From c05cb1dcb1bb51cadc6e413395f2adb63cbab6ad Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 28 Sep 2014 12:50:33 -0400 Subject: fix mac ffmpeg build --- .../HttpClientManager/HttpClientManager.cs | 120 ++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs') 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; @@ -156,6 +157,20 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager } } + /// + /// The _semaphoreLocks + /// + private readonly ConcurrentDictionary _semaphoreLocks = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + /// + /// Gets the lock. + /// + /// The filename. + /// System.Object. + private SemaphoreSlim GetLock(string url) + { + return _semaphoreLocks.GetOrAdd(url, key => new SemaphoreSlim(1, 1)); + } + /// /// Gets the response internal. /// @@ -215,6 +230,107 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager /// /// public async Task 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 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 SendAsyncInternal(HttpRequestOptions options, string httpMethod) { ValidateParams(options); @@ -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); } -- cgit v1.2.3