Merge pull request #1633 from dennisreimann/onion-location

Add Onion-Location HTTP header
This commit is contained in:
Nicolas Dorier 2020-06-05 11:09:55 +09:00 committed by GitHub
commit c338779f0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View file

@ -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) private static bool IsMapped(Invoice invoice, ApplicationDbContext ctx)
{ {
var h = BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest).ScriptPubKey.Hash.ToString(); var h = BitcoinAddress.Create(invoice.BitcoinAddress, Network.RegTest).ScriptPubKey.Hash.ToString();

View file

@ -12,6 +12,7 @@ using Newtonsoft.Json;
using BTCPayServer.Models; using BTCPayServer.Models;
using BTCPayServer.Configuration; using BTCPayServer.Configuration;
using System.Net.WebSockets; using System.Net.WebSockets;
using BTCPayServer.Services;
using BTCPayServer.Services.Stores; using BTCPayServer.Services.Stores;
namespace BTCPayServer.Hosting namespace BTCPayServer.Hosting
@ -20,10 +21,13 @@ namespace BTCPayServer.Hosting
{ {
RequestDelegate _Next; RequestDelegate _Next;
BTCPayServerOptions _Options; BTCPayServerOptions _Options;
BTCPayServerEnvironment _Env;
public BTCPayMiddleware(RequestDelegate next, public BTCPayMiddleware(RequestDelegate next,
BTCPayServerOptions options) BTCPayServerOptions options,
BTCPayServerEnvironment env)
{ {
_Env = env ?? throw new ArgumentNullException(nameof(env));
_Next = next ?? throw new ArgumentNullException(nameof(next)); _Next = next ?? throw new ArgumentNullException(nameof(next));
_Options = options ?? throw new ArgumentNullException(nameof(options)); _Options = options ?? throw new ArgumentNullException(nameof(options));
} }
@ -56,6 +60,12 @@ namespace BTCPayServer.Hosting
await _Next(httpContext); await _Next(httpContext);
return; 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) catch (WebSocketException)
{ } { }