From 3069fe0dd9776d24140d791fd39ad0683ffa3d71 Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Tue, 9 Jan 2018 16:54:40 +0900 Subject: [PATCH] BTCPayServer should work on HTTP even if externalurl is https --- BTCPayServer/BTCPayServer.csproj | 2 +- BTCPayServer/Hosting/BTCpayMiddleware.cs | 70 ++++++++++++++++++------ 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/BTCPayServer/BTCPayServer.csproj b/BTCPayServer/BTCPayServer.csproj index 3017a859c..b1982f2e4 100644 --- a/BTCPayServer/BTCPayServer.csproj +++ b/BTCPayServer/BTCPayServer.csproj @@ -2,7 +2,7 @@ Exe netcoreapp2.0 - 1.0.0.55 + 1.0.0.57 diff --git a/BTCPayServer/Hosting/BTCpayMiddleware.cs b/BTCPayServer/Hosting/BTCpayMiddleware.cs index ffad7bdce..32571930f 100644 --- a/BTCPayServer/Hosting/BTCpayMiddleware.cs +++ b/BTCPayServer/Hosting/BTCpayMiddleware.cs @@ -99,39 +99,73 @@ namespace BTCPayServer.Hosting private void RewriteHostIfNeeded(HttpContext httpContext) { + string reverseProxyScheme = null; + if (httpContext.Request.Headers.TryGetValue("X-Forwarded-Proto", out StringValues proto)) + { + var scheme = proto.SingleOrDefault(); + if (scheme != null) + { + reverseProxyScheme = scheme; + } + } + + ushort? reverseProxyPort = null; + if (httpContext.Request.Headers.TryGetValue("X-Forwarded-Port", out StringValues port)) + { + var portString = port.SingleOrDefault(); + if (portString != null && ushort.TryParse(portString, out ushort pp)) + { + reverseProxyPort = pp; + } + } + // Make sure that code executing after this point think that the external url has been hit. if (_Options.ExternalUrl != null) { - httpContext.Request.Scheme = _Options.ExternalUrl.Scheme; + if (reverseProxyScheme != null && _Options.ExternalUrl.Scheme != reverseProxyScheme) + { + if (reverseProxyScheme == "http" && _Options.ExternalUrl.Scheme == "https") + Logs.PayServer.LogWarning($"BTCPay ExternalUrl setting expected to use scheme '{_Options.ExternalUrl.Scheme}' externally, but the reverse proxy uses scheme '{reverseProxyScheme}'"); + httpContext.Request.Scheme = reverseProxyScheme; + } + else + { + httpContext.Request.Scheme = _Options.ExternalUrl.Scheme; + } if (_Options.ExternalUrl.IsDefaultPort) httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host); else - httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host, _Options.ExternalUrl.Port); + { + if (reverseProxyPort != null && _Options.ExternalUrl.Port != reverseProxyPort.Value) + { + Logs.PayServer.LogWarning($"BTCPay ExternalUrl setting expected to use port '{_Options.ExternalUrl.Port}' externally, but the reverse proxy uses port '{reverseProxyPort.Value}'"); + httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host, reverseProxyPort.Value); + } + else + { + httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host, _Options.ExternalUrl.Port); + } + } } // NGINX pass X-Forwarded-Proto and X-Forwarded-Port, so let's use that to have better guess of the real domain else { ushort? p = null; - if (httpContext.Request.Headers.TryGetValue("X-Forwarded-Proto", out StringValues proto)) + if (reverseProxyScheme != null) { - var scheme = proto.SingleOrDefault(); - if (scheme != null) - { - httpContext.Request.Scheme = scheme; - if (scheme == "http") - p = 80; - if (scheme == "https") - p = 443; - } + httpContext.Request.Scheme = reverseProxyScheme; + if (reverseProxyScheme == "http") + p = 80; + if (reverseProxyScheme == "https") + p = 443; } - if (httpContext.Request.Headers.TryGetValue("X-Forwarded-Port", out StringValues port)) + + + if (reverseProxyPort != null) { - var portString = port.SingleOrDefault(); - if (portString != null && ushort.TryParse(portString, out ushort pp)) - { - p = pp; - } + p = reverseProxyPort.Value; } + if (p.HasValue) { bool isDefault = httpContext.Request.Scheme == "http" && p.Value == 80;