var builder = WebApplication.CreateBuilder(args); // Configure clients builder.Services.AddHttpClient("GoBackend", client => { client.BaseAddress = new Uri("http://localhost:8080"); }); var app = builder.Build(); // 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(); }); // Proxy all requests to Go backend app.Use(async (context, next) => { // Skip special paths if (context.Request.Path.StartsWithSegments("/.well-known")) { await next(); return; } var client = context.RequestServices.GetRequiredService() .CreateClient("GoBackend"); try { var request = new HttpRequestMessage( new HttpMethod(context.Request.Method), context.Request.Path + context.Request.QueryString); // Copy headers foreach (var header in context.Request.Headers) { if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray())) { request.Content ??= new StreamContent(context.Request.Body); request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); } } if (context.Request.ContentLength > 0) { request.Content = new StreamContent(context.Request.Body); } var response = await client.SendAsync(request); context.Response.StatusCode = (int)response.StatusCode; foreach (var header in response.Headers) { context.Response.Headers[header.Key] = header.Value.ToArray(); } if (response.Content.Headers.ContentType != null) { context.Response.ContentType = response.Content.Headers.ContentType.ToString(); } await response.Content.CopyToAsync(context.Response.Body); } catch (HttpRequestException) { context.Response.StatusCode = 502; } }); app.Run();