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);