5
5
using System . Diagnostics ;
6
6
using System . Collections . Concurrent ;
7
7
using System . Runtime . InteropServices ;
8
+ using System ;
8
9
9
10
namespace HttpServer
10
11
{
@@ -19,6 +20,7 @@ public sealed class Program
19
20
{
20
21
private bool Verbose = false ;
21
22
private ConcurrentDictionary < string , Session > Sessions = new ConcurrentDictionary < string , Session > ( ) ;
23
+ private Dictionary < string , byte [ ] > cache = new Dictionary < string , byte [ ] > ( StringComparer . OrdinalIgnoreCase ) ;
22
24
23
25
public static int Main ( )
24
26
{
@@ -83,7 +85,7 @@ private void OpenUrl(string url)
83
85
}
84
86
else
85
87
{
86
- System . Console . WriteLine ( "Don't know how to open url on this OS platform" ) ;
88
+ Console . WriteLine ( "Don't know how to open url on this OS platform" ) ;
87
89
}
88
90
89
91
proc . StartInfo = si ;
@@ -102,6 +104,31 @@ private void HandleRequest(HttpListener listener)
102
104
ReceivePostAsync ( context ) ;
103
105
}
104
106
107
+ private async Task < byte [ ] ? > GetFileContent ( string path )
108
+ {
109
+ if ( Verbose )
110
+ await Console . Out . WriteLineAsync ( $ "get content for: { path } ") ;
111
+
112
+ if ( cache . ContainsKey ( path ) )
113
+ {
114
+ if ( Verbose )
115
+ await Console . Out . WriteLineAsync ( $ "returning cached content for: { path } ") ;
116
+
117
+ return cache [ path ] ;
118
+ }
119
+
120
+ var content = await File . ReadAllBytesAsync ( path ) . ConfigureAwait ( false ) ;
121
+ if ( content == null )
122
+ return null ;
123
+
124
+ if ( Verbose )
125
+ await Console . Out . WriteLineAsync ( $ "adding content to cache for: { path } ") ;
126
+
127
+ cache [ path ] = content ;
128
+
129
+ return content ;
130
+ }
131
+
105
132
private async void ReceivePostAsync ( HttpListenerContext context )
106
133
{
107
134
if ( Verbose )
@@ -165,15 +192,17 @@ private async void ServeAsync(HttpListenerContext context)
165
192
byte [ ] ? buffer ;
166
193
try
167
194
{
168
- buffer = await File . ReadAllBytesAsync ( path ) . ConfigureAwait ( false ) ;
169
- if ( throttleMbps > 0 ) {
195
+ buffer = await GetFileContent ( path ) ;
196
+
197
+ if ( buffer != null && throttleMbps > 0 )
198
+ {
170
199
double delaySeconds = ( buffer . Length * 8 ) / ( throttleMbps * 1024 * 1024 ) ;
171
200
int delayMs = ( int ) ( delaySeconds * 1000 ) ;
172
- if ( session != null )
201
+ if ( session != null )
173
202
{
174
203
Task currentDelay ;
175
204
int myIndex ;
176
- lock ( session )
205
+ lock ( session )
177
206
{
178
207
currentDelay = session . CurrentDelay ;
179
208
myIndex = session . Started ;
@@ -185,10 +214,10 @@ private async void ServeAsync(HttpListenerContext context)
185
214
// wait for everybody else to finish in this while loop
186
215
await currentDelay ;
187
216
188
- lock ( session )
217
+ lock ( session )
189
218
{
190
219
// it's my turn to insert delay for others
191
- if ( session . Finished == myIndex )
220
+ if ( session . Finished == myIndex )
192
221
{
193
222
session . CurrentDelay = Task . Delay ( delayMs ) ;
194
223
break ;
@@ -202,10 +231,10 @@ private async void ServeAsync(HttpListenerContext context)
202
231
// wait my own delay
203
232
await Task . Delay ( delayMs + latencyMs ) ;
204
233
205
- lock ( session )
234
+ lock ( session )
206
235
{
207
236
session . Finished ++ ;
208
- if ( session . Finished == session . Started )
237
+ if ( session . Finished == session . Started )
209
238
{
210
239
Sessions . TryRemove ( sessionId ! , out _ ) ;
211
240
}
0 commit comments