diff --git a/YoutubeExplode/Utils/ClientDelegatingHandler.cs b/YoutubeExplode/Utils/ClientDelegatingHandler.cs index bcab6d98..02155d1d 100644 --- a/YoutubeExplode/Utils/ClientDelegatingHandler.cs +++ b/YoutubeExplode/Utils/ClientDelegatingHandler.cs @@ -1,10 +1,12 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using YoutubeExplode.Utils.Extensions; namespace YoutubeExplode.Utils; -// Used to extend an externally provided HttpClient with additional behavior +// Like DelegatingHandler, but wraps an HttpClient instead of an HttpMessageHandler. +// Used to extend an externally provided HttpClient with additional behavior. internal abstract class ClientDelegatingHandler : HttpMessageHandler { private readonly HttpClient _http; @@ -19,8 +21,18 @@ protected ClientDelegatingHandler(HttpClient http, bool disposeClient = false) protected override async Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken - ) => - await _http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); + ) + { + // Clone the request to reset its completion status, which is required + // in order to pass the request from one HttpClient to another. + using var clonedRequest = request.Clone(); + + return await _http.SendAsync( + clonedRequest, + HttpCompletionOption.ResponseHeadersRead, + cancellationToken + ); + } protected override void Dispose(bool disposing) { diff --git a/YoutubeExplode/Utils/Extensions/HttpExtensions.cs b/YoutubeExplode/Utils/Extensions/HttpExtensions.cs index 53780a3e..2bc31677 100644 --- a/YoutubeExplode/Utils/Extensions/HttpExtensions.cs +++ b/YoutubeExplode/Utils/Extensions/HttpExtensions.cs @@ -56,6 +56,7 @@ public static async ValueTask HeadAsync( ) { using var request = new HttpRequestMessage(HttpMethod.Head, requestUri); + return await http.SendAsync( request, HttpCompletionOption.ResponseHeadersRead, diff --git a/YoutubeExplode/YoutubeHttpHandler.cs b/YoutubeExplode/YoutubeHttpHandler.cs index b1cba91e..a5f8c246 100644 --- a/YoutubeExplode/YoutubeHttpHandler.cs +++ b/YoutubeExplode/YoutubeHttpHandler.cs @@ -168,10 +168,12 @@ CancellationToken cancellationToken { try { - using var clonedRequest = request.Clone(); - var response = HandleResponse( - await base.SendAsync(HandleRequest(clonedRequest), cancellationToken) + await base.SendAsync( + // Request will be cloned by the base handler + HandleRequest(request), + cancellationToken + ) ); // Retry on 5XX errors