mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 13:57:14 -04:00
limit access to response stream
This commit is contained in:
parent
c035f2baa1
commit
a855864207
@ -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);
|
Write(httpRes, ex.Message);
|
||||||
|
|
||||||
httpRes.Close();
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
@ -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();
|
var outputStream = response.OutputStream;
|
||||||
response.OutputStream.Dispose();
|
|
||||||
|
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;
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,7 @@ namespace ServiceStack.Host
|
|||||||
serializer(response, responseStream);
|
serializer(response, responseStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action<object, IResponse> GetResponseSerializer(string contentType)
|
private Action<object, Stream> GetStreamSerializer(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)
|
|
||||||
{
|
{
|
||||||
switch (GetRealContentType(contentType))
|
switch (GetRealContentType(contentType))
|
||||||
{
|
{
|
||||||
|
@ -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);
|
ContentTypes.Instance.SerializeToStream(request, result, outputStream);
|
||||||
serializer(result, response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user