@@ -92,11 +92,6 @@ private static readonly ConcurrentTLruCache<string, string> HMACTokenLru
9292 /// </summary>
9393 private readonly ICacheHash cacheHash ;
9494
95- /// <summary>
96- /// The collection of known commands gathered from the processors.
97- /// </summary>
98- private readonly HashSet < string > knownCommands ;
99-
10095 /// <summary>
10196 /// Contains various helper methods based on the current configuration.
10297 /// </summary>
@@ -117,6 +112,11 @@ private static readonly ConcurrentTLruCache<string, string> HMACTokenLru
117112 /// </summary>
118113 private readonly AsyncKeyReaderWriterLock < string > asyncKeyLock ;
119114
115+ /// <summary>
116+ /// Contains helpers that allow authorization of image requests.
117+ /// </summary>
118+ private readonly ImageSharpRequestAuthorizationUtilities authorizationUtilities ;
119+
120120 /// <summary>
121121 /// Initializes a new instance of the <see cref="ImageSharpMiddleware"/> class.
122122 /// </summary>
@@ -131,7 +131,8 @@ private static readonly ConcurrentTLruCache<string, string> HMACTokenLru
131131 /// <param name="cacheHash">An <see cref="ICacheHash"/>instance used for calculating cached file names.</param>
132132 /// <param name="commandParser">The command parser.</param>
133133 /// <param name="formatUtilities">Contains various format helper methods based on the current configuration.</param>
134- /// <param name="asyncKeyLock">The async key lock</param>
134+ /// <param name="asyncKeyLock">The async key lock.</param>
135+ /// <param name="requestAuthorizationUtilities">Contains helpers that allow authorization of image requests.</param>
135136 public ImageSharpMiddleware (
136137 RequestDelegate next ,
137138 IOptions < ImageSharpMiddlewareOptions > options ,
@@ -144,7 +145,8 @@ public ImageSharpMiddleware(
144145 ICacheHash cacheHash ,
145146 CommandParser commandParser ,
146147 FormatUtilities formatUtilities ,
147- AsyncKeyReaderWriterLock < string > asyncKeyLock )
148+ AsyncKeyReaderWriterLock < string > asyncKeyLock ,
149+ ImageSharpRequestAuthorizationUtilities requestAuthorizationUtilities )
148150 {
149151 Guard . NotNull ( next , nameof ( next ) ) ;
150152 Guard . NotNull ( options , nameof ( options ) ) ;
@@ -158,6 +160,7 @@ public ImageSharpMiddleware(
158160 Guard . NotNull ( commandParser , nameof ( commandParser ) ) ;
159161 Guard . NotNull ( formatUtilities , nameof ( formatUtilities ) ) ;
160162 Guard . NotNull ( asyncKeyLock , nameof ( asyncKeyLock ) ) ;
163+ Guard . NotNull ( requestAuthorizationUtilities , nameof ( requestAuthorizationUtilities ) ) ;
161164
162165 this . next = next ;
163166 this . options = options . Value ;
@@ -172,20 +175,10 @@ public ImageSharpMiddleware(
172175 ? CultureInfo . InvariantCulture
173176 : CultureInfo . CurrentCulture ;
174177
175- var commands = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
176- foreach ( IImageWebProcessor processor in this . processors )
177- {
178- foreach ( string command in processor . Commands )
179- {
180- commands . Add ( command ) ;
181- }
182- }
183-
184- this . knownCommands = commands ;
185-
186178 this . logger = loggerFactory . CreateLogger < ImageSharpMiddleware > ( ) ;
187179 this . formatUtilities = formatUtilities ;
188180 this . asyncKeyLock = asyncKeyLock ;
181+ this . authorizationUtilities = requestAuthorizationUtilities ;
189182 }
190183
191184 /// <summary>
@@ -197,31 +190,6 @@ public ImageSharpMiddleware(
197190
198191 private async Task Invoke ( HttpContext httpContext , bool retry )
199192 {
200- CommandCollection commands = this . requestParser . ParseRequestCommands ( httpContext ) ;
201-
202- // First check for a HMAC token and capture before the command is stripped out.
203- byte [ ] secret = this . options . HMACSecretKey ;
204- bool checkHMAC = false ;
205- string token = null ;
206- if ( secret ? . Length > 0 )
207- {
208- checkHMAC = true ;
209- token = commands . GetValueOrDefault ( HMACUtilities . TokenCommand ) ;
210- }
211-
212- if ( commands . Count > 0 )
213- {
214- // Strip out any unknown commands, if needed.
215- var keys = new List < string > ( commands . Keys ) ;
216- for ( int i = keys . Count - 1 ; i >= 0 ; i -- )
217- {
218- if ( ! this . knownCommands . Contains ( keys [ i ] ) )
219- {
220- commands . RemoveAt ( i ) ;
221- }
222- }
223- }
224-
225193 // Get the correct provider for the request
226194 IImageProvider provider = null ;
227195 foreach ( IImageProvider resolver in this . providers )
@@ -240,6 +208,19 @@ private async Task Invoke(HttpContext httpContext, bool retry)
240208 return ;
241209 }
242210
211+ CommandCollection commands = this . requestParser . ParseRequestCommands ( httpContext ) ;
212+
213+ // First check for a HMAC token and capture before the command is stripped out.
214+ byte [ ] secret = this . options . HMACSecretKey ;
215+ bool checkHMAC = false ;
216+ string token = null ;
217+ if ( secret ? . Length > 0 )
218+ {
219+ checkHMAC = true ;
220+ token = commands . GetValueOrDefault ( ImageSharpRequestAuthorizationUtilities . TokenCommand ) ;
221+ }
222+
223+ this . authorizationUtilities . StripUnknownCommands ( commands ) ;
243224 ImageCommandContext imageCommandContext = new ( httpContext , commands , this . commandParser , this . parserCulture ) ;
244225
245226 // At this point we know that this is an image request so should attempt to compute a validating HMAC.
@@ -253,7 +234,9 @@ private async Task Invoke(HttpContext httpContext, bool retry)
253234 //
254235 // As a rule all image requests should contain valid commands only.
255236 // Key generation uses string.Create under the hood with very low allocation so should be good enough as a cache key.
256- hmac = await HMACTokenLru . GetOrAddAsync ( httpContext . Request . GetEncodedUrl ( ) , _ => this . options . OnComputeHMACAsync ( imageCommandContext , secret ) ) ;
237+ hmac = await HMACTokenLru . GetOrAddAsync (
238+ httpContext . Request . GetEncodedUrl ( ) ,
239+ _ => this . authorizationUtilities . ComputeHMACAsync ( imageCommandContext , CommandHandling . None ) ) ;
257240 }
258241
259242 await this . options . OnParseCommandsAsync . Invoke ( imageCommandContext ) ;
0 commit comments