switch from httpclient to plain httpwebrequest
This commit is contained in:
parent
9b9e5fc4e4
commit
0bdc8a49d5
|
@ -22,7 +22,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -353,7 +352,7 @@ namespace MediaBrowser.Common.Implementations
|
|||
FileSystemManager = CreateFileSystemManager();
|
||||
RegisterSingleInstance(FileSystemManager);
|
||||
|
||||
HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger, CreateHttpClient, FileSystemManager);
|
||||
HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger, FileSystemManager);
|
||||
RegisterSingleInstance(HttpClient);
|
||||
|
||||
NetworkManager = CreateNetworkManager();
|
||||
|
@ -378,8 +377,6 @@ namespace MediaBrowser.Common.Implementations
|
|||
return new CommonFileSystem(Logger, true);
|
||||
}
|
||||
|
||||
protected abstract HttpClient CreateHttpClient(bool enableHttpCompression);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of types within an assembly
|
||||
/// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace MediaBrowser.Common.Implementations.HttpClientManager
|
||||
{
|
||||
|
@ -8,11 +7,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// </summary>
|
||||
public class HttpClientInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP client.
|
||||
/// </summary>
|
||||
/// <value>The HTTP client.</value>
|
||||
public HttpClient HttpClient { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the last timeout.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
@ -10,7 +9,10 @@ using System.Collections.Generic;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Cache;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -32,9 +34,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// </summary>
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
|
||||
public delegate HttpClient GetHttpClientHandler(bool enableHttpCompression);
|
||||
|
||||
private readonly GetHttpClientHandler _getHttpClientHandler;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
/// <summary>
|
||||
|
@ -48,7 +47,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// or
|
||||
/// logger
|
||||
/// </exception>
|
||||
public HttpClientManager(IApplicationPaths appPaths, ILogger logger, GetHttpClientHandler getHttpClientHandler, IFileSystem fileSystem)
|
||||
public HttpClientManager(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
|
||||
{
|
||||
if (appPaths == null)
|
||||
{
|
||||
|
@ -60,7 +59,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
}
|
||||
|
||||
_logger = logger;
|
||||
_getHttpClientHandler = getHttpClientHandler;
|
||||
_fileSystem = fileSystem;
|
||||
_appPaths = appPaths;
|
||||
}
|
||||
|
@ -92,17 +90,58 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
if (!_httpClients.TryGetValue(key, out client))
|
||||
{
|
||||
client = new HttpClientInfo
|
||||
{
|
||||
client = new HttpClientInfo();
|
||||
|
||||
HttpClient = _getHttpClientHandler(enableHttpCompression)
|
||||
};
|
||||
_httpClients.TryAdd(key, client);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
private PropertyInfo _httpBehaviorPropertyInfo;
|
||||
|
||||
private HttpWebRequest GetRequest(HttpRequestOptions options, string method, bool enableHttpCompression)
|
||||
{
|
||||
var request = HttpWebRequest.CreateHttp(options.Url);
|
||||
|
||||
if (!string.IsNullOrEmpty(options.AcceptHeader))
|
||||
{
|
||||
request.Accept = options.AcceptHeader;
|
||||
}
|
||||
|
||||
request.AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None;
|
||||
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);
|
||||
request.ConnectionGroupName = GetHostFromUrl(options.Url);
|
||||
request.KeepAlive = true;
|
||||
request.Method = method;
|
||||
request.Pipelined = true;
|
||||
request.Timeout = 20000;
|
||||
|
||||
if (!string.IsNullOrEmpty(options.UserAgent))
|
||||
{
|
||||
request.UserAgent = options.UserAgent;
|
||||
}
|
||||
|
||||
var sp = request.ServicePoint;
|
||||
|
||||
if (_httpBehaviorPropertyInfo == null)
|
||||
{
|
||||
_httpBehaviorPropertyInfo = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
_httpBehaviorPropertyInfo.SetValue(sp, (byte)0, null);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response internal.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="httpMethod">The HTTP method.</param>
|
||||
/// <returns>Task{HttpResponseInfo}.</returns>
|
||||
/// <exception cref="HttpException">
|
||||
/// </exception>
|
||||
public async Task<HttpResponseInfo> GetResponse(HttpRequestOptions options)
|
||||
{
|
||||
ValidateParams(options.Url, options.CancellationToken);
|
||||
|
@ -116,75 +155,92 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true };
|
||||
}
|
||||
|
||||
using (var message = GetHttpRequestMessage(options))
|
||||
var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression);
|
||||
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
|
||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
|
||||
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
||||
}
|
||||
|
||||
_logger.Info("HttpClientManager.GET url: {0}", options.Url);
|
||||
|
||||
try
|
||||
{
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
var httpResponse = (HttpWebResponse)response;
|
||||
|
||||
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
||||
}
|
||||
|
||||
_logger.Info("HttpClientManager.Get url: {0}", options.Url);
|
||||
|
||||
try
|
||||
{
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var response = await client.HttpClient.SendAsync(message, HttpCompletionOption.ResponseContentRead, options.CancellationToken).ConfigureAwait(false);
|
||||
|
||||
EnsureSuccessStatusCode(response);
|
||||
EnsureSuccessStatusCode(httpResponse);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
return new HttpResponseInfo
|
||||
using (var stream = httpResponse.GetResponseStream())
|
||||
{
|
||||
Content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
|
||||
var memoryStream = new MemoryStream();
|
||||
|
||||
StatusCode = response.StatusCode,
|
||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||
|
||||
ContentType = response.Content.Headers.ContentType.MediaType
|
||||
};
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
var httpException = exception as HttpException;
|
||||
return new HttpResponseInfo
|
||||
{
|
||||
Content = memoryStream,
|
||||
|
||||
if (httpException != null && httpException.IsTimedOut)
|
||||
{
|
||||
client.LastTimeout = DateTime.UtcNow;
|
||||
StatusCode = httpResponse.StatusCode,
|
||||
|
||||
ContentType = httpResponse.ContentType
|
||||
};
|
||||
}
|
||||
|
||||
throw exception;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
var httpException = exception as HttpException;
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
if (httpException != null && httpException.IsTimedOut)
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
client.LastTimeout = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
throw exception;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,81 +254,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
|
||||
public async Task<Stream> Get(HttpRequestOptions options)
|
||||
{
|
||||
ValidateParams(options.Url, options.CancellationToken);
|
||||
var response = await GetResponse(options).ConfigureAwait(false);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
|
||||
|
||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
|
||||
{
|
||||
throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true };
|
||||
}
|
||||
|
||||
using (var message = GetHttpRequestMessage(options))
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
|
||||
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
|
||||
}
|
||||
|
||||
_logger.Info("HttpClientManager.Get url: {0}", options.Url);
|
||||
|
||||
try
|
||||
{
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var response = await client.HttpClient.SendAsync(message, HttpCompletionOption.ResponseContentRead, options.CancellationToken).ConfigureAwait(false);
|
||||
|
||||
EnsureSuccessStatusCode(response);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
return await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
}
|
||||
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;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -303,6 +287,96 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
return Get(url, null, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a POST request
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <param name="postData">Params to add to the POST data.</param>
|
||||
/// <returns>stream on success, null on failure</returns>
|
||||
/// <exception cref="HttpException">
|
||||
/// </exception>
|
||||
/// <exception cref="System.ArgumentNullException">postData</exception>
|
||||
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
|
||||
public async Task<Stream> Post(HttpRequestOptions options, Dictionary<string, string> postData)
|
||||
{
|
||||
ValidateParams(options.Url, options.CancellationToken);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var httpWebRequest = GetRequest(options, "POST", options.EnableHttpCompression);
|
||||
|
||||
var strings = postData.Keys.Select(key => string.Format("{0}={1}", key, postData[key]));
|
||||
var postContent = string.Join("&", strings.ToArray());
|
||||
var bytes = Encoding.UTF8.GetBytes(postContent);
|
||||
|
||||
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
|
||||
httpWebRequest.ContentLength = bytes.Length;
|
||||
httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
|
||||
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.Info("HttpClientManager.POST url: {0}", options.Url);
|
||||
|
||||
try
|
||||
{
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
|
||||
{
|
||||
var httpResponse = (HttpWebResponse)response;
|
||||
|
||||
EnsureSuccessStatusCode(httpResponse);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var stream = httpResponse.GetResponseStream())
|
||||
{
|
||||
var memoryStream = new MemoryStream();
|
||||
|
||||
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
|
||||
|
||||
memoryStream.Position = 0;
|
||||
|
||||
return memoryStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
options.ResourcePool.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a POST request
|
||||
/// </summary>
|
||||
|
@ -311,57 +385,15 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
/// <param name="resourcePool">The resource pool.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>stream on success, null on failure</returns>
|
||||
/// <exception cref="System.ArgumentNullException">postData</exception>
|
||||
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
|
||||
public async Task<Stream> Post(string url, Dictionary<string, string> postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
|
||||
public Task<Stream> Post(string url, Dictionary<string, string> postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
|
||||
{
|
||||
ValidateParams(url, cancellationToken);
|
||||
|
||||
if (postData == null)
|
||||
return Post(new HttpRequestOptions
|
||||
{
|
||||
throw new ArgumentNullException("postData");
|
||||
}
|
||||
Url = url,
|
||||
ResourcePool = resourcePool,
|
||||
CancellationToken = cancellationToken
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var strings = postData.Keys.Select(key => string.Format("{0}={1}", key, postData[key]));
|
||||
var postContent = string.Join("&", strings.ToArray());
|
||||
var content = new StringContent(postContent, Encoding.UTF8, "application/x-www-form-urlencoded");
|
||||
|
||||
if (resourcePool != null)
|
||||
{
|
||||
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.Info("HttpClientManager.Post url: {0}", url);
|
||||
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var msg = await GetHttpClient(GetHostFromUrl(url), true).HttpClient.PostAsync(url, content, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
EnsureSuccessStatusCode(msg);
|
||||
|
||||
return await msg.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
throw GetCancellationException(url, cancellationToken, ex);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (resourcePool != null)
|
||||
{
|
||||
resourcePool.Release();
|
||||
}
|
||||
}
|
||||
}, postData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -392,6 +424,8 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression);
|
||||
|
||||
if (options.ResourcePool != null)
|
||||
{
|
||||
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
|
||||
|
@ -399,60 +433,79 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
|
||||
options.Progress.Report(0);
|
||||
|
||||
_logger.Info("HttpClientManager.GetTempFile url: {0}, temp file: {1}", options.Url, tempFile);
|
||||
_logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
|
||||
|
||||
try
|
||||
{
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var message = GetHttpRequestMessage(options))
|
||||
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
|
||||
{
|
||||
using (var response = await GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression).HttpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, options.CancellationToken).ConfigureAwait(false))
|
||||
var httpResponse = (HttpWebResponse)response;
|
||||
|
||||
EnsureSuccessStatusCode(httpResponse);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var contentLength = GetContentLength(httpResponse);
|
||||
|
||||
if (!contentLength.HasValue)
|
||||
{
|
||||
EnsureSuccessStatusCode(response);
|
||||
|
||||
options.CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var contentLength = GetContentLength(response);
|
||||
|
||||
if (!contentLength.HasValue)
|
||||
// We're not able to track progress
|
||||
using (var stream = httpResponse.GetResponseStream())
|
||||
{
|
||||
// We're not able to track progress
|
||||
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var stream = ProgressStream.CreateReadProgressStream(await response.Content.ReadAsStreamAsync().ConfigureAwait(false), options.Progress.Report, contentLength.Value))
|
||||
{
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options.Progress.Report(100);
|
||||
|
||||
return new HttpResponseInfo
|
||||
{
|
||||
TempFilePath = tempFile,
|
||||
|
||||
StatusCode = response.StatusCode,
|
||||
|
||||
ContentType = response.Content.Headers.ContentType.MediaType
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var stream = ProgressStream.CreateReadProgressStream(httpResponse.GetResponseStream(), options.Progress.Report, contentLength.Value))
|
||||
{
|
||||
using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
await stream.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, options.CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options.Progress.Report(100);
|
||||
|
||||
return new HttpResponseInfo
|
||||
{
|
||||
TempFilePath = tempFile,
|
||||
|
||||
StatusCode = httpResponse.StatusCode,
|
||||
|
||||
ContentType = httpResponse.ContentType
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException ex)
|
||||
{
|
||||
var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw new HttpException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw GetTempFileException(ex, options, tempFile);
|
||||
_logger.ErrorException("Error getting response from " + options.Url, ex);
|
||||
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -522,6 +575,18 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
return long.Parse(string.Join(string.Empty, lengthValues.ToArray()), UsCulture);
|
||||
}
|
||||
|
||||
private long? GetContentLength(HttpWebResponse response)
|
||||
{
|
||||
var length = response.ContentLength;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
|
@ -614,11 +679,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
{
|
||||
if (dispose)
|
||||
{
|
||||
foreach (var client in _httpClients.Values.ToList())
|
||||
{
|
||||
client.HttpClient.Dispose();
|
||||
}
|
||||
|
||||
_httpClients.Clear();
|
||||
}
|
||||
}
|
||||
|
@ -659,6 +719,17 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
|
|||
}
|
||||
}
|
||||
|
||||
private void EnsureSuccessStatusCode(HttpWebResponse response)
|
||||
{
|
||||
var statusCode = response.StatusCode;
|
||||
var isSuccessful = statusCode >= HttpStatusCode.OK && statusCode <= (HttpStatusCode)299;
|
||||
|
||||
if (!isSuccessful)
|
||||
{
|
||||
throw new HttpException(response.StatusDescription) { StatusCode = response.StatusCode };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the specified URL.
|
||||
/// </summary>
|
||||
|
|
|
@ -73,6 +73,11 @@ namespace MediaBrowser.Common.Net
|
|||
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
|
||||
Task<string> GetTempFile(HttpRequestOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the temporary file response.
|
||||
/// </summary>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>Task{HttpResponseInfo}.</returns>
|
||||
Task<HttpResponseInfo> GetTempFileResponse(HttpRequestOptions options);
|
||||
}
|
||||
}
|
|
@ -702,16 +702,6 @@ namespace MediaBrowser.ServerApplication
|
|||
OnApplicationUpdated(package.version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the HTTP client.
|
||||
/// </summary>
|
||||
/// <param name="enableHttpCompression">if set to <c>true</c> [enable HTTP compression].</param>
|
||||
/// <returns>HttpClient.</returns>
|
||||
protected override HttpClient CreateHttpClient(bool enableHttpCompression)
|
||||
{
|
||||
return HttpClientFactory.GetHttpClient(enableHttpCompression);
|
||||
}
|
||||
|
||||
protected override void ConfigureAutoRunAtStartup(bool autorun)
|
||||
{
|
||||
Autorun.Configure(autorun);
|
||||
|
|
|
@ -190,7 +190,6 @@
|
|||
<Compile Include="FFMpeg\FFMpegInfo.cs" />
|
||||
<Compile Include="IO\FileSystemFactory.cs" />
|
||||
<Compile Include="Native\Assemblies.cs" />
|
||||
<Compile Include="Native\HttpClientFactory.cs" />
|
||||
<Compile Include="Native\NativeApp.cs" />
|
||||
<Compile Include="IO\NativeFileSystem.cs" />
|
||||
<Compile Include="Native\ServerAuthorization.cs" />
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Cache;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.Native
|
||||
{
|
||||
/// <summary>
|
||||
/// Class HttpClientFactory
|
||||
/// </summary>
|
||||
public static class HttpClientFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the HTTP client.
|
||||
/// </summary>
|
||||
/// <param name="enableHttpCompression">if set to <c>true</c> [enable HTTP compression].</param>
|
||||
/// <returns>HttpClient.</returns>
|
||||
public static HttpClient GetHttpClient(bool enableHttpCompression)
|
||||
{
|
||||
var client = new HttpClient(new WebRequestHandler
|
||||
{
|
||||
CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate),
|
||||
AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None
|
||||
|
||||
})
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(20)
|
||||
};
|
||||
|
||||
client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user