limit access to response stream

This commit is contained in:
Luke Pulverenti 2016-11-12 02:14:04 -05:00
parent c035f2baa1
commit a855864207
5 changed files with 32 additions and 56 deletions

View File

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.HttpServer.SocketSharp;
@ -248,9 +249,7 @@ namespace Emby.Server.Implementations.HttpServer
httpRes.StatusCode = statusCode;
httpRes.ContentType = "text/html";
httpRes.Write(ex.Message);
httpRes.Close();
Write(httpRes, ex.Message);
}
catch
{
@ -404,7 +403,7 @@ namespace Emby.Server.Implementations.HttpServer
{
httpRes.StatusCode = 400;
httpRes.ContentType = "text/plain";
httpRes.Write("Invalid host");
Write(httpRes, "Invalid host");
return;
}
@ -458,7 +457,7 @@ namespace Emby.Server.Implementations.HttpServer
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=\"" +
newUrl + "\">" + newUrl + "</a></body></html>");
return;
@ -475,7 +474,7 @@ namespace Emby.Server.Implementations.HttpServer
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=\"" +
newUrl + "\">" + newUrl + "</a></body></html>");
return;
@ -513,7 +512,7 @@ namespace Emby.Server.Implementations.HttpServer
{
httpRes.StatusCode = 503;
httpRes.ContentType = "text/html";
httpRes.Write(GlobalResponse);
Write(httpRes, GlobalResponse);
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)
{
httpRes.StatusCode = 302;

View File

@ -77,16 +77,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
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()
{
if (!this.IsClosed)
@ -108,8 +98,10 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
{
try
{
response.OutputStream.Flush();
response.OutputStream.Dispose();
var outputStream = response.OutputStream;
outputStream.Flush();
outputStream.Dispose();
response.Close();
}
catch (Exception ex)
@ -118,11 +110,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
}
}
public void Flush()
{
_response.OutputStream.Flush();
}
public bool IsClosed
{
get;

View File

@ -136,23 +136,12 @@ namespace MediaBrowser.Model.Services
Stream OutputStream { get; }
/// <summary>
/// Write once to the Response Stream then close it.
/// </summary>
/// <param name="text"></param>
void Write(string text);
/// <summary>
/// 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.
/// </summary>
void Close();
/// <summary>
/// Response.Flush() and OutputStream.Flush() seem to have different behaviour in ASP.NET
/// </summary>
void Flush();
/// <summary>
/// Gets a value indicating whether this instance is closed.
/// </summary>
@ -160,8 +149,6 @@ namespace MediaBrowser.Model.Services
void SetContentLength(long contentLength);
bool KeepAlive { get; set; }
//Add Metadata to Response
Dictionary<string, object> Items { get; }
}

View File

@ -18,15 +18,7 @@ namespace ServiceStack.Host
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))
{

View File

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