aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-09-28 12:50:33 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-09-28 12:50:33 -0400
commitc05cb1dcb1bb51cadc6e413395f2adb63cbab6ad (patch)
tree1b376930053e5eaed96e24d4a8ea49c16ed419f2 /MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
parent3be25f8bfbe6286d47ab5cf400fac7673e284d61 (diff)
fix mac ffmpeg build
Diffstat (limited to 'MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs')
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs120
1 files changed, 118 insertions, 2 deletions
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 5702af6d1..f761c0964 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Logging;
@@ -157,6 +158,20 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
}
/// <summary>
+ /// The _semaphoreLocks
+ /// </summary>
+ private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks = new ConcurrentDictionary<string, SemaphoreSlim>(StringComparer.OrdinalIgnoreCase);
+ /// <summary>
+ /// Gets the lock.
+ /// </summary>
+ /// <param name="url">The filename.</param>
+ /// <returns>System.Object.</returns>
+ private SemaphoreSlim GetLock(string url)
+ {
+ return _semaphoreLocks.GetOrAdd(url, key => new SemaphoreSlim(1, 1));
+ }
+
+ /// <summary>
/// Gets the response internal.
/// </summary>
/// <param name="options">The options.</param>
@@ -216,6 +231,107 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
/// </exception>
public async Task<HttpResponseInfo> SendAsync(HttpRequestOptions options, string httpMethod)
{
+ if (!options.EnableUnconditionalCache)
+ {
+ return await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
+ }
+
+ var url = options.Url;
+ var urlHash = url.ToLower().GetMD5().ToString("N");
+ var semaphore = GetLock(url);
+
+ var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash);
+
+ var response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
+ if (response != null)
+ {
+ return response;
+ }
+
+ await semaphore.WaitAsync(options.CancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ response = await GetCachedResponse(responseCachePath, options.CacheLength, url).ConfigureAwait(false);
+ if (response != null)
+ {
+ return response;
+ }
+
+ response = await SendAsyncInternal(options, httpMethod).ConfigureAwait(false);
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ await CacheResponse(response, responseCachePath).ConfigureAwait(false);
+ }
+
+ return response;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+
+ private async Task<HttpResponseInfo> GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url)
+ {
+ try
+ {
+ if (_fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow)
+ {
+ using (var stream = _fileSystem.GetFileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ {
+ var memoryStream = new MemoryStream();
+
+ await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
+ memoryStream.Position = 0;
+
+ return new HttpResponseInfo
+ {
+ ResponseUrl = url,
+ Content = memoryStream,
+ StatusCode = HttpStatusCode.OK,
+ Headers = new NameValueCollection(),
+ ContentLength = memoryStream.Length
+ };
+ }
+ }
+ }
+ catch (FileNotFoundException)
+ {
+
+ }
+ catch (DirectoryNotFoundException)
+ {
+
+ }
+
+ return null;
+ }
+
+ private async Task CacheResponse(HttpResponseInfo response, string responseCachePath)
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(responseCachePath));
+
+ using (var responseStream = response.Content)
+ {
+ using (var fileStream = _fileSystem.GetFileStream(responseCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
+ {
+ var memoryStream = new MemoryStream();
+
+ await responseStream.CopyToAsync(memoryStream).ConfigureAwait(false);
+
+ memoryStream.Position = 0;
+ await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
+
+ memoryStream.Position = 0;
+ response.Content = memoryStream;
+ }
+ }
+ }
+
+ private async Task<HttpResponseInfo> SendAsyncInternal(HttpRequestOptions options, string httpMethod)
+ {
ValidateParams(options);
options.CancellationToken.ThrowIfCancellationRequested();
@@ -236,11 +352,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
!string.IsNullOrEmpty(options.RequestContent) ||
string.Equals(httpMethod, "post", StringComparison.OrdinalIgnoreCase))
{
- var bytes = options.RequestContentBytes ??
+ var bytes = options.RequestContentBytes ??
Encoding.UTF8.GetBytes(options.RequestContent ?? string.Empty);
httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
-
+
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
}