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

Commit a212792

Browse files
forward html and javascript requests to devserver
1 parent 20e11e6 commit a212792

3 files changed

Lines changed: 67 additions & 8 deletions

File tree

src/SqlStreamStore.HAL.DevServer/DevServerStartup.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
namespace SqlStreamStore.HAL.DevServer
22
{
33
using System;
4+
using System.Linq;
5+
using System.Net.Http;
6+
using System.Net.Http.Headers;
47
using System.Threading.Tasks;
58
using Microsoft.AspNetCore.Builder;
69
using Microsoft.AspNetCore.Hosting;
710
using Microsoft.AspNetCore.Http;
811
using Microsoft.Extensions.DependencyInjection;
12+
using Microsoft.Extensions.Primitives;
913
using MidFunc = System.Func<
1014
Microsoft.AspNetCore.Http.HttpContext,
1115
System.Func<System.Threading.Tasks.Task>,
@@ -15,10 +19,12 @@
1519
internal class DevServerStartup : IStartup
1620
{
1721
private readonly IStreamStore _streamStore;
22+
private readonly HttpClient _httpClient;
1823

1924
public DevServerStartup(IStreamStore streamStore)
2025
{
2126
_streamStore = streamStore;
27+
_httpClient = new HttpClient();
2228
}
2329

2430
public IServiceProvider ConfigureServices(IServiceCollection services) => services
@@ -29,6 +35,8 @@ public void Configure(IApplicationBuilder app) => app
2935
.UseResponseCompression()
3036
.Use(CatchAndDisplayErrors)
3137
.Use(AllowAllOrigins)
38+
.Use(SqlStreamStreamBrowserJavascript)
39+
.Use(SqlStreamStreamBrowserHtml)
3240
.UseSqlStreamStoreHal(_streamStore);
3341

3442
private static MidFunc CatchAndDisplayErrors => async (context, next) =>
@@ -57,5 +65,49 @@ public void Configure(IApplicationBuilder app) => app
5765

5866
return next();
5967
};
68+
69+
private static string[] GetAcceptHeaders(HttpRequest contextRequest)
70+
=> Array.ConvertAll(
71+
contextRequest.Headers.GetCommaSeparatedValues("Accept"),
72+
value => MediaTypeWithQualityHeaderValue.TryParse(value, out var header)
73+
? header.MediaType
74+
: null);
75+
76+
private MidFunc SqlStreamStreamBrowserJavascript => (context, next)
77+
=> context.Request.Path.Value?.EndsWith(".js") ?? false
78+
? ForwardToClientDevServer(
79+
context,
80+
$"{context.Request.PathBase.ToUriComponent()}{context.Request.Path.ToUriComponent()}")
81+
: next();
82+
83+
private MidFunc SqlStreamStreamBrowserHtml => (context, next)
84+
=> GetAcceptHeaders(context.Request)
85+
.Any(header => header == "text/html")
86+
? ForwardToClientDevServer(context, context.Request.PathBase.ToUriComponent())
87+
: next();
88+
89+
private async Task ForwardToClientDevServer(HttpContext context, string path)
90+
{
91+
using(var request = new HttpRequestMessage(
92+
new HttpMethod(context.Request.Method),
93+
new UriBuilder
94+
{
95+
Port = 3000,
96+
Host = "localhost",
97+
Path = path,
98+
Query = context.Request.QueryString.ToUriComponent()
99+
}.Uri))
100+
using(var response = await _httpClient.SendAsync(request))
101+
using(var stream = await response.Content.ReadAsStreamAsync())
102+
{
103+
context.Response.StatusCode = (int) response.StatusCode;
104+
foreach(var header in response.Headers.Concat(response.Content.Headers))
105+
{
106+
context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
107+
}
108+
109+
await stream.CopyToAsync(context.Response.Body, 8192, context.RequestAborted);
110+
}
111+
}
60112
}
61113
}

src/SqlStreamStore.HAL/HttpContextExtensions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
namespace SqlStreamStore.HAL
22
{
3+
using System;
34
using System.IO;
45
using System.Linq;
56
using System.Net.Http;
7+
using System.Net.Http.Headers;
68
using System.Threading.Tasks;
79
using Microsoft.AspNetCore.Http;
810
using Newtonsoft.Json;
911
using Newtonsoft.Json.Serialization;
12+
using SqlStreamStore.Streams;
1013

1114
internal static class HttpContextExtensions
1215
{
@@ -76,6 +79,14 @@ public static int GetExpectedVersion(this HttpRequest request)
7679
request.Headers[Constants.Headers.ExpectedVersion],
7780
out var expectedVersion)
7881
? expectedVersion
79-
: Streams.ExpectedVersion.Any;
82+
: ExpectedVersion.Any;
83+
84+
public static string[] GetAcceptHeaders(this HttpRequest contextRequest)
85+
=> Array.ConvertAll(
86+
contextRequest.Headers
87+
.GetCommaSeparatedValues("Accept"),
88+
value => MediaTypeWithQualityHeaderValue.TryParse(value, out var header)
89+
? header.MediaType
90+
: null);
8091
}
8192
}

src/SqlStreamStore.HAL/SqlStreamStoreHalMiddleware.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{
33
using System;
44
using System.Linq;
5-
using System.Net.Http.Headers;
65
using System.Threading.Tasks;
76
using Halcyon.HAL;
87
using Microsoft.AspNetCore.Builder;
@@ -27,12 +26,9 @@ private static MidFunc MethodsNotAllowed(params string[] methods) => (context, n
2726
return Task.CompletedTask;
2827
};
2928

30-
private static MidFunc AcceptOnlyHalJson => (context, next) =>
29+
private static MidFunc AcceptHalJson => (context, next) =>
3130
{
32-
var accept = context.Request.Headers.GetCommaSeparatedValues("Accept")
33-
.Select(value => MediaTypeWithQualityHeaderValue.TryParse(value, out var header)
34-
? header.MediaType
35-
: null);
31+
var accept = context.Request.GetAcceptHeaders();
3632

3733
return accept.Any(header => header == Constants.Headers.ContentTypes.HalJson
3834
|| header == Constants.Headers.ContentTypes.Any)
@@ -72,7 +68,7 @@ public static IApplicationBuilder UseSqlStreamStoreHal(
7268

7369
return builder
7470
.Use(ExceptionHandlingMiddleware.HandleExceptions)
75-
.Use(AcceptOnlyHalJson)
71+
.Use(AcceptHalJson)
7672
.Use(Index)
7773
.Map("/stream", UseAllStream(streamStore))
7874
.Map("/streams", UseStream(streamStore));

0 commit comments

Comments
 (0)