Browse Source

limit access to response stream

Luke Pulverenti 8 years ago
parent
commit
a855864207

+ 15 - 7
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -9,6 +9,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Reflection;
 using System.Reflection;
+using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Emby.Server.Implementations.HttpServer;
 using Emby.Server.Implementations.HttpServer;
 using Emby.Server.Implementations.HttpServer.SocketSharp;
 using Emby.Server.Implementations.HttpServer.SocketSharp;
@@ -248,9 +249,7 @@ namespace Emby.Server.Implementations.HttpServer
                 httpRes.StatusCode = statusCode;
                 httpRes.StatusCode = statusCode;
 
 
                 httpRes.ContentType = "text/html";
                 httpRes.ContentType = "text/html";
-                httpRes.Write(ex.Message);
-
-                httpRes.Close();
+                Write(httpRes, ex.Message);
             }
             }
             catch
             catch
             {
             {
@@ -404,7 +403,7 @@ namespace Emby.Server.Implementations.HttpServer
                 {
                 {
                     httpRes.StatusCode = 400;
                     httpRes.StatusCode = 400;
                     httpRes.ContentType = "text/plain";
                     httpRes.ContentType = "text/plain";
-                    httpRes.Write("Invalid host");
+                    Write(httpRes, "Invalid host");
                     return;
                     return;
                 }
                 }
 
 
@@ -458,7 +457,7 @@ namespace Emby.Server.Implementations.HttpServer
 
 
                     if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
                     if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
                     {
                     {
-                        httpRes.Write(
+                        Write(httpRes,
                             "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" +
                             "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" +
                             newUrl + "\">" + newUrl + "</a></body></html>");
                             newUrl + "\">" + newUrl + "</a></body></html>");
                         return;
                         return;
@@ -475,7 +474,7 @@ namespace Emby.Server.Implementations.HttpServer
 
 
                     if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
                     if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase))
                     {
                     {
-                        httpRes.Write(
+                        Write(httpRes,
                             "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" +
                             "<!doctype html><html><head><title>Emby</title></head><body>Please update your Emby bookmark to <a href=\"" +
                             newUrl + "\">" + newUrl + "</a></body></html>");
                             newUrl + "\">" + newUrl + "</a></body></html>");
                         return;
                         return;
@@ -513,7 +512,7 @@ namespace Emby.Server.Implementations.HttpServer
                 {
                 {
                     httpRes.StatusCode = 503;
                     httpRes.StatusCode = 503;
                     httpRes.ContentType = "text/html";
                     httpRes.ContentType = "text/html";
-                    httpRes.Write(GlobalResponse);
+                    Write(httpRes, GlobalResponse);
                     return;
                     return;
                 }
                 }
 
 
@@ -547,6 +546,15 @@ namespace Emby.Server.Implementations.HttpServer
             }
             }
         }
         }
 
 
+        private void Write(IResponse response, string text)
+        {
+            var bOutput = Encoding.UTF8.GetBytes(text);
+            response.SetContentLength(bOutput.Length);
+
+            var outputStream = response.OutputStream;
+            outputStream.Write(bOutput, 0, bOutput.Length);
+        }
+
         public static void RedirectToUrl(IResponse httpRes, string url)
         public static void RedirectToUrl(IResponse httpRes, string url)
         {
         {
             httpRes.StatusCode = 302;
             httpRes.StatusCode = 302;

+ 4 - 17
Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs

@@ -77,16 +77,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
             get { return _response.OutputStream; }
             get { return _response.OutputStream; }
         }
         }
 
 
-        public void Write(string text)
-        {
-            var bOutput = System.Text.Encoding.UTF8.GetBytes(text);
-            _response.ContentLength64 = bOutput.Length;
-
-            var outputStream = _response.OutputStream;
-            outputStream.Write(bOutput, 0, bOutput.Length);
-            Close();
-        }
-
         public void Close()
         public void Close()
         {
         {
             if (!this.IsClosed)
             if (!this.IsClosed)
@@ -108,8 +98,10 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
         {
         {
             try
             try
             {
             {
-                response.OutputStream.Flush();
-                response.OutputStream.Dispose();
+                var outputStream = response.OutputStream;
+
+                outputStream.Flush();
+                outputStream.Dispose();
                 response.Close();
                 response.Close();
             }
             }
             catch (Exception ex)
             catch (Exception ex)
@@ -118,11 +110,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
             }
             }
         }
         }
 
 
-        public void Flush()
-        {
-            _response.OutputStream.Flush();
-        }
-
         public bool IsClosed
         public bool IsClosed
         {
         {
             get;
             get;

+ 0 - 13
MediaBrowser.Model/Services/IRequest.cs

@@ -136,23 +136,12 @@ namespace MediaBrowser.Model.Services
 
 
         Stream OutputStream { get; }
         Stream OutputStream { get; }
 
 
-        /// <summary>
-        /// Write once to the Response Stream then close it. 
-        /// </summary>
-        /// <param name="text"></param>
-        void Write(string text);
-
         /// <summary>
         /// <summary>
         /// Signal that this response has been handled and no more processing should be done.
         /// Signal that this response has been handled and no more processing should be done.
         /// When used in a request or response filter, no more filters or processing is done on this request.
         /// When used in a request or response filter, no more filters or processing is done on this request.
         /// </summary>
         /// </summary>
         void Close();
         void Close();
 
 
-        /// <summary>
-        /// Response.Flush() and OutputStream.Flush() seem to have different behaviour in ASP.NET
-        /// </summary>
-        void Flush();
-
         /// <summary>
         /// <summary>
         /// Gets a value indicating whether this instance is closed.
         /// Gets a value indicating whether this instance is closed.
         /// </summary>
         /// </summary>
@@ -160,8 +149,6 @@ namespace MediaBrowser.Model.Services
 
 
         void SetContentLength(long contentLength);
         void SetContentLength(long contentLength);
 
 
-        bool KeepAlive { get; set; }
-
         //Add Metadata to Response
         //Add Metadata to Response
         Dictionary<string, object> Items { get; }
         Dictionary<string, object> Items { get; }
     }
     }

+ 1 - 9
ServiceStack/Host/ContentTypes.cs

@@ -18,15 +18,7 @@ namespace ServiceStack.Host
             serializer(response, responseStream);
             serializer(response, responseStream);
         }
         }
 
 
-        public Action<object, IResponse> GetResponseSerializer(string contentType)
-        {
-            var serializer = GetStreamSerializer(contentType);
-            if (serializer == null) return null;
-
-            return (dto, httpRes) => serializer(dto, httpRes.OutputStream);
-        }
-
-        public Action<object, Stream> GetStreamSerializer(string contentType)
+        private Action<object, Stream> GetStreamSerializer(string contentType)
         {
         {
             switch (GetRealContentType(contentType))
             switch (GetRealContentType(contentType))
             {
             {

+ 12 - 10
ServiceStack/HttpResponseExtensionsInternal.cs

@@ -6,6 +6,7 @@ using System.IO;
 using System.Net;
 using System.Net;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Text;
 using System.Threading;
 using System.Threading;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
 using ServiceStack.Host;
 using ServiceStack.Host;
@@ -14,19 +15,19 @@ namespace ServiceStack
 {
 {
     public static class HttpResponseExtensionsInternal
     public static class HttpResponseExtensionsInternal
     {
     {
-        public static async Task<bool> WriteToOutputStream(IResponse response, object result)
+        public static async Task<bool> WriteToOutputStream(IResponse response, Stream outputStream, object result)
         {
         {
             var asyncStreamWriter = result as IAsyncStreamWriter;
             var asyncStreamWriter = result as IAsyncStreamWriter;
             if (asyncStreamWriter != null)
             if (asyncStreamWriter != null)
             {
             {
-                await asyncStreamWriter.WriteToAsync(response.OutputStream, CancellationToken.None).ConfigureAwait(false);
+                await asyncStreamWriter.WriteToAsync(outputStream, CancellationToken.None).ConfigureAwait(false);
                 return true;
                 return true;
             }
             }
 
 
             var streamWriter = result as IStreamWriter;
             var streamWriter = result as IStreamWriter;
             if (streamWriter != null)
             if (streamWriter != null)
             {
             {
-                streamWriter.WriteTo(response.OutputStream);
+                streamWriter.WriteTo(outputStream);
                 return true;
                 return true;
             }
             }
 
 
@@ -35,7 +36,7 @@ namespace ServiceStack
             {
             {
                 using (stream)
                 using (stream)
                 {
                 {
-                    await stream.CopyToAsync(response.OutputStream).ConfigureAwait(false);
+                    await stream.CopyToAsync(outputStream).ConfigureAwait(false);
                     return true;
                     return true;
                 }
                 }
             }
             }
@@ -46,7 +47,7 @@ namespace ServiceStack
                 response.ContentType = "application/octet-stream";
                 response.ContentType = "application/octet-stream";
                 response.SetContentLength(bytes.Length);
                 response.SetContentLength(bytes.Length);
 
 
-                await response.OutputStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+                await outputStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
                 return true;
                 return true;
             }
             }
 
 
@@ -151,10 +152,11 @@ namespace ServiceStack
                 response.ContentType += "; charset=utf-8";
                 response.ContentType += "; charset=utf-8";
             }
             }
 
 
-            var writeToOutputStreamResult = await WriteToOutputStream(response, result).ConfigureAwait(false);
+            var outputStream = response.OutputStream;
+
+            var writeToOutputStreamResult = await WriteToOutputStream(response, outputStream, result).ConfigureAwait(false);
             if (writeToOutputStreamResult)
             if (writeToOutputStreamResult)
             {
             {
-                response.Flush(); //required for Compression
                 return;
                 return;
             }
             }
 
 
@@ -164,12 +166,12 @@ namespace ServiceStack
                 if (response.ContentType == null || response.ContentType == "text/html")
                 if (response.ContentType == null || response.ContentType == "text/html")
                     response.ContentType = defaultContentType;
                     response.ContentType = defaultContentType;
 
 
-                response.Write(responseText);
+                var bytes = Encoding.UTF8.GetBytes(responseText);
+                await outputStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
                 return;
                 return;
             }
             }
 
 
-            var serializer = ContentTypes.Instance.GetResponseSerializer(defaultContentType);
-            serializer(result, response);
+            ContentTypes.Instance.SerializeToStream(request, result, outputStream);
         }
         }
     }
     }
 }
 }