Skip to content

Commit 52a9fa0

Browse files
Merge pull request #268 from SixLabors/js/no-double-enumerate-
Optimize Invalid command removal.
2 parents b86ae56 + f8fdde6 commit 52a9fa0

File tree

6 files changed

+42
-26
lines changed

6 files changed

+42
-26
lines changed

Diff for: src/ImageSharp.Web/Commands/PresetOnlyQueryCollectionRequestParser.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public CommandCollection ParseRequestCommands(HttpContext context)
3939
return new();
4040
}
4141

42-
string requestedPreset = context.Request.Query[QueryKey][0];
42+
StringValues query = context.Request.Query[QueryKey];
43+
string requestedPreset = query[query.Count - 1];
4344
if (this.presets.TryGetValue(requestedPreset, out CommandCollection collection))
4445
{
4546
return collection;
@@ -63,7 +64,8 @@ private static CommandCollection ParsePreset(string unparsedPresetValue)
6364
CommandCollection transformed = new();
6465
foreach (KeyValuePair<string, StringValues> pair in parsed)
6566
{
66-
transformed.Add(new(pair.Key, pair.Value.ToString()));
67+
// Use the indexer for both set and query. This replaces any previously parsed values.
68+
transformed[pair.Key] = pair.Value[pair.Value.Count - 1];
6769
}
6870

6971
return transformed;

Diff for: src/ImageSharp.Web/Commands/QueryCollectionRequestParser.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public CommandCollection ParseRequestCommands(HttpContext context)
2828
CommandCollection transformed = new();
2929
foreach (KeyValuePair<string, StringValues> pair in parsed)
3030
{
31-
transformed.Add(new(pair.Key, pair.Value.ToString()));
31+
// Use the indexer for both set and query. This replaces any previously parsed values.
32+
transformed[pair.Key] = pair.Value[pair.Value.Count - 1];
3233
}
3334

3435
return transformed;

Diff for: src/ImageSharp.Web/ImageSharp.Web.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
<ItemGroup>
4848
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.2.0" />
49-
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.1" />
49+
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.2" />
5050
</ItemGroup>
5151

5252
<Import Project="..\..\shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems" Label="Shared" />

Diff for: src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs

+4-21
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,13 @@ private async Task Invoke(HttpContext httpContext, bool retry)
212212
if (commands.Count > 0)
213213
{
214214
// Strip out any unknown commands, if needed.
215-
int index = 0;
216-
foreach (string command in commands.Keys)
215+
var keys = new List<string>(commands.Keys);
216+
for (int i = keys.Count - 1; i >= 0; i--)
217217
{
218-
if (!this.knownCommands.Contains(command))
218+
if (!this.knownCommands.Contains(keys[i]))
219219
{
220-
// Need to actually remove, allocates new list to allow modifications
221-
this.StripUnknownCommands(commands, index);
222-
break;
220+
commands.RemoveAt(i);
223221
}
224-
225-
index++;
226222
}
227223
}
228224

@@ -307,19 +303,6 @@ private static void SetBadRequest(HttpContext httpContext)
307303
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
308304
}
309305

310-
private void StripUnknownCommands(CommandCollection commands, int startAtIndex)
311-
{
312-
var keys = new List<string>(commands.Keys);
313-
for (int index = startAtIndex; index < keys.Count; index++)
314-
{
315-
string command = keys[index];
316-
if (!this.knownCommands.Contains(command))
317-
{
318-
commands.Remove(command);
319-
}
320-
}
321-
}
322-
323306
private async Task ProcessRequestAsync(
324307
HttpContext httpContext,
325308
IImageResolver sourceImageResolver,

Diff for: tests/ImageSharp.Web.Tests/Commands/CommandCollectionTests.cs

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Collections.Generic;
56
using SixLabors.ImageSharp.Web.Commands;
67
using Xunit;
@@ -17,6 +18,15 @@ public void CanAddCommands()
1718
Assert.Single(collection);
1819
}
1920

21+
[Fact]
22+
public void CannotAddDuplicateCommands()
23+
{
24+
CommandCollection collection = new();
25+
collection.Add(new("a", "b"));
26+
Assert.Throws<ArgumentException>(() => collection.Add(new("a", "b")));
27+
Assert.Single(collection);
28+
}
29+
2030
[Fact]
2131
public void CanReadCommands()
2232
{
@@ -48,6 +58,15 @@ public void CanInsertCommands()
4858
Assert.Equal(0, collection.IndexOf(kv2));
4959
}
5060

61+
[Fact]
62+
public void CannotInsertDuplicateCommands()
63+
{
64+
CommandCollection collection = new();
65+
collection.Add(new("a", "b"));
66+
Assert.Throws<ArgumentException>(() => collection.Insert(0, new("a", "b")));
67+
Assert.Single(collection);
68+
}
69+
5170
[Fact]
5271
public void CanInsertCommandsViaKey()
5372
{
@@ -68,6 +87,15 @@ public void CanInsertCommandsViaKey()
6887
Assert.Equal(0, collection.IndexOf(kv2));
6988
}
7089

90+
[Fact]
91+
public void CannotInsertDuplicateCommandsViaKey()
92+
{
93+
CommandCollection collection = new();
94+
collection.Add(new("a", "b"));
95+
Assert.Throws<ArgumentException>(() => collection.Insert(0, "a", "b"));
96+
Assert.Single(collection);
97+
}
98+
7199
[Fact]
72100
public void CanSetCommandsViaIndex()
73101
{

Diff for: tests/ImageSharp.Web.Tests/Commands/QueryCollectionUriParserTests.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ private static HttpContext CreateHttpContext()
2828
{
2929
var httpContext = new DefaultHttpContext();
3030
httpContext.Request.Path = "/testwebsite.com/image-12345.jpeg";
31-
httpContext.Request.QueryString = new QueryString("?width=400&height=200");
31+
32+
// Duplicate height param to test replacements
33+
httpContext.Request.QueryString = new QueryString("?width=400&height=100&height=200");
3234
return httpContext;
3335
}
3436
}

0 commit comments

Comments
 (0)