Allow to use TorHttpClient without relative URI to process only absolute HTTP requests.
MODIFY
WalletWasabi.Gui/Global.cs
WalletWasabi.Gui/Global.cs
@@ -158,9 +158,9 @@ namespace WalletWasabi.Gui
await TorManager.StartAsync(ensureRunning: true).ConfigureAwait(false);
}
- var httpClient = (Tor.Http.TorHttpClient)HttpClientFactory.NewHttpClient(() => null!, isolateStream: false);
+ Tor.Http.TorHttpClient torHttpClient = HttpClientFactory.NewTorHttpClient(isolateStream: false);
#pragma warning disable CA2000 // Dispose objects before losing scope
- HostedServices.Register(new TorMonitor(period: TimeSpan.FromSeconds(3), fallbackBackendUri: Config.GetFallbackBackendUri(), httpClient: httpClient, torProcessManager: TorManager), nameof(TorMonitor));
+ HostedServices.Register(new TorMonitor(period: TimeSpan.FromSeconds(3), fallbackBackendUri: Config.GetFallbackBackendUri(), torHttpClient, TorManager), nameof(TorMonitor));
#pragma warning restore CA2000 // Dispose objects before losing scope
}

MODIFY
WalletWasabi/Tor/Http/IHttpClient.cs
WalletWasabi/Tor/Http/IHttpClient.cs
@@ -11,7 +11,7 @@ namespace WalletWasabi.Tor.Http
/// <remarks>Relative HTTP requests are allowed only when <see cref="BaseUriGetter"/> returns non-<see langword="null"/> value.</remarks>
public interface IHttpClient
{
- Func<Uri?> BaseUriGetter { get; }
+ Func<Uri>? BaseUriGetter { get; }
/// <summary>Sends an HTTP(s) request.</summary>
/// <param name="request">HTTP request message to send.</param>

MODIFY
WalletWasabi/Tor/Http/TorHttpClient.cs
WalletWasabi/Tor/Http/TorHttpClient.cs
@@ -24,17 +24,22 @@ namespace WalletWasabi.Tor.Http
private volatile bool _disposedValue = false; // To detect redundant calls
+ /// <summary>Use this constructor when you want to issue absolute HTTP requests.</summary>
+ public TorHttpClient(EndPoint torSocks5EndPoint, bool isolateStream = false):
+ this(baseUriGetter: null, torSocks5EndPoint, isolateStream)
+ {
+ }
+
+ /// <summary>Use this constructor when you want to issue relative or absolute HTTP requests.</summary>
public TorHttpClient(Uri baseUri, EndPoint torSocks5EndPoint, bool isolateStream = false) :
this(() => baseUri, torSocks5EndPoint, isolateStream)
{
- baseUri = Guard.NotNull(nameof(baseUri), baseUri);
}
- public TorHttpClient(Func<Uri> baseUriGetter, EndPoint torSocks5EndPoint, bool isolateStream = false)
+ /// <summary>Use this constructor when you want to issue relative or absolute HTTP requests.</summary>
+ public TorHttpClient(Func<Uri>? baseUriGetter, EndPoint torSocks5EndPoint, bool isolateStream = false)
{
- BaseUriGetter = Guard.NotNull(nameof(baseUriGetter), baseUriGetter);
- Guard.NotNull(nameof(torSocks5EndPoint), torSocks5EndPoint);
-
+ BaseUriGetter = baseUriGetter;
TorSocks5EndPoint = torSocks5EndPoint;
TorSocks5Client = null;
IsolateStream = isolateStream;
@@ -58,7 +63,7 @@ namespace WalletWasabi.Tor.Http
public static Exception? LatestTorException { get; private set; } = null;
- public Func<Uri> BaseUriGetter { get; }
+ public Func<Uri>? BaseUriGetter { get; }
private EndPoint TorSocks5EndPoint { get; }
/// <summary>
@@ -72,8 +77,14 @@ namespace WalletWasabi.Tor.Http
/// <exception cref="HttpRequestException">When HTTP request fails to be processed. Inner exception may be an instance of <see cref="TorException"/>.</exception>
/// <exception cref="OperationCanceledException">When <paramref name="cancel"/> is canceled by the user.</exception>
+ /// <exception cref="InvalidOperationException">When a relative HTTP request is to be send but <see cref="BaseUriGetter"/> is <c>null</c>.</exception>
public async Task<HttpResponseMessage> SendAsync(HttpMethod method, string relativeUri, HttpContent? content = null, CancellationToken cancel = default)
{
+ if (BaseUriGetter is null)
+ {
+ throw new InvalidOperationException($"{nameof(BaseUriGetter)} is not set.");
+ }
+
Guard.NotNull(nameof(method), method);
relativeUri = Guard.NotNull(nameof(relativeUri), relativeUri);
Uri requestUri = new(BaseUriGetter(), relativeUri);

MODIFY
WalletWasabi/WebClients/Wasabi/HttpClientFactory.cs
WalletWasabi/WebClients/Wasabi/HttpClientFactory.cs
@@ -48,10 +48,10 @@ namespace WalletWasabi.WebClients.Wasabi
}
/// <summary>Tor SOCKS5 endpoint.</summary>
- /// <remarks>The property should be <c>>private</c> when Tor refactoring is done.</remarks>
+ /// <remarks>The property should be <c>private</c> when Tor refactoring is done.</remarks>
public EndPoint? TorEndpoint { get; }
- /// <remarks>The property should be <c>>private</c> when Tor refactoring is done.</remarks>
+ /// <remarks>The property should be <c>private</c> when Tor refactoring is done.</remarks>
public Func<Uri> BackendUriGetter { get; }
/// <summary>Whether Tor is enabled or disabled.</summary>
@@ -85,6 +85,19 @@ namespace WalletWasabi.WebClients.Wasabi
}
}
+ /// <summary>Creates new <see cref="TorHttpClient"/>.</summary>
+ /// <remarks>Do not use this function unless <see cref="NewHttpClient(Func{Uri}, bool)"/> is not sufficient for your use case.</remarks>
+ /// <exception cref="InvalidOperationException"/>
+ public TorHttpClient NewTorHttpClient(bool isolateStream, Func<Uri>? baseUriFn = null)
+ {
+ if (TorEndpoint is null)
+ {
+ throw new InvalidOperationException("Tor is not enabled in the user settings.");
+ }
+
+ return new TorHttpClient(baseUriFn, TorEndpoint, isolateStream);
+ }
+
/// <summary>
/// Creates a new <see cref="IHttpClient"/> with the base URI is set to Wasabi Backend.
/// </summary>

Allow to use TorHttpClient without relative URI to process only absolute HTTP requests.