refactor(wrapper): changes to handle docs and frontned now
This commit is contained in:
@@ -1,85 +1,65 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
// to build the binary dotnet publish -c Release -o ./publish
|
|
||||||
// Go backend
|
|
||||||
builder.Services.AddHttpClient("GoBackend", client =>
|
|
||||||
{
|
|
||||||
client.BaseAddress = new Uri("http://localhost:8080");
|
|
||||||
client.Timeout = TimeSpan.FromSeconds(30);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Node frontend
|
// Configure clients
|
||||||
builder.Services.AddHttpClient("NodeFrontend", client =>
|
builder.Services.AddHttpClient("GoBackend", client => {
|
||||||
{
|
client.BaseAddress = new Uri("http://localhost:8080");
|
||||||
client.BaseAddress = new Uri("http://localhost:3000");
|
|
||||||
client.Timeout = TimeSpan.FromSeconds(30);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.UseStaticFiles();
|
// Handle trailing slash redirects
|
||||||
|
app.Use(async (context, next) => {
|
||||||
|
if (context.Request.Path.Equals("/lst", StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
context.Response.Redirect("/lst/", permanent: true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
|
||||||
app.Use((Func<HttpContext, Func<Task>, Task>)(async (context, next) =>
|
// Proxy all requests to Go backend
|
||||||
{
|
app.Use(async (context, next) => {
|
||||||
var clientFactory = context.RequestServices.GetRequiredService<IHttpClientFactory>();
|
// Skip special paths
|
||||||
|
if (context.Request.Path.StartsWithSegments("/.well-known")) {
|
||||||
|
await next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var isApiRequest =
|
var client = context.RequestServices.GetRequiredService<IHttpClientFactory>()
|
||||||
context.Request.Path.StartsWithSegments("/api") ||
|
.CreateClient("GoBackend");
|
||||||
context.Request.Path.StartsWithSegments("/graphql") ||
|
|
||||||
context.Request.Path.StartsWithSegments("/auth") ||
|
|
||||||
!context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
var client = clientFactory.CreateClient(isApiRequest ? "GoBackend" : "NodeFrontend");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var requestUri = context.Request.Path + context.Request.QueryString;
|
|
||||||
|
|
||||||
|
try {
|
||||||
var request = new HttpRequestMessage(
|
var request = new HttpRequestMessage(
|
||||||
new HttpMethod(context.Request.Method),
|
new HttpMethod(context.Request.Method),
|
||||||
requestUri);
|
context.Request.Path + context.Request.QueryString);
|
||||||
|
|
||||||
foreach (var header in context.Request.Headers)
|
// Copy headers
|
||||||
{
|
foreach (var header in context.Request.Headers) {
|
||||||
if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()))
|
if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray())) {
|
||||||
{
|
|
||||||
request.Content ??= new StreamContent(context.Request.Body);
|
request.Content ??= new StreamContent(context.Request.Body);
|
||||||
request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
|
request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Request.ContentLength > 0 || context.Request.Headers.ContainsKey("Transfer-Encoding"))
|
if (context.Request.ContentLength > 0) {
|
||||||
{
|
|
||||||
request.Content = new StreamContent(context.Request.Body);
|
request.Content = new StreamContent(context.Request.Body);
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted);
|
var response = await client.SendAsync(request);
|
||||||
|
|
||||||
context.Response.StatusCode = (int)response.StatusCode;
|
context.Response.StatusCode = (int)response.StatusCode;
|
||||||
|
|
||||||
foreach (var header in response.Headers)
|
foreach (var header in response.Headers) {
|
||||||
{
|
|
||||||
context.Response.Headers[header.Key] = header.Value.ToArray();
|
context.Response.Headers[header.Key] = header.Value.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var header in response.Content.Headers)
|
if (response.Content.Headers.ContentType != null) {
|
||||||
{
|
context.Response.ContentType = response.Content.Headers.ContentType.ToString();
|
||||||
context.Response.Headers[header.Key] = header.Value.ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Response.Headers.Remove("transfer-encoding");
|
|
||||||
|
|
||||||
await response.Content.CopyToAsync(context.Response.Body);
|
await response.Content.CopyToAsync(context.Response.Body);
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
catch (HttpRequestException) {
|
||||||
{
|
context.Response.StatusCode = 502;
|
||||||
context.Response.StatusCode = isApiRequest ? 503 : 502;
|
|
||||||
await context.Response.WriteAsync($"{(isApiRequest ? "Go API" : "Frontend")} unavailable: {ex.Message}");
|
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -1,15 +1,46 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<location path="." inheritInChildApplications="false">
|
|
||||||
<system.webServer>
|
<system.webServer>
|
||||||
|
<rewrite>
|
||||||
|
<rules>
|
||||||
|
<!-- Redirect root to /lst/ -->
|
||||||
|
<rule name="Root Redirect" stopProcessing="true">
|
||||||
|
<match url="^$" />
|
||||||
|
<action type="Redirect" url="/lst/" redirectType="Permanent" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Proxy static assets -->
|
||||||
|
<rule name="Static Assets" stopProcessing="true">
|
||||||
|
<match url="^lst/assets/(.*)" />
|
||||||
|
<action type="Rewrite" url="http://localhost:8080/lst/assets/{R:1}" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Proxy API requests -->
|
||||||
|
<rule name="API Routes" stopProcessing="true">
|
||||||
|
<match url="^lst/api/(.*)" />
|
||||||
|
<action type="Rewrite" url="http://localhost:8080/lst/api/{R:1}" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- Proxy all other requests -->
|
||||||
|
<rule name="Frontend Routes" stopProcessing="true">
|
||||||
|
<match url="^lst/(.*)" />
|
||||||
|
<action type="Rewrite" url="http://localhost:8080/lst/{R:1}" />
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</rewrite>
|
||||||
|
|
||||||
|
<staticContent>
|
||||||
|
<clear />
|
||||||
|
<mimeMap fileExtension=".js" mimeType="application/javascript" />
|
||||||
|
<mimeMap fileExtension=".mjs" mimeType="application/javascript" />
|
||||||
|
<mimeMap fileExtension=".css" mimeType="text/css" />
|
||||||
|
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
|
||||||
|
</staticContent>
|
||||||
|
|
||||||
<handlers>
|
<handlers>
|
||||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
||||||
</handlers>
|
</handlers>
|
||||||
<aspNetCore processPath="dotnet"
|
|
||||||
arguments=".\LstWrapper.dll"
|
<aspNetCore processPath="dotnet" arguments=".\LstWrapper.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
|
||||||
stdoutLogEnabled="true"
|
|
||||||
stdoutLogFile=".\logs\stdout"
|
|
||||||
hostingModel="inprocess" />
|
|
||||||
</system.webServer>
|
</system.webServer>
|
||||||
</location>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
Reference in New Issue
Block a user