Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit bfd1a09

Browse files
Merge pull request #15 from thefringeninja/head
Code Improvments
2 parents 45c34f4 + 2e8a76f commit bfd1a09

7 files changed

Lines changed: 75 additions & 83 deletions

src/SqlStreamStore.HAL/ExceptionHandlingMiddleware.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using Halcyon.HAL;
6+
using Microsoft.AspNetCore.Builder;
67
using Newtonsoft.Json;
78
using SqlStreamStore.Streams;
89
using MidFunc = System.Func<
@@ -45,7 +46,10 @@ private static readonly IDictionary<Type, Func<Exception, Response>> s_exception
4546
[typeof(Exception)] = s_defaultExceptionHandler
4647
};
4748

48-
public static MidFunc HandleExceptions => async (context, next) =>
49+
public static IApplicationBuilder UseExceptionHandling(this IApplicationBuilder builder)
50+
=> builder.Use(HandleExceptions);
51+
52+
private static MidFunc HandleExceptions => async (context, next) =>
4953
{
5054
try
5155
{

src/SqlStreamStore.HAL/IndexMiddleware.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@ public static IApplicationBuilder UseIndex(this IApplicationBuilder builder)
1717
private static bool IsIndex(HttpContext context)
1818
=> (context.Request.Path.Value ?? "/") == "/";
1919

20-
private static MidFunc Index => async (context, next) =>
20+
private static MidFunc Index => (context, next) =>
2121
{
2222
var response = new Response(new HALResponse(null)
2323
.AddLinks(new Link(Constants.Relations.Feed, "stream"))
2424
.AddLinks(new Link(Constants.Relations.Self, string.Empty))
2525
.AddLinks(Links.Index(string.Empty))
2626
.AddLinks(Links.Find("streams/{streamId}")));
2727

28-
using(new OptionalHeadRequestWrapper(context))
29-
{
30-
await context.WriteHalResponse(response);
31-
}
28+
return context.WriteHalResponse(response);
3229
};
3330
}
3431
}

src/SqlStreamStore.HAL/OptionalHeadRequestWrapper.cs

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/SqlStreamStore.HAL/ReadAllStreamMiddleware.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,16 @@ private static MidFunc GetStream(AllStreamResource allStream) => async (context,
3434

3535
var response = await allStream.Get(options, context.RequestAborted);
3636

37-
using(new OptionalHeadRequestWrapper(context))
38-
{
39-
await context.WriteHalResponse(response);
40-
}
37+
await context.WriteHalResponse(response);
4138
};
4239

43-
private static MidFunc GetStreamMessage(AllStreamMessageResource allStreamMessages) => async (context, next) =>
40+
private static MidFunc GetStreamMessage(AllStreamMessageResource allStreamMessages) => async (context, next) =>
4441
{
4542
var response = await allStreamMessages.Get(
4643
new ReadAllStreamMessageOperation(context.Request),
4744
context.RequestAborted);
4845

49-
using(new OptionalHeadRequestWrapper(context))
50-
{
51-
await context.WriteHalResponse(response);
52-
}
46+
await context.WriteHalResponse(response);
5347
};
5448
}
5549
}

src/SqlStreamStore.HAL/ReadStreamMiddleware.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ private static MidFunc GetStream(StreamResource streams) => async (context, next
3333

3434
var response = await streams.Get(options, context.RequestAborted);
3535

36-
using(new OptionalHeadRequestWrapper(context))
37-
{
38-
await context.WriteHalResponse(response);
39-
}
36+
await context.WriteHalResponse(response);
4037
};
4138

4239
private static MidFunc GetStreamMessage(StreamMessageResource streamMessages) => async (context, next) =>
@@ -45,10 +42,7 @@ private static MidFunc GetStreamMessage(StreamMessageResource streamMessages) =>
4542

4643
var response = await streamMessages.Get(options, context.RequestAborted);
4744

48-
using(new OptionalHeadRequestWrapper(context))
49-
{
50-
await context.WriteHalResponse(response);
51-
}
45+
await context.WriteHalResponse(response);
5246
};
5347
}
5448
}

src/SqlStreamStore.HAL/SqlStreamStoreHalMiddleware.cs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
namespace SqlStreamStore.HAL
22
{
33
using System;
4+
using System.IO;
45
using System.Linq;
6+
using System.Threading;
57
using System.Threading.Tasks;
68
using Halcyon.HAL;
79
using Microsoft.AspNetCore.Builder;
@@ -57,6 +59,13 @@ private static MidFunc MethodsNotAllowed(params string[] methods) => (context, n
5759
406));
5860
};
5961

62+
private static MidFunc HeadRequests => async (context, next) =>
63+
{
64+
using(new OptionalHeadRequestWrapper(context))
65+
{
66+
await next();
67+
}
68+
};
6069
public static IApplicationBuilder UseSqlStreamStoreHal(
6170
this IApplicationBuilder builder,
6271
IStreamStore streamStore)
@@ -67,9 +76,10 @@ public static IApplicationBuilder UseSqlStreamStoreHal(
6776
throw new ArgumentNullException(nameof(streamStore));
6877

6978
return builder
70-
.Use(ExceptionHandlingMiddleware.HandleExceptions)
79+
.UseExceptionHandling()
7180
.Use(CaseSensitiveQueryStrings)
7281
.Use(AcceptHalJson)
82+
.Use(HeadRequests)
7383
.UseIndex()
7484
.Map("/stream", UseAllStream(streamStore))
7585
.Map("/streams", UseStream(streamStore));
@@ -91,5 +101,56 @@ private static Action<IApplicationBuilder> UseAllStream(IStreamStore streamStore
91101
.Use(MethodsNotAllowed("POST", "PUT", "DELETE", "TRACE", "PATCH"));
92102

93103
private static bool IsOptions(HttpContext context) => context.IsOptions();
104+
105+
private class OptionalHeadRequestWrapper : IDisposable
106+
{
107+
private readonly HttpContext _context;
108+
private readonly Stream _originalBody;
109+
110+
public OptionalHeadRequestWrapper(HttpContext context)
111+
{
112+
_context = context;
113+
_originalBody = _context.Response.Body;
114+
if(context.Request.Method == "HEAD")
115+
{
116+
context.Response.Body = new HeadRequestStream();
117+
}
118+
}
119+
120+
public void Dispose()
121+
{
122+
_context.Response.Body = _originalBody;
123+
}
124+
125+
private class HeadRequestStream : Stream
126+
{
127+
private long _length;
128+
129+
public override void Flush() => FlushAsync(CancellationToken.None).Wait();
130+
public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException();
131+
public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
132+
public override void SetLength(long value) => throw new NotImplementedException();
133+
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
134+
135+
public override Task WriteAsync(
136+
byte[] buffer,
137+
int offset,
138+
int count,
139+
CancellationToken cancellationToken)
140+
{
141+
_length += count;
142+
Position += count;
143+
return Task.CompletedTask;
144+
}
145+
146+
public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask;
147+
148+
public override bool CanRead { get; } = false;
149+
public override bool CanSeek { get; } = false;
150+
public override bool CanWrite { get; } = true;
151+
public override long Length => _length;
152+
public override long Position { get; set; }
153+
}
154+
}
94155
}
95156
}

src/SqlStreamStore.HAL/StreamMetadataMiddleware.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ private static MidFunc GetStreamMetadata(StreamMetadataResource streamsMetadata)
4343

4444
var response = await streamsMetadata.Get(options, context.RequestAborted);
4545

46-
using(new OptionalHeadRequestWrapper(context))
47-
{
48-
await context.WriteHalResponse(response);
49-
}
46+
await context.WriteHalResponse(response);
5047
};
5148
}
5249
}

0 commit comments

Comments
 (0)