Skip to content

Commit

Permalink
[core] Migrate to HttpClient everywhere (#475)
Browse files Browse the repository at this point in the history
If we move everything to HttpClient it makes it easier to support proxies in future.
  • Loading branch information
alanmcgovern authored Nov 7, 2021
1 parent dad4254 commit d04058e
Show file tree
Hide file tree
Showing 15 changed files with 53 additions and 201 deletions.
2 changes: 1 addition & 1 deletion src/DotNetCoreSample/DotNetCoreSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Exe</OutputType>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetCoreSample/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@
}
}
}
}
}
13 changes: 9 additions & 4 deletions src/MonoTorrent.Client/MonoTorrent.Client.Tracker/HTTPTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@
using System.Threading.Tasks;

using MonoTorrent.BEncoding;
using MonoTorrent.Connections;
using MonoTorrent.Logging;

using ReusableTasks;

namespace MonoTorrent.Client.Tracker
{
class HTTPTracker : Tracker
public class HTTPTracker : Tracker
{
static readonly Logger logger = Logger.Create (nameof (HTTPTracker));

Expand All @@ -58,7 +59,9 @@ class HTTPTracker : Tracker

internal Uri ScrapeUri { get; }

public HTTPTracker (Uri announceUrl)
Factories.HttpClientCreator HttpClientCreator { get; }

public HTTPTracker (Uri announceUrl, Factories.HttpClientCreator httpClientCreator)
: base (announceUrl)
{
string uri = announceUrl.OriginalString;
Expand All @@ -71,6 +74,8 @@ public HTTPTracker (Uri announceUrl)
CanScrape = ScrapeUri != null;
Status = TrackerState.Unknown;

HttpClientCreator = httpClientCreator;

// Use a random integer prefixed by our identifier.
lock (random)
Key = new BEncodedString ($"{VersionInfo.ClientVersion}-{random.Next (1, int.MaxValue)}");
Expand All @@ -89,7 +94,7 @@ protected override async ReusableTask<AnnounceResponse> DoAnnounceAsync (Announc
var peers = new List<Peer> ();

Uri announceString = CreateAnnounceString (parameters);
using var client = new HttpClient ();
using var client = HttpClientCreator ();
client.DefaultRequestHeaders.Add ("User-Agent", VersionInfo.ClientVersion);

HttpResponseMessage response;
Expand Down Expand Up @@ -136,7 +141,7 @@ protected override async ReusableTask<ScrapeResponse> DoScrapeAsync (ScrapeParam
else
url += $"&info_hash={parameters.InfoHash.UrlEncode ()}";

using var client = new HttpClient ();
using var client = HttpClientCreator ();
client.DefaultRequestHeaders.Add ("User-Agent", VersionInfo.ClientVersion);

HttpResponseMessage response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

namespace MonoTorrent.Client.Tracker
{
abstract class Tracker : ITracker
public abstract class Tracker : ITracker
{
public bool CanAnnounce { get; protected set; }
public bool CanScrape { get; protected set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public static class TrackerFactory
{
static readonly Dictionary<string, Func<Uri, ITracker>> trackerTypes = new Dictionary<string, Func<Uri, ITracker>> {
{ "udp", uri => new UdpTracker (uri) },
{ "http", uri => new HTTPTracker (uri) },
{ "https", uri => new HTTPTracker (uri) },
{ "http", uri => new HTTPTracker (uri, Factories.Default.CreateHttpClient) },
{ "https", uri => new HTTPTracker (uri, Factories.Default.CreateHttpClient) },
};

public static void Register (string protocol, Type trackerType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -70,7 +71,7 @@ public HttpRequestData (RequestMessage request)

Factories RequestCreator { get; }

IHttpRequest Requester { get; set; }
HttpClient Requester { get; set; }

public TimeSpan ConnectionTimeout {
get; set;
Expand Down Expand Up @@ -215,9 +216,11 @@ public async ReusableTask<int> ReceiveAsync (ByteBuffer buffer, int offset, int
var rr = WebRequests.Dequeue ();

Requester?.Dispose ();
Requester = RequestCreator.CreateHttpRequest ();
Requester.ConnectionTimeout = ConnectionTimeout;
DataStream = await Requester.GetStreamAsync (rr.fileUri, rr.startOffset, rr.count);
Requester = RequestCreator.CreateHttpClient ();
var msg = new HttpRequestMessage (HttpMethod.Get, rr.fileUri);
msg.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue (rr.startOffset, rr.startOffset + rr.count - 1);
Requester.Timeout = ConnectionTimeout;
DataStream = await (await Requester.SendAsync (msg)).Content.ReadAsStreamAsync ();
DataStreamCount = rr.count;
return await ReceiveAsync (buffer, offset, count) + written;
}
Expand Down
61 changes: 9 additions & 52 deletions src/MonoTorrent.Client/MonoTorrent/Torrent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

Expand Down Expand Up @@ -406,42 +407,20 @@ public static Task<Torrent> LoadAsync (Stream stream)
/// <summary>
/// Loads a .torrent file from the specified URL
/// </summary>
/// <param name="client">The HttpClient used to download the url</param>
/// <param name="url">The URL to download the .torrent from</param>
/// <param name="location">The path to download the .torrent to before it gets loaded</param>
/// <param name="savePath">The path to download the .torrent to before it gets loaded</param>
/// <returns></returns>
public static Torrent Load (Uri url, string location)
public static async Task<Torrent> LoadAsync (HttpClient client, Uri url, string savePath)
{
Check.Url (url);
Check.Location (location);

try {
using var client = new WebClient ();
client.DownloadFile (url, location);
File.WriteAllBytes (savePath, await client.GetByteArrayAsync (url));
} catch (Exception ex) {
File.Delete (location);
File.Delete (savePath);
throw new TorrentException ("Could not download .torrent file from the specified url", ex);
}

return Load (location);
}

/// <summary>
/// Loads a .torrent file from the specified URL
/// </summary>
/// <param name="url">The URL to download the .torrent from</param>
/// <param name="location">The path to download the .torrent to before it gets loaded</param>
/// <returns></returns>
public static async Task<Torrent> LoadAsync (Uri url, string location)
{
try {
using var client = new WebClient ();
await client.DownloadFileTaskAsync (url, location).ConfigureAwait (false);
} catch (Exception ex) {
File.Delete (location);
throw new TorrentException ("Could not download .torrent file from the specified url", ex);
}

return await LoadAsync (location).ConfigureAwait (false);
return await LoadAsync (savePath).ConfigureAwait (false);
}

/// <summary>
Expand Down Expand Up @@ -507,28 +486,6 @@ public static bool TryLoad (Stream stream, out Torrent torrent)
return torrent != null;
}

/// <summary>
/// Loads a .torrent file from the specified URL. A return value indicates
/// whether the operation was successful.
/// </summary>
/// <param name="url">The URL to download the .torrent from</param>
/// <param name="location">The path to download the .torrent to before it gets loaded</param>
/// <param name="torrent">If the loading was succesful it is assigned the Torrent</param>
/// <returns>True if successful</returns>
public static bool TryLoad (Uri url, string location, out Torrent torrent)
{
Check.Url (url);
Check.Location (location);

try {
torrent = Load (url, location);
} catch {
torrent = null;
}

return torrent != null;
}

/// <summary>
/// Called from either Load(stream) or Load(string).
/// </summary>
Expand All @@ -541,8 +498,8 @@ static Torrent Load (Stream stream, string path)
Check.Path (path);

try {
var decoded = BEncodedDictionary.DecodeTorrent (stream);
return LoadCore (decoded.torrent, new InfoHash (decoded.infohash));
(var torrent, var infohash) = BEncodedDictionary.DecodeTorrent (stream);
return LoadCore (torrent, new InfoHash (infohash));
} catch (BEncodingException ex) {
throw new TorrentException ("Invalid torrent file specified", ex);
}
Expand Down
75 changes: 0 additions & 75 deletions src/MonoTorrent.Connections/MonoTorrent.Connections/HttpRequest.cs

This file was deleted.

16 changes: 8 additions & 8 deletions src/MonoTorrent.Factories/Factories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Net;
using System.Security.Cryptography;
using System.Net.Http;

using MonoTorrent.Client.Connections;
using MonoTorrent.Client.Listeners;
Expand All @@ -18,7 +19,7 @@ public partial class Factories
{
public delegate IBlockCache BlockCacheCreator (IPieceWriter writer, long capacity, ByteBufferPool buffer);
public delegate IDhtListener DhtListenerCreator (IPEndPoint endpoint);
public delegate IHttpRequest HttpRequestCreator ();
public delegate HttpClient HttpClientCreator ();
public delegate ILocalPeerDiscovery LocalPeerDiscoveryCreator ();
public delegate IPeerConnection PeerConnectionCreator (Uri uri);
public delegate IPeerConnectionListener PeerConnectionListenerCreator (IPEndPoint endPoint);
Expand All @@ -38,8 +39,8 @@ public partial class Factories

BlockCacheCreator BlockCacheFunc { get; set; }
DhtListenerCreator DhtListenerFunc { get; set; }
HttpRequestCreator HttpRequestFunc { get; set; }
LocalPeerDiscoveryCreator LocalPeerDiscoveryFunc { get; set; }
HttpClientCreator HttpClientFunc { get; set; }
ReadOnlyDictionary<string, PeerConnectionCreator> PeerConnectionFuncs { get; set; }
PeerConnectionListenerCreator PeerConnectionListenerFunc { get; set; }
PieceRequesterCreator PieceRequesterFunc { get; set; }
Expand All @@ -58,7 +59,7 @@ public Factories ()

BlockCacheFunc = (writer, capacity, buffer) => new MemoryCache (buffer, capacity, writer);
DhtListenerFunc = endpoint => new DhtListener (endpoint);
HttpRequestFunc = () => new HttpRequest ();
HttpClientFunc = () => new HttpClient ();
LocalPeerDiscoveryFunc = () => new LocalPeerDiscovery ();
PeerConnectionFuncs = new ReadOnlyDictionary<string, PeerConnectionCreator> (
new Dictionary<string, PeerConnectionCreator> {
Expand Down Expand Up @@ -91,13 +92,12 @@ public Factories WithDhtListenerCreator (DhtListenerCreator creator)
dupe.DhtListenerFunc = creator ?? Default.DhtListenerFunc;
return dupe;
}

public IHttpRequest CreateHttpRequest ()
=> HttpRequestFunc ();
public Factories WithHttpRequestCreator (HttpRequestCreator creator)
public HttpClient CreateHttpClient ()
=> HttpClientFunc ();
public Factories WithHttpClientCreator (HttpClientCreator creator)
{
var dupe = MemberwiseClone ();
dupe.HttpRequestFunc = creator ?? Default.HttpRequestFunc;
dupe.HttpClientFunc = creator ?? Default.HttpClientFunc;
return dupe;
}

Expand Down
44 changes: 0 additions & 44 deletions src/MonoTorrent/MonoTorrent.Connections/IHttpRequest.cs

This file was deleted.

Loading

0 comments on commit d04058e

Please sign in to comment.