Improved http timeout handling

This commit is contained in:
Qstick 2024-01-14 15:25:25 -06:00 committed by Mark McDowall
parent 1bba7e177b
commit f87a66fcba
2 changed files with 35 additions and 18 deletions

View File

@ -131,6 +131,16 @@ namespace NzbDrone.Common.Test.Http
response.Content.Should().NotBeNullOrWhiteSpace(); response.Content.Should().NotBeNullOrWhiteSpace();
} }
[Test]
public void should_throw_timeout_request()
{
var request = new HttpRequest($"https://{_httpBinHost}/delay/10");
request.RequestTimeout = new TimeSpan(0, 0, 5);
Assert.ThrowsAsync<WebException>(async () => await Subject.ExecuteAsync(request));
}
[Test] [Test]
public async Task should_execute_https_get() public async Task should_execute_https_get()
{ {

View File

@ -102,31 +102,38 @@ namespace NzbDrone.Common.Http.Dispatchers
var httpClient = GetClient(request.Url); var httpClient = GetClient(request.Url);
using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token); try
{ {
byte[] data = null; using var responseMessage = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token);
try
{ {
if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK) byte[] data = null;
try
{ {
await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token); if (request.ResponseStream != null && responseMessage.StatusCode == HttpStatusCode.OK)
{
await responseMessage.Content.CopyToAsync(request.ResponseStream, null, cts.Token);
}
else
{
data = await responseMessage.Content.ReadAsByteArrayAsync(cts.Token);
}
} }
else catch (Exception ex)
{ {
data = await responseMessage.Content.ReadAsByteArrayAsync(cts.Token); throw new WebException("Failed to read complete http response", ex, WebExceptionStatus.ReceiveFailure, null);
} }
var headers = responseMessage.Headers.ToNameValueCollection();
headers.Add(responseMessage.Content.Headers.ToNameValueCollection());
return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode, responseMessage.Version);
} }
catch (Exception ex) }
{ catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
throw new WebException("Failed to read complete http response", ex, WebExceptionStatus.ReceiveFailure, null); {
} throw new WebException("Http request timed out", ex.InnerException, WebExceptionStatus.Timeout, null);
var headers = responseMessage.Headers.ToNameValueCollection();
headers.Add(responseMessage.Content.Headers.ToNameValueCollection());
return new HttpResponse(request, new HttpHeader(headers), data, responseMessage.StatusCode, responseMessage.Version);
} }
} }