Skip to content

Commit f8a49d1

Browse files
committed
converts callbacks to async
changes OnParseCommands, OnBeforeSave, OnProcessed, OnPrepareResponse to return `Task` instead of void to enable async callbacks
1 parent 2bce803 commit f8a49d1

File tree

6 files changed

+51
-57
lines changed

6 files changed

+51
-57
lines changed

src/ImageSharp.Web/Middleware/ImageContext.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,11 @@ public void ComprehendRequestHeaders(DateTimeOffset lastModified, long length)
125125
/// <param name="statusCode">The status code.</param>
126126
/// <param name="metaData">The image metadata.</param>
127127
/// <returns>The <see cref="Task"/>.</returns>
128-
public Task SendStatusAsync(int statusCode, in ImageCacheMetadata metaData)
128+
public async Task SendStatusAsync(int statusCode, ImageCacheMetadata metaData)
129129
{
130-
this.ApplyResponseHeaders(statusCode, metaData.ContentType, this.ComputeMaxAge(metaData));
130+
await this.ApplyResponseHeadersAsync(statusCode, metaData.ContentType, this.ComputeMaxAge(metaData));
131131

132132
// this.logger.LogHandled(statusCode, SubPath);
133-
return ResponseConstants.CompletedTask;
134133
}
135134

136135
/// <summary>
@@ -141,7 +140,7 @@ public Task SendStatusAsync(int statusCode, in ImageCacheMetadata metaData)
141140
/// <returns>The <see cref="Task"/>.</returns>
142141
public async Task SendAsync(Stream stream, ImageCacheMetadata metaData)
143142
{
144-
this.ApplyResponseHeaders(ResponseConstants.Status200Ok, metaData.ContentType, this.ComputeMaxAge(metaData));
143+
await this.ApplyResponseHeadersAsync(ResponseConstants.Status200Ok, metaData.ContentType, this.ComputeMaxAge(metaData));
145144

146145
if (stream.CanSeek)
147146
{
@@ -170,7 +169,7 @@ private static PreconditionState GetMaxPreconditionState(params PreconditionStat
170169
return max;
171170
}
172171

173-
private void ApplyResponseHeaders(int statusCode, string contentType, TimeSpan maxAge)
172+
private async Task ApplyResponseHeadersAsync(int statusCode, string contentType, TimeSpan maxAge)
174173
{
175174
this.response.StatusCode = statusCode;
176175
if (statusCode < 400)
@@ -193,7 +192,7 @@ private void ApplyResponseHeaders(int statusCode, string contentType, TimeSpan m
193192
MustRevalidate = true
194193
};
195194

196-
this.options.OnPrepareResponse?.Invoke(this.context);
195+
await this.options.OnPrepareResponse?.Invoke(this.context);
197196
}
198197

199198
if (statusCode == ResponseConstants.Status200Ok)

src/ImageSharp.Web/Middleware/ImageSharpMiddleware.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public async Task Invoke(HttpContext context)
167167
}
168168
}
169169

170-
this.options.OnParseCommands?.Invoke(new ImageCommandContext(context, commands, CommandParser.Instance));
170+
await this.options.OnParseCommands?.Invoke(new ImageCommandContext(context, commands, CommandParser.Instance));
171171

172172
// Get the correct service for the request.
173173
IImageProvider provider = null;
@@ -273,7 +273,7 @@ private async Task ProcessRequestAsync(HttpContext context, bool processRequest,
273273
using (var image = FormattedImage.Load(this.options.Configuration, inStream))
274274
{
275275
image.Process(this.logger, this.processors, commands);
276-
this.options.OnBeforeSave?.Invoke(image);
276+
await this.options.OnBeforeSave?.Invoke(image);
277277
image.Save(outStream);
278278
format = image.Format;
279279
}
@@ -298,7 +298,7 @@ private async Task ProcessRequestAsync(HttpContext context, bool processRequest,
298298
outStream.Position = 0;
299299
string contentType = cachedImageMetadata.ContentType;
300300
string extension = this.formatUtilities.GetExtensionFromContentType(contentType);
301-
this.options.OnProcessed?.Invoke(new ImageProcessingContext(context, outStream, commands, contentType, extension));
301+
await this.options.OnProcessed?.Invoke(new ImageProcessingContext(context, outStream, commands, contentType, extension));
302302
outStream.Position = 0;
303303

304304
// Save the image to the cache and send the response to the caller.

src/ImageSharp.Web/Middleware/ImageSharpMiddlewareOptions.cs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5+
using System.Threading.Tasks;
56
using Microsoft.AspNetCore.Http;
67
using SixLabors.ImageSharp.Web.Commands;
78
using SixLabors.ImageSharp.Web.Processors;
@@ -38,44 +39,44 @@ public class ImageSharpMiddlewareOptions
3839
/// Gets or sets the additional command parsing method that can be used to used to augment commands.
3940
/// This is called once the commands have been gathered and before an <see cref="IImageProvider"/> has been assigned.
4041
/// </summary>
41-
public Action<ImageCommandContext> OnParseCommands { get; set; } = c =>
42+
public Func<ImageCommandContext, Task> OnParseCommands { get; set; } = c =>
4243
{
43-
if (c.Commands.Count == 0)
44+
if (c.Commands.Count != 0)
4445
{
45-
return;
46-
}
47-
48-
// It's a good idea to have this to provide very basic security.
49-
// We can safely use the static resize processor properties.
50-
uint width = c.Parser.ParseValue<uint>(c.Commands.GetValueOrDefault(ResizeWebProcessor.Width));
51-
uint height = c.Parser.ParseValue<uint>(c.Commands.GetValueOrDefault(ResizeWebProcessor.Height));
46+
// It's a good idea to have this to provide very basic security.
47+
// We can safely use the static resize processor properties.
48+
uint width = c.Parser.ParseValue<uint>(c.Commands.GetValueOrDefault(ResizeWebProcessor.Width));
49+
uint height = c.Parser.ParseValue<uint>(c.Commands.GetValueOrDefault(ResizeWebProcessor.Height));
5250

53-
if (width > 4000 && height > 4000)
54-
{
55-
c.Commands.Remove(ResizeWebProcessor.Width);
56-
c.Commands.Remove(ResizeWebProcessor.Height);
51+
if (width > 4000 && height > 4000)
52+
{
53+
c.Commands.Remove(ResizeWebProcessor.Width);
54+
c.Commands.Remove(ResizeWebProcessor.Height);
55+
}
5756
}
57+
58+
return Task.CompletedTask;
5859
};
5960

6061
/// <summary>
6162
/// Gets or sets the additional method that can be used for final manipulation before the image is saved.
6263
/// This is called after image has been processed, but before the image has been saved to the output stream for caching.
6364
/// This can be used to alter the metadata of the resultant image.
6465
/// </summary>
65-
public Action<FormattedImage> OnBeforeSave { get; set; } = _ => { };
66+
public Func<FormattedImage, Task> OnBeforeSave { get; set; } = _ => Task.CompletedTask;
6667

6768
/// <summary>
6869
/// Gets or sets the additional processing method.
6970
/// This is called after image has been processed, but before the result has been cached.
7071
/// This can be used to further optimize the resultant image.
7172
/// </summary>
72-
public Action<ImageProcessingContext> OnProcessed { get; set; } = _ => { };
73+
public Func<ImageProcessingContext, Task> OnProcessed { get; set; } = _ => Task.CompletedTask;
7374

7475
/// <summary>
7576
/// Gets or sets the additional response method.
7677
/// This is called after the status code and headers have been set, but before the body has been written.
7778
/// This can be used to add or change the response headers.
7879
/// </summary>
79-
public Action<HttpContext> OnPrepareResponse { get; set; } = _ => { };
80+
public Func<HttpContext, Task> OnPrepareResponse { get; set; } = _ => Task.CompletedTask;
8081
}
81-
}
82+
}

src/ImageSharp.Web/Middleware/ResponseConstants.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System.Threading.Tasks;
@@ -26,17 +26,5 @@ internal static class ResponseConstants
2626
/// resource has been denied.
2727
/// </summary>
2828
internal const int Status412PreconditionFailed = 412;
29-
30-
/// <summary>
31-
/// An empty completed task.
32-
/// </summary>
33-
internal static readonly Task CompletedTask = CreateCompletedTask();
34-
35-
private static Task CreateCompletedTask()
36-
{
37-
var tcs = new TaskCompletionSource<object>();
38-
tcs.SetResult(null);
39-
return tcs.Task;
40-
}
4129
}
4230
}

tests/ImageSharp.Web.Tests/Actions/ActionTests.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@ public async Task ShouldRunOnValidateActionAsync(string url)
4242
}
4343

4444
bool complete = false;
45-
void OnParseCommands(ImageCommandContext context)
45+
Task OnParseCommands(ImageCommandContext context)
4646
{
4747
Assert.NotNull(context);
4848
Assert.NotNull(context.Context);
4949
Assert.NotNull(context.Commands);
5050
Assert.NotNull(context.Parser);
5151
complete = true;
52+
return Task.CompletedTask;
5253
}
5354

5455
using (TestServer server = ImageSharpTestServer.CreateWithActions(OnParseCommands))
@@ -69,13 +70,14 @@ public async Task ShouldRunOnValidateActionNoCommandsAsync(string url)
6970
}
7071

7172
bool complete = false;
72-
void OnParseCommands(ImageCommandContext context)
73+
Task OnParseCommands(ImageCommandContext context)
7374
{
7475
Assert.NotNull(context);
7576
Assert.NotNull(context.Context);
7677
Assert.NotNull(context.Commands);
7778
Assert.NotNull(context.Parser);
7879
complete = true;
80+
return Task.CompletedTask;
7981
}
8082

8183
using (TestServer server = ImageSharpTestServer.CreateWithActions(OnParseCommands))
@@ -90,12 +92,13 @@ void OnParseCommands(ImageCommandContext context)
9092
public async Task ShouldRunOnBeforeSaveActionAsync()
9193
{
9294
bool complete = false;
93-
void OnBeforeSave(FormattedImage image)
95+
Task OnBeforeSave(FormattedImage image)
9496
{
9597
Assert.NotNull(image);
9698
Assert.NotNull(image.Format);
9799
Assert.NotNull(image.Image);
98100
complete = true;
101+
return Task.CompletedTask;
99102
}
100103

101104
using (TestServer server = ImageSharpTestServer.CreateWithActions(null, OnBeforeSave))
@@ -110,13 +113,14 @@ void OnBeforeSave(FormattedImage image)
110113
public async Task ShouldRunOnProcessedActionAsync()
111114
{
112115
bool complete = false;
113-
void OnProcessed(ImageProcessingContext context)
116+
Task OnProcessed(ImageProcessingContext context)
114117
{
115118
Assert.NotNull(context);
116119
Assert.NotNull(context.Context);
117120
Assert.NotNull(context.Extension);
118121
Assert.NotNull(context.Stream);
119122
complete = true;
123+
return Task.CompletedTask;
120124
}
121125

122126
using (TestServer server = ImageSharpTestServer.CreateWithActions(null, null, OnProcessed))
@@ -131,11 +135,12 @@ void OnProcessed(ImageProcessingContext context)
131135
public async Task ShouldRunOnPrepareResponseActionAsync()
132136
{
133137
bool complete = false;
134-
void OnPrepareResponse(HttpContext context)
138+
Task OnPrepareResponse(HttpContext context)
135139
{
136140
Assert.NotNull(context);
137141
Assert.NotNull(context.Response);
138142
complete = true;
143+
return Task.CompletedTask;
139144
}
140145

141146
using (TestServer server = ImageSharpTestServer.CreateWithActions(null, null, null, OnPrepareResponse))

tests/ImageSharp.Web.Tests/ImageSharpTestServer.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.IO;
7+
using System.Threading.Tasks;
78
using Azure.Storage.Blobs;
89
using Azure.Storage.Blobs.Models;
910
using Microsoft.AspNetCore.Builder;
@@ -42,10 +43,10 @@ public static class ImageSharpTestServer
4243
options.MaxBrowserCacheDays = -1;
4344
options.MaxCacheDays = -1;
4445
options.CachedNameLength = 12;
45-
options.OnParseCommands = _ => { };
46-
options.OnBeforeSave = _ => { };
47-
options.OnProcessed = _ => { };
48-
options.OnPrepareResponse = _ => { };
46+
options.OnParseCommands = _ => Task.CompletedTask;
47+
options.OnBeforeSave = _ => Task.CompletedTask;
48+
options.OnProcessed = _ => Task.CompletedTask;
49+
options.OnPrepareResponse = _ => Task.CompletedTask;
4950
})
5051
.SetRequestParser<QueryCollectionRequestParser>()
5152
.Configure<PhysicalFileSystemCacheOptions>(_ => { })
@@ -73,10 +74,10 @@ public static class ImageSharpTestServer
7374
options.MaxBrowserCacheDays = -1;
7475
options.MaxCacheDays = -1;
7576
options.CachedNameLength = 12;
76-
options.OnParseCommands = _ => { };
77-
options.OnBeforeSave = _ => { };
78-
options.OnProcessed = _ => { };
79-
options.OnPrepareResponse = _ => { };
77+
options.OnParseCommands = _ => Task.CompletedTask;
78+
options.OnBeforeSave = _ => Task.CompletedTask;
79+
options.OnProcessed = _ => Task.CompletedTask;
80+
options.OnPrepareResponse = _ => Task.CompletedTask;
8081
})
8182
.SetRequestParser<QueryCollectionRequestParser>()
8283
.Configure<PhysicalFileSystemCacheOptions>(_ => { })
@@ -99,10 +100,10 @@ public static class ImageSharpTestServer
99100
public static TestServer CreateAzure() => Create(DefaultConfig, DefaultServices);
100101

101102
public static TestServer CreateWithActions(
102-
Action<ImageCommandContext> onParseCommands,
103-
Action<FormattedImage> onBeforeSave = null,
104-
Action<ImageProcessingContext> onProcessed = null,
105-
Action<HttpContext> onPrepareResponse = null)
103+
Func<ImageCommandContext, Task> onParseCommands,
104+
Func<FormattedImage, Task> onBeforeSave = null,
105+
Func<ImageProcessingContext, Task> onProcessed = null,
106+
Func<HttpContext, Task> onPrepareResponse = null)
106107
{
107108
void ConfigureServices(IServiceCollection services)
108109
{

0 commit comments

Comments
 (0)