Skip to content

Commit 11caa09

Browse files
Merge pull request #183 from ronaldbarendse/bugfix/processing-order
Order and filter processors by supported commands
2 parents 728997a + ab8eecb commit 11caa09

File tree

3 files changed

+113
-7
lines changed

3 files changed

+113
-7
lines changed

src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,10 @@ public async Task Invoke(HttpContext context)
188188
IDictionary<string, string> commands = this.requestParser.ParseRequestCommands(context);
189189
if (commands.Count > 0)
190190
{
191-
// Strip out any unknown commands.
191+
// Strip out any unknown commands
192192
foreach (string command in new List<string>(commands.Keys))
193193
{
194-
if (!this.knownCommands.Contains(command))
194+
if (!this.knownCommands.Contains(command, StringComparer.OrdinalIgnoreCase))
195195
{
196196
commands.Remove(command);
197197
}
@@ -201,7 +201,7 @@ public async Task Invoke(HttpContext context)
201201
await this.options.OnParseCommandsAsync.Invoke(
202202
new ImageCommandContext(context, commands, this.commandParser, this.parserCulture));
203203

204-
// Get the correct service for the request.
204+
// Get the correct service for the request
205205
IImageProvider provider = null;
206206
foreach (IImageProvider resolver in this.providers)
207207
{

src/ImageSharp.Web/Processors/WebProcessingExtensions.cs

Lines changed: 56 additions & 4 deletions
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 System.Globalization;
67
using Microsoft.Extensions.Logging;
@@ -33,15 +34,66 @@ public static FormattedImage Process(
3334
CommandParser commandParser,
3435
CultureInfo culture)
3536
{
36-
if (commands.Count != 0)
37+
var commandKeys = new List<string>(commands.Keys);
38+
39+
foreach (IImageWebProcessor processor in processors.GetBySupportedCommands(commandKeys))
40+
{
41+
source = processor.Process(source, logger, commands, commandParser, culture);
42+
}
43+
44+
return source;
45+
}
46+
47+
/// <summary>
48+
/// Sorts the processors according to the first supported command and removes processors without supported commands.
49+
/// </summary>
50+
/// <param name="processors">The collection of available processors.</param>
51+
/// <param name="commands">The parsed collection of processing commands.</param>
52+
/// <returns>
53+
/// The sorted proccessors that supports any of the specified commands.
54+
/// </returns>
55+
public static IEnumerable<IImageWebProcessor> GetBySupportedCommands(this IEnumerable<IImageWebProcessor> processors, List<string> commands)
56+
{
57+
var indexedProcessors = new List<(int Index, IImageWebProcessor Processor)>();
58+
59+
foreach (IImageWebProcessor processor in processors)
3760
{
38-
foreach (IImageWebProcessor processor in processors)
61+
// Get index of first supported command
62+
int index = commands.FindIndex(c => processor.IsSupportedCommand(c));
63+
if (index != -1)
3964
{
40-
source = processor.Process(source, logger, commands, commandParser, culture);
65+
indexedProcessors.Add((index, processor));
4166
}
4267
}
4368

44-
return source;
69+
indexedProcessors.Sort((x, y) => x.Index.CompareTo(y.Index));
70+
71+
// Return sorted processors
72+
foreach ((int _, IImageWebProcessor processor) in indexedProcessors)
73+
{
74+
yield return processor;
75+
}
76+
}
77+
78+
/// <summary>
79+
/// Determines whether the specified command is supported by the processor
80+
/// </summary>
81+
/// <param name="processor">The processor.</param>
82+
/// <param name="command">The command.</param>
83+
/// <returns>
84+
/// <c>true</c> if the specified command is supported by the processor; otherwise, <c>false</c>.
85+
/// </returns>
86+
public static bool IsSupportedCommand(this IImageWebProcessor processor, string command)
87+
{
88+
foreach (string processorCommand in processor.Commands)
89+
{
90+
if (processorCommand.Equals(command, StringComparison.OrdinalIgnoreCase))
91+
{
92+
return true;
93+
}
94+
}
95+
96+
return false;
4597
}
4698
}
4799
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using SixLabors.ImageSharp.Web.Processors;
7+
using SixLabors.ImageSharp.Web.Tests.DependencyInjection;
8+
using Xunit;
9+
10+
namespace SixLabors.ImageSharp.Web.Tests.Processors
11+
{
12+
public class WebProcessingExtensionsTests
13+
{
14+
[Fact]
15+
public void WebProcessingExtensions_GetBySupportedCommands()
16+
{
17+
var processors = new IImageWebProcessor[]
18+
{
19+
new JpegQualityWebProcessor(),
20+
new ResizeWebProcessor(),
21+
new BackgroundColorWebProcessor(),
22+
new MockWebProcessor()
23+
};
24+
25+
var commands = new List<string>
26+
{
27+
ResizeWebProcessor.Width,
28+
JpegQualityWebProcessor.Quality,
29+
ResizeWebProcessor.Height
30+
};
31+
32+
var supportedProcessors = WebProcessingExtensions.GetBySupportedCommands(processors, commands).ToArray();
33+
34+
Assert.Equal(2, supportedProcessors.Length);
35+
Assert.IsType<ResizeWebProcessor>(supportedProcessors[0]);
36+
Assert.IsType<JpegQualityWebProcessor>(supportedProcessors[1]);
37+
}
38+
39+
[Fact]
40+
public void WebProcessingExtensions_GetBySupportedCommands_Empty()
41+
{
42+
var processors = new IImageWebProcessor[]
43+
{
44+
new MockWebProcessor()
45+
};
46+
47+
var commands = new List<string>();
48+
49+
var supportedProcessors = WebProcessingExtensions.GetBySupportedCommands(processors, commands).ToArray();
50+
51+
Assert.Empty(supportedProcessors);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)