2121
2222namespace Core . Middlewares ;
2323
24- public readonly record struct CacheModel ( long ex , string ext , short statusCode = 200 , int contentLength = 0 ) ;
25-
2624public class Staticache
2725{
2826 #region static
2927 static readonly Serilog . ILogger Log = Serilog . Log . ForContext < Staticache > ( ) ;
3028
31- public readonly static ConcurrentDictionary < string , CacheModel > cacheFiles = new ( ) ;
29+ public readonly static ConcurrentDictionary < string , StaticacheCacheModel > cacheFiles = new ( ) ;
3230
3331 static readonly Timer cleanupTimer = new Timer ( cleanup , null , TimeSpan . FromMinutes ( 1 ) , TimeSpan . FromSeconds ( 5 ) ) ;
3432
33+ static StaticachePreparedRoute [ ] preparedRoutes = Array . Empty < StaticachePreparedRoute > ( ) ;
34+
3535 public static void Initialization ( )
3636 {
37+ #region load cache files
3738 long now = DateTimeOffset . Now . ToUnixTimeMilliseconds ( ) ;
3839
3940 string cacheDir = Path . Combine ( "cache" , "static" ) ;
@@ -76,13 +77,33 @@ public static void Initialization()
7677 continue ;
7778 }
7879
79- cacheFiles . TryAdd ( cachekey , new CacheModel ( unixTime , ext , 200 , contentLength ) ) ;
80+ cacheFiles . TryAdd ( cachekey , new StaticacheCacheModel ( unixTime , ext , 200 , contentLength ) ) ;
8081 }
8182 catch
8283 {
8384 deleteFile ( inFile ) ;
8485 }
8586 }
87+ #endregion
88+
89+ EventListener . UpdateInitFile += ( ) =>
90+ {
91+ var routes = CoreInit . conf . Staticache . routes ;
92+ if ( routes == null || routes . Count == 0 )
93+ preparedRoutes = Array . Empty < StaticachePreparedRoute > ( ) ;
94+
95+ preparedRoutes = routes . Select ( r => new StaticachePreparedRoute
96+ {
97+ Route = r ,
98+ PathRegex = new Regex (
99+ r . pathRex ,
100+ RegexOptions . IgnoreCase |
101+ RegexOptions . CultureInvariant |
102+ RegexOptions . Compiled ,
103+ TimeSpan . FromMilliseconds ( 100 )
104+ )
105+ } ) . ToArray ( ) ;
106+ } ;
86107 }
87108
88109 static void cleanup ( object state )
@@ -113,8 +134,7 @@ static void deleteFile(string file)
113134 {
114135 try
115136 {
116- if ( File . Exists ( file ) )
117- File . Delete ( file ) ;
137+ File . Delete ( file ) ;
118138 }
119139 catch ( Exception ex )
120140 {
@@ -136,7 +156,7 @@ public Task Invoke(HttpContext httpContext)
136156 return _next ( httpContext ) ;
137157
138158 var requestInfo = httpContext . Features . Get < RequestModel > ( ) ;
139- if ( requestInfo . AesGcmKey != null || requestInfo . IsWsRequest || requestInfo . IsProxyRequest || requestInfo . IsProxyImg )
159+ if ( requestInfo . AesGcmKey != null || requestInfo . IsProxyRequest || requestInfo . IsProxyImg )
140160 return _next ( httpContext ) ;
141161
142162 var endpoint = httpContext . GetEndpoint ( ) ;
@@ -162,16 +182,17 @@ public Task Invoke(HttpContext httpContext)
162182
163183 bool customRoute = false ;
164184 StaticacheRoute route = default ;
185+ string path = httpContext . Request . Path . Value ;
165186
166187 #region init routes
167- if ( init . routes ? . Count > 0 && init . enable )
188+ if ( init . enable )
168189 {
169- foreach ( var r in init . routes )
190+ foreach ( var p in preparedRoutes )
170191 {
171- string path = httpContext . Request . Path . Value ;
192+ var r = p . Route ;
172193
173194 if ( ( r . path != null && path . Equals ( r . path ) )
174- || ( r . pathRex != null && Regex . IsMatch ( path , r . pathRex , RegexOptions . IgnoreCase ) ) )
195+ || ( r . pathRex != null && p . PathRegex . IsMatch ( path ) ) )
175196 {
176197 customRoute = true ;
177198 route = r ;
@@ -192,10 +213,10 @@ public Task Invoke(HttpContext httpContext)
192213 return _next ( httpContext ) ;
193214 }
194215
195- if ( init . minimalCacheMinutes > staticache . cacheMinutes )
216+ if ( init . minimalCacheMinutes > staticache . cacheMinutes && ! staticache . always )
196217 return _next ( httpContext ) ;
197218
198- if ( init . disabledPaths != null && init . disabledPaths . Contains ( httpContext . Request . Path . Value ) )
219+ if ( init . disabledPaths != null && init . disabledPaths . Contains ( path ) )
199220 return _next ( httpContext ) ;
200221
201222 if ( staticache . setHeadersNoCache )
@@ -223,7 +244,7 @@ public Task Invoke(HttpContext httpContext)
223244
224245 string cachekey = getQueryKeys ( httpContext , route . skipUids || staticache . skipUids , parameters , route . queryKeys , route . ignoreQueryKeys ) ;
225246
226- if ( cacheFiles . TryGetValue ( cachekey , out CacheModel _r ) )
247+ if ( cacheFiles . TryGetValue ( cachekey , out StaticacheCacheModel _r ) )
227248 {
228249 httpContext . Response . StatusCode = _r . statusCode ;
229250 httpContext . Response . Headers [ "X-StatiCache-Status" ] = "HIT" ;
@@ -250,10 +271,11 @@ public Task Invoke(HttpContext httpContext)
250271 string file = GetFilePath ( cachekey , _r . ex , _r . contentLength , _r . ext ) ;
251272 return httpContext . Response . SendFileAsync ( file ) ;
252273 }
253-
254- httpContext . Features . Set ( new StaticacheFeature ( route . cacheMinutes , cachekey ) ) ;
255-
256- return _next ( httpContext ) ;
274+ else
275+ {
276+ httpContext . Features . Set ( new StaticacheFeature ( route . cacheMinutes , cachekey ) ) ;
277+ return _next ( httpContext ) ;
278+ }
257279 }
258280
259281
@@ -325,5 +347,5 @@ private static void QueryAppend(ref Fnv1aHash hash, string key, HttpContext http
325347
326348 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
327349 public static string GetFilePath ( string cachekey , long ex , int length , string ext )
328- => Path . Combine ( "cache" , "static" , BucketFolders . Name ( cachekey [ 0 ] ) , $ "{ cachekey } -{ ex } _{ length } .{ ext ?? "html" } ") ;
350+ => Path . Combine ( "cache" , "static" , BucketFolders . Name ( cachekey [ 0 ] ) , $ "{ cachekey } -{ ex } _{ length } .{ ext } ") ;
329351}
0 commit comments