@@ -30,11 +30,15 @@ public static class Proxy
3030
3131 public static Func < HttpContext , bool > ShouldCache = context =>
3232 {
33+ // Ignore if local
34+ if ( context . Request . Host . Value ! . Contains ( "localhost" ) )
35+ return false ;
3336 // Ignore Cache-Control headers
3437 if ( context . Request . Headers . TryGetValue ( "Cache-Control" , out var cacheControlValues ) )
35- {
3638 return false ;
37- }
39+ // Ignore if has QueryString
40+ if ( context . Request . QueryString . HasValue )
41+ return false ;
3842
3943 var path = context . Request . Path . Value ?? string . Empty ;
4044 if ( path . Length > 0 )
@@ -104,13 +108,31 @@ static bool IsHopByHopHeader(string headerName)
104108 public static async Task HttpToNode ( HttpContext context , HttpClient nextClient )
105109 {
106110 var request = context . Request ;
111+
107112 var cacheKey = request . Path . Value ?? string . Empty ;
108- if ( Cache . TryGetValue ( cacheKey , out var cached ) )
113+ var shouldCache = ShouldCache ( context ) ;
114+ if ( shouldCache )
109115 {
110- Console . WriteLine ( "Cache hit: " + cacheKey ) ;
111- context . Response . ContentType = cached . mimeType ;
112- await context . Response . Body . WriteAsync ( cached . data , context . RequestAborted ) ;
113- return ;
116+ // if contains ?clear, remove from cache
117+ var qs = request . QueryString . Value ?? string . Empty ;
118+ if ( qs . Contains ( "?clear" ) )
119+ {
120+ if ( qs . Contains ( "?clear=all" ) )
121+ {
122+ Cache . Clear ( ) ;
123+ }
124+ else
125+ {
126+ Cache . TryRemove ( cacheKey , out _ ) ;
127+ }
128+ }
129+ if ( Cache . TryGetValue ( cacheKey , out var cached ) )
130+ {
131+ Console . WriteLine ( $ "Cache hit: { cacheKey } |mimeType| { cached . mimeType } |size| { cached . data . Length } ") ;
132+ context . Response . ContentType = cached . mimeType ;
133+ await context . Response . Body . WriteAsync ( cached . data , context . RequestAborted ) ;
134+ return ;
135+ }
114136 }
115137
116138 // Build relative URI (path + query)
@@ -165,19 +187,24 @@ public static async Task HttpToNode(HttpContext context, HttpClient nextClient)
165187 // ASP.NET Core will set its own transfer-encoding
166188 context . Response . Headers . Remove ( "transfer-encoding" ) ;
167189
168- if ( context . Response . StatusCode == StatusCodes . Status200OK && ShouldCache ( context ) )
190+ if ( context . Response . StatusCode == StatusCodes . Status200OK )
169191 {
170- var bytes = await response . Content . ReadAsByteArrayAsync ( ) ;
171- var mimeType = response . Content . Headers . ContentType ? . ToString ( )
172- ?? ServiceStack . MimeTypes . GetMimeType ( cacheKey ) ;
173- Cache [ cacheKey ] = ( mimeType , bytes ) ;
174- Console . WriteLine ( "Cache miss: " + cacheKey + " |size| " + bytes . Length ) ;
175- await context . Response . Body . WriteAsync ( bytes , context . RequestAborted ) ;
176- }
177- else
178- {
179- await response . Content . CopyToAsync ( context . Response . Body , context . RequestAborted ) ;
192+ if ( shouldCache )
193+ {
194+ var bytes = await response . Content . ReadAsByteArrayAsync ( ) ;
195+ if ( bytes . Length > 0 )
196+ {
197+ var mimeType = response . Content . Headers . ContentType ? . ToString ( )
198+ ?? ServiceStack . MimeTypes . GetMimeType ( cacheKey ) ;
199+ Cache [ cacheKey ] = ( mimeType , bytes ) ;
200+ Console . WriteLine ( $ "Cache miss: { cacheKey } |mimeType| { mimeType } |size| { bytes . Length } ") ;
201+ await context . Response . Body . WriteAsync ( bytes , context . RequestAborted ) ;
202+ return ;
203+ }
204+ }
180205 }
206+
207+ await response . Content . CopyToAsync ( context . Response . Body , context . RequestAborted ) ;
181208 }
182209
183210 public static void MapNotFoundToNode ( WebApplication app , HttpClient nextClient , string [ ] ignorePaths )
0 commit comments