From 67758609a7e97ff793af78ac036c518f1ea328b6 Mon Sep 17 00:00:00 2001 From: Dennis Reimann Date: Thu, 4 Jun 2020 08:53:55 +0200 Subject: [PATCH] Add Onion-Location HTTP header Closes #1626. --- BTCPayServer.Tests/UnitTest1.cs | 30 ++++++++++++++++++++++++ BTCPayServer/Hosting/BTCpayMiddleware.cs | 12 +++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/BTCPayServer.Tests/UnitTest1.cs b/BTCPayServer.Tests/UnitTest1.cs index 4e0acf2f6..63f8eff65 100644 --- a/BTCPayServer.Tests/UnitTest1.cs +++ b/BTCPayServer.Tests/UnitTest1.cs @@ -3607,6 +3607,36 @@ normal: } } + [Fact(Timeout = TestTimeout)] + [Trait("Integration", "Integration")] + public async void CheckOnionlocationForNonOnionHtmlRequests() + { + using (var tester = ServerTester.Create()) + { + await tester.StartAsync(); + + var url = tester.PayTester.ServerUri.AbsoluteUri; + HttpClient client = new HttpClient(); + + // check onion location is present for HTML page request + using var htmlRequest = new HttpRequestMessage(HttpMethod.Get, new Uri(url)); + htmlRequest.Headers.TryAddWithoutValidation("Accept", "text/html,*/*"); + + var htmlResponse = await client.SendAsync(htmlRequest); + htmlResponse.EnsureSuccessStatusCode(); + Assert.True(htmlResponse.Headers.TryGetValues("Onion-Location", out var onionLocation)); + Assert.StartsWith("http://wsaxew3qa5ljfuenfebmaf3m5ykgatct3p6zjrqwoouj3foererde3id.onion", onionLocation.FirstOrDefault() ?? "no-onion-location-header"); + + // no onion location for other mime types + using var otherRequest = new HttpRequestMessage(HttpMethod.Get, new Uri(url)); + otherRequest.Headers.TryAddWithoutValidation("Accept", "*/*"); + + var otherResponse = await client.SendAsync(otherRequest); + otherResponse.EnsureSuccessStatusCode(); + Assert.False(otherResponse.Headers.Contains("Onion-Location")); + } + } + private static bool IsMapped(Invoice invoice, ApplicationDbContext ctx) { var h = BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest).ScriptPubKey.Hash.ToString(); diff --git a/BTCPayServer/Hosting/BTCpayMiddleware.cs b/BTCPayServer/Hosting/BTCpayMiddleware.cs index 7175fd0d4..ecd5f3137 100644 --- a/BTCPayServer/Hosting/BTCpayMiddleware.cs +++ b/BTCPayServer/Hosting/BTCpayMiddleware.cs @@ -12,6 +12,7 @@ using Newtonsoft.Json; using BTCPayServer.Models; using BTCPayServer.Configuration; using System.Net.WebSockets; +using BTCPayServer.Services; using BTCPayServer.Services.Stores; namespace BTCPayServer.Hosting @@ -20,10 +21,13 @@ namespace BTCPayServer.Hosting { RequestDelegate _Next; BTCPayServerOptions _Options; + BTCPayServerEnvironment _Env; public BTCPayMiddleware(RequestDelegate next, - BTCPayServerOptions options) + BTCPayServerOptions options, + BTCPayServerEnvironment env) { + _Env = env ?? throw new ArgumentNullException(nameof(env)); _Next = next ?? throw new ArgumentNullException(nameof(next)); _Options = options ?? throw new ArgumentNullException(nameof(options)); } @@ -56,6 +60,12 @@ namespace BTCPayServer.Hosting await _Next(httpContext); return; } + + if (!httpContext.Request.IsOnion() && (httpContext.Request.Headers["Accept"].ToString().StartsWith("text/html", StringComparison.InvariantCulture))) + { + var onionLocation = _Env.OnionUrl + httpContext.Request.Path; + httpContext.Response.SetHeader("Onion-Location", onionLocation); + } } catch (WebSocketException) { }