From b9eea70d9c9f336ac849b7e51dd3296cb723a277 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 2 Feb 2026 22:25:21 +0000
Subject: [PATCH 1/2] Initial plan
From 8f3639771cc7c34329644889d502cf8fb78b6544 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 2 Feb 2026 23:15:37 +0000
Subject: [PATCH 2/2] Fix Location header to respect X-Forwarded-Proto and
X-Forwarded-Host headers
Updated SqlMutationEngine.cs and SqlResponseHelpers.cs to use the
SqlPaginationUtil.ResolveRequestScheme and ResolveRequestHost methods
when constructing Location headers. This ensures that when behind a
reverse proxy (like Azure API Management), the Location header uses
the original client request scheme (HTTPS) instead of the internal
connection scheme (HTTP).
Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
---
src/Core/Resolvers/SqlMutationEngine.cs | 7 +++++--
src/Core/Resolvers/SqlPaginationUtil.cs | 8 ++++----
src/Core/Resolvers/SqlResponseHelpers.cs | 7 +++++--
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/Core/Resolvers/SqlMutationEngine.cs b/src/Core/Resolvers/SqlMutationEngine.cs
index dfc53449f8..63ff11af85 100644
--- a/src/Core/Resolvers/SqlMutationEngine.cs
+++ b/src/Core/Resolvers/SqlMutationEngine.cs
@@ -397,9 +397,12 @@ await queryExecutor.ExecuteQueryAsync(
case EntityActionOperation.Insert:
HttpContext httpContext = GetHttpContext();
+ // Use scheme/host from X-Forwarded-* headers if present, else fallback to request values
+ string scheme = SqlPaginationUtil.ResolveRequestScheme(httpContext.Request);
+ string host = SqlPaginationUtil.ResolveRequestHost(httpContext.Request);
string locationHeaderURL = UriHelper.BuildAbsolute(
- scheme: httpContext.Request.Scheme,
- host: httpContext.Request.Host,
+ scheme: scheme,
+ host: new HostString(host),
pathBase: GetBaseRouteFromConfig(_runtimeConfigProvider.GetConfig()),
path: httpContext.Request.Path);
diff --git a/src/Core/Resolvers/SqlPaginationUtil.cs b/src/Core/Resolvers/SqlPaginationUtil.cs
index bb9362015b..b410639907 100644
--- a/src/Core/Resolvers/SqlPaginationUtil.cs
+++ b/src/Core/Resolvers/SqlPaginationUtil.cs
@@ -756,7 +756,7 @@ public static string FormatQueryString(NameValueCollection? queryStringParameter
/// The HTTP request.
/// The scheme string ("http" or "https").
/// Thrown when client explicitly sets an invalid scheme.
- private static string ResolveRequestScheme(HttpRequest req)
+ internal static string ResolveRequestScheme(HttpRequest req)
{
string? rawScheme = req.Headers["X-Forwarded-Proto"].FirstOrDefault();
string? normalized = rawScheme?.Trim().ToLowerInvariant();
@@ -780,7 +780,7 @@ private static string ResolveRequestScheme(HttpRequest req)
/// The HTTP request.
/// The host string.
/// Thrown when client explicitly sets an invalid host.
- private static string ResolveRequestHost(HttpRequest req)
+ internal static string ResolveRequestHost(HttpRequest req)
{
string? rawHost = req.Headers["X-Forwarded-Host"].FirstOrDefault();
string? trimmed = rawHost?.Trim();
@@ -803,7 +803,7 @@ private static string ResolveRequestHost(HttpRequest req)
///
/// Scheme, e.g., "http" or "https".
/// True if valid, otherwise false.
- private static bool IsValidScheme(string? scheme)
+ internal static bool IsValidScheme(string? scheme)
{
return scheme is "http" or "https";
}
@@ -813,7 +813,7 @@ private static bool IsValidScheme(string? scheme)
///
/// The host name (with optional port).
/// True if valid, otherwise false.
- private static bool IsValidHost(string? host)
+ internal static bool IsValidHost(string? host)
{
if (string.IsNullOrWhiteSpace(host))
{
diff --git a/src/Core/Resolvers/SqlResponseHelpers.cs b/src/Core/Resolvers/SqlResponseHelpers.cs
index d0bf768281..d955a7a36b 100644
--- a/src/Core/Resolvers/SqlResponseHelpers.cs
+++ b/src/Core/Resolvers/SqlResponseHelpers.cs
@@ -381,9 +381,12 @@ HttpContext httpContext
// The third part is the computed primary key route.
if (operationType is EntityActionOperation.Insert && !string.IsNullOrEmpty(primaryKeyRoute))
{
+ // Use scheme/host from X-Forwarded-* headers if present, else fallback to request values
+ string scheme = SqlPaginationUtil.ResolveRequestScheme(httpContext.Request);
+ string host = SqlPaginationUtil.ResolveRequestHost(httpContext.Request);
locationHeaderURL = UriHelper.BuildAbsolute(
- scheme: httpContext.Request.Scheme,
- host: httpContext.Request.Host,
+ scheme: scheme,
+ host: new HostString(host),
pathBase: baseRoute,
path: httpContext.Request.Path);