refactor(wrapper): changes to handle docs and frontned now

This commit is contained in:
2025-07-19 11:38:47 -05:00
parent 9acfd1ccd0
commit 253d998b68
2 changed files with 78 additions and 67 deletions

View File

@@ -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")) {
var isApiRequest = await next();
context.Request.Path.StartsWithSegments("/api") || return;
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;
var client = context.RequestServices.GetRequiredService<IHttpClientFactory>()
.CreateClient("GoBackend");
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();

View File

@@ -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>
<handlers> <rules>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> <!-- Redirect root to /lst/ -->
</handlers> <rule name="Root Redirect" stopProcessing="true">
<aspNetCore processPath="dotnet" <match url="^$" />
arguments=".\LstWrapper.dll" <action type="Redirect" url="/lst/" redirectType="Permanent" />
stdoutLogEnabled="true" </rule>
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess" /> <!-- Proxy static assets -->
</system.webServer> <rule name="Static Assets" stopProcessing="true">
</location> <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>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\LstWrapper.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
</configuration> </configuration>