Просмотр исходного кода

Added auto-detection of client-capabilities to determine whether to use gzip or deflate

LukePulverenti Luke Pulverenti luke pulverenti 13 лет назад
Родитель
Сommit
027d1724e5
2 измененных файлов с 78 добавлено и 33 удалено
  1. 77 3
      MediaBrowser.Common/Net/Handlers/BaseHandler.cs
  2. 1 30
      MediaBrowser.Common/Net/RequestContext.cs

+ 77 - 3
MediaBrowser.Common/Net/Handlers/BaseHandler.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Collections.Specialized;
 using System.IO;
 using System.IO;
 using System.IO.Compression;
 using System.IO.Compression;
+using System.Net;
 
 
 namespace MediaBrowser.Common.Net.Handlers
 namespace MediaBrowser.Common.Net.Handlers
 {
 {
@@ -46,7 +47,7 @@ namespace MediaBrowser.Common.Net.Handlers
         /// <summary>
         /// <summary>
         /// The action to write the response to the output stream
         /// The action to write the response to the output stream
         /// </summary>
         /// </summary>
-        public virtual Action<Stream> WriteStream
+        public Action<Stream> WriteStream
         {
         {
             get
             get
             {
             {
@@ -125,11 +126,84 @@ namespace MediaBrowser.Common.Net.Handlers
             }
             }
         }
         }
 
 
+        private bool ClientSupportsCompression
+        {
+            get
+            {
+                string enc = RequestContext.Request.Headers["Accept-Encoding"] ?? string.Empty;
+
+                return enc.IndexOf("deflate", StringComparison.OrdinalIgnoreCase) != -1 || enc.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) != -1;
+            }
+        }
+
+        private string CompressionMethod
+        {
+            get
+            {
+                string enc = RequestContext.Request.Headers["Accept-Encoding"] ?? string.Empty;
+
+                if (enc.IndexOf("deflate", StringComparison.OrdinalIgnoreCase) != -1)
+                {
+                    return "deflate";
+                }
+                if (enc.IndexOf("gzip", StringComparison.OrdinalIgnoreCase) != -1)
+                {
+                    return "gzip";
+                }
+
+                return null;
+            }
+        }
+
+        protected virtual void PrepareResponseBeforeWriteOutput(HttpListenerResponse response)
+        {
+            // Don't force this to true. HttpListener will default it to true if supported by the client.
+            if (!UseChunkedEncoding)
+            {
+                response.SendChunked = false;
+            }
+
+            if (ContentLength.HasValue)
+            {
+                response.ContentLength64 = ContentLength.Value;
+            }
+
+            if (CompressResponse && ClientSupportsCompression)
+            {
+                response.AddHeader("Content-Encoding", CompressionMethod);
+            }
+
+            TimeSpan cacheDuration = CacheDuration;
+            
+            if (cacheDuration.Ticks > 0)
+            {
+                CacheResponse(response, cacheDuration, LastDateModified);
+            }
+        }
+
+        private void CacheResponse(HttpListenerResponse response, TimeSpan duration, DateTime? dateModified)
+        {
+            DateTime lastModified = dateModified ?? DateTime.Now;
+
+            response.Headers[HttpResponseHeader.CacheControl] = "public, max-age=" + Convert.ToInt32(duration.TotalSeconds);
+            response.Headers[HttpResponseHeader.Expires] = DateTime.Now.Add(duration).ToString("r");
+            response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
+        }
+
         private void WriteReponse(Stream stream)
         private void WriteReponse(Stream stream)
         {
         {
-            if (CompressResponse)
+            PrepareResponseBeforeWriteOutput(RequestContext.Response);
+
+            if (CompressResponse && ClientSupportsCompression)
             {
             {
-                CompressedStream = new DeflateStream(stream, CompressionLevel.Fastest, false);
+                if (CompressionMethod.Equals("deflate", StringComparison.OrdinalIgnoreCase))
+                {
+                    CompressedStream = new DeflateStream(stream, CompressionLevel.Fastest, false);
+                }
+                else
+                {
+                    CompressedStream = new GZipStream(stream, CompressionLevel.Fastest, false);
+                }
 
 
                 WriteResponseToOutputStream(CompressedStream);
                 WriteResponseToOutputStream(CompressedStream);
             }
             }

+ 1 - 30
MediaBrowser.Common/Net/RequestContext.cs

@@ -1,8 +1,8 @@
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
-using MediaBrowser.Common.Net.Handlers;
 using MediaBrowser.Common.Logging;
 using MediaBrowser.Common.Logging;
+using MediaBrowser.Common.Net.Handlers;
 
 
 namespace MediaBrowser.Common.Net
 namespace MediaBrowser.Common.Net
 {
 {
@@ -62,26 +62,6 @@ namespace MediaBrowser.Common.Net
 
 
             if (statusCode == 200 || statusCode == 206)
             if (statusCode == 200 || statusCode == 206)
             {
             {
-                // Don't force this to true. HttpListener will default it to true if supported by the client.
-                if (!handler.UseChunkedEncoding)
-                {
-                    Response.SendChunked = false;
-                }
-
-                if (handler.ContentLength.HasValue)
-                {
-                    Response.ContentLength64 = handler.ContentLength.Value;
-                }
-
-                if (handler.CompressResponse)
-                {
-                    Response.AddHeader("Content-Encoding", "deflate");
-                }
-
-                if (cacheDuration.Ticks > 0)
-                {
-                    CacheResponse(Response, cacheDuration, handler.LastDateModified);
-                }
                 handler.WriteStream(Response.OutputStream);
                 handler.WriteStream(Response.OutputStream);
             }
             }
             else
             else
@@ -91,15 +71,6 @@ namespace MediaBrowser.Common.Net
             }
             }
         }
         }
 
 
-        private void CacheResponse(HttpListenerResponse response, TimeSpan duration, DateTime? dateModified)
-        {
-            DateTime lastModified = dateModified ?? DateTime.Now;
-
-            response.Headers[HttpResponseHeader.CacheControl] = "public, max-age=" + Convert.ToInt32(duration.TotalSeconds);
-            response.Headers[HttpResponseHeader.Expires] = DateTime.Now.Add(duration).ToString("r");
-            response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
-        }
-
         private bool IsCacheValid(DateTime ifModifiedSince, TimeSpan cacheDuration, DateTime? dateModified)
         private bool IsCacheValid(DateTime ifModifiedSince, TimeSpan cacheDuration, DateTime? dateModified)
         {
         {
             if (dateModified.HasValue)
             if (dateModified.HasValue)