From 009e860f6f6c939f1fb332d84d387f0e7f519858 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 22 Dec 2016 11:47:43 -0500 Subject: [PATCH] limit http compression --- .../HttpServer/HttpResultFactory.cs | 71 +++++++++---------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 995dc7b7b0..e78446bc84 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -203,20 +203,12 @@ namespace Emby.Server.Implementations.HttpServer // Do not use the memoryStreamFactory here, they don't place nice with compression using (var ms = new MemoryStream()) { - using (var compressionStream = GetCompressionStream(ms, compressionType)) - { - ContentTypes.Instance.SerializeToStream(request, dto, compressionStream); - compressionStream.Dispose(); - - var compressedBytes = ms.ToArray(); + ContentTypes.Instance.SerializeToStream(request, dto, ms); + ms.Position = 0; - var httpResult = new StreamWriter(compressedBytes, request.ResponseContentType, _logger); + var responseHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); - //httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture); - httpResult.Headers["Content-Encoding"] = compressionType; - - return httpResult; - } + return GetCompressedResult(ms, compressionType, responseHeaders, false, request.ResponseContentType).Result; } } @@ -591,45 +583,53 @@ namespace Emby.Server.Implementations.HttpServer }; } - string content; - using (var stream = await factoryFn().ConfigureAwait(false)) { - using (var reader = new StreamReader(stream)) + return await GetCompressedResult(stream, requestedCompressionType, responseHeaders, isHeadRequest, contentType).ConfigureAwait(false); + } + } + + private async Task GetCompressedResult(Stream stream, + string requestedCompressionType, + IDictionary responseHeaders, + bool isHeadRequest, + string contentType) + { + using (var reader = new MemoryStream()) + { + await stream.CopyToAsync(reader).ConfigureAwait(false); + + reader.Position = 0; + var content = reader.ToArray(); + + if (content.Length >= 1024) { - content = await reader.ReadToEndAsync().ConfigureAwait(false); + content = Compress(content, requestedCompressionType); + responseHeaders["Content-Encoding"] = requestedCompressionType; } - } - var contents = Compress(content, requestedCompressionType); + responseHeaders["Content-Length"] = content.Length.ToString(UsCulture); - responseHeaders["Content-Length"] = contents.Length.ToString(UsCulture); - responseHeaders["Content-Encoding"] = requestedCompressionType; + if (isHeadRequest) + { + return GetHttpResult(new byte[] { }, contentType, true); + } - if (isHeadRequest) - { - return GetHttpResult(new byte[] { }, contentType, true); + return GetHttpResult(content, contentType, true, responseHeaders); } - - return GetHttpResult(contents, contentType, true, responseHeaders); } - private byte[] Compress(string text, string compressionType) + private byte[] Compress(byte[] bytes, string compressionType) { if (compressionType == "deflate") - return Deflate(text); + return Deflate(bytes); if (compressionType == "gzip") - return GZip(text); + return GZip(bytes); throw new NotSupportedException(compressionType); } - private byte[] Deflate(string text) - { - return Deflate(Encoding.UTF8.GetBytes(text)); - } - private byte[] Deflate(byte[] bytes) { // In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream @@ -644,11 +644,6 @@ namespace Emby.Server.Implementations.HttpServer } } - private byte[] GZip(string text) - { - return GZip(Encoding.UTF8.GetBytes(text)); - } - private byte[] GZip(byte[] buffer) { using (var ms = new MemoryStream())