aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs')
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs145
1 files changed, 76 insertions, 69 deletions
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 89f405e8a..f4d4826eb 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -17,6 +17,7 @@ using System.Net.Cache;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Common.Implementations.HttpClientManager
{
@@ -282,8 +283,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
var url = options.Url;
var urlHash = url.ToLower().GetMD5().ToString("N");
- var semaphore = GetLock(url);
-
+
var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
@@ -292,6 +292,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
return response;
}
+ var semaphore = GetLock(url);
+
await semaphore.WaitAsync(options.CancellationToken).ConfigureAwait(false);
try
@@ -355,7 +357,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
private async Task CacheResponse(HttpResponseInfo response, string responseCachePath)
{
- Directory.CreateDirectory(Path.GetDirectoryName(responseCachePath));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(responseCachePath));
using (var responseStream = response.Content)
{
@@ -464,20 +466,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
catch (OperationCanceledException ex)
{
- var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
-
- var httpException = exception as HttpException;
-
- if (httpException != null && httpException.IsTimedOut)
- {
- client.LastTimeout = DateTime.UtcNow;
- }
-
- throw exception;
+ throw GetCancellationException(options, client, options.CancellationToken, ex);
}
catch (Exception ex)
{
- throw GetException(ex, options);
+ throw GetException(ex, options, client);
}
finally
{
@@ -488,27 +481,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
}
- /// <summary>
- /// Gets the exception.
- /// </summary>
- /// <param name="ex">The ex.</param>
- /// <param name="options">The options.</param>
- /// <returns>HttpException.</returns>
- private HttpException GetException(WebException ex, HttpRequestOptions options)
- {
- _logger.ErrorException("Error getting response from " + options.Url, ex);
-
- var exception = new HttpException(ex.Message, ex);
-
- var response = ex.Response as HttpWebResponse;
- if (response != null)
- {
- exception.StatusCode = response.StatusCode;
- }
-
- return exception;
- }
-
private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
{
return new HttpResponseInfo(disposable)
@@ -599,7 +571,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
{
ValidateParams(options);
- Directory.CreateDirectory(_appPaths.TempDirectory);
+ _fileSystem.CreateDirectory(_appPaths.TempDirectory);
var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
@@ -624,6 +596,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
_logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
}
+ var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
+
try
{
options.CancellationToken.ThrowIfCancellationRequested();
@@ -632,7 +606,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
{
var httpResponse = (HttpWebResponse)response;
- var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
EnsureSuccessStatusCode(client, httpResponse, options);
options.CancellationToken.ThrowIfCancellationRequested();
@@ -669,7 +642,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
catch (Exception ex)
{
DeleteTempFile(tempFile);
- throw GetException(ex, options);
+ throw GetException(ex, options, client);
}
finally
{
@@ -694,14 +667,37 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
- private Exception GetException(Exception ex, HttpRequestOptions options)
+ private Exception GetException(Exception ex, HttpRequestOptions options, HttpClientInfo client)
{
+ if (ex is HttpException)
+ {
+ return ex;
+ }
+
var webException = ex as WebException
?? ex.InnerException as WebException;
if (webException != null)
{
- return GetException(webException, options);
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
+
+ var exception = new HttpException(ex.Message, ex);
+
+ var response = webException.Response as HttpWebResponse;
+ if (response != null)
+ {
+ exception.StatusCode = response.StatusCode;
+
+ if ((int)response.StatusCode == 429)
+ {
+ client.LastTimeout = DateTime.UtcNow;
+ }
+ }
+
+ return exception;
}
var operationCanceledException = ex as OperationCanceledException
@@ -709,10 +705,13 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
if (operationCanceledException != null)
{
- return GetCancellationException(options.Url, options.CancellationToken, operationCanceledException);
+ return GetCancellationException(options, client, options.CancellationToken, operationCanceledException);
}
- _logger.ErrorException("Error getting response from " + options.Url, ex);
+ if (options.LogErrors)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+ }
return ex;
}
@@ -784,18 +783,24 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
/// <summary>
/// Throws the cancellation exception.
/// </summary>
- /// <param name="url">The URL.</param>
+ /// <param name="options">The options.</param>
+ /// <param name="client">The client.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="exception">The exception.</param>
/// <returns>Exception.</returns>
- private Exception GetCancellationException(string url, CancellationToken cancellationToken, OperationCanceledException exception)
+ private Exception GetCancellationException(HttpRequestOptions options, HttpClientInfo client, CancellationToken cancellationToken, OperationCanceledException exception)
{
// If the HttpClient's timeout is reached, it will cancel the Task internally
if (!cancellationToken.IsCancellationRequested)
{
- var msg = string.Format("Connection to {0} timed out", url);
+ var msg = string.Format("Connection to {0} timed out", options.Url);
+
+ if (options.LogErrors)
+ {
+ _logger.Error(msg);
+ }
- _logger.Error(msg);
+ client.LastTimeout = DateTime.UtcNow;
// Throw an HttpException so that the caller doesn't think it was cancelled by user code
return new HttpException(msg, exception)
@@ -815,12 +820,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
if (!isSuccessful)
{
- if ((int) statusCode == 429)
- {
- client.LastTimeout = DateTime.UtcNow;
- }
-
- if (statusCode == HttpStatusCode.RequestEntityTooLarge)
if (options.LogErrorResponseBody)
{
try
@@ -869,25 +868,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
Task<WebResponse> asyncTask = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
ThreadPool.RegisterWaitForSingleObject((asyncTask as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, timeout, true);
- asyncTask.ContinueWith(task =>
- {
- taskCompletion.TrySetResult(task.Result);
-
- }, TaskContinuationOptions.NotOnFaulted);
+ var callback = new TaskCallback { taskCompletion = taskCompletion };
+ asyncTask.ContinueWith(callback.OnSuccess, TaskContinuationOptions.NotOnFaulted);
// Handle errors
- asyncTask.ContinueWith(task =>
- {
- if (task.Exception != null)
- {
- taskCompletion.TrySetException(task.Exception);
- }
- else
- {
- taskCompletion.TrySetException(new List<Exception>());
- }
-
- }, TaskContinuationOptions.OnlyOnFaulted);
+ asyncTask.ContinueWith(callback.OnError, TaskContinuationOptions.OnlyOnFaulted);
return taskCompletion.Task;
}
@@ -903,5 +888,27 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
}
}
+
+ private class TaskCallback
+ {
+ public TaskCompletionSource<WebResponse> taskCompletion;
+
+ public void OnSuccess(Task<WebResponse> task)
+ {
+ taskCompletion.TrySetResult(task.Result);
+ }
+
+ public void OnError(Task<WebResponse> task)
+ {
+ if (task.Exception != null)
+ {
+ taskCompletion.TrySetException(task.Exception);
+ }
+ else
+ {
+ taskCompletion.TrySetException(new List<Exception>());
+ }
+ }
+ }
}
}