aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/HttpServer')
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs17
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs91
-rw-r--r--Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs7
-rw-r--r--Emby.Server.Implementations/HttpServer/StreamWriter.cs12
4 files changed, 54 insertions, 73 deletions
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 64f498b12..49c664eec 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -86,9 +86,7 @@ namespace Emby.Server.Implementations.HttpServer
public string GlobalResponse { get; set; }
- public override void Configure()
- {
- var mapExceptionToStatusCode = new Dictionary<Type, int>
+ readonly Dictionary<Type, int> _mapExceptionToStatusCode = new Dictionary<Type, int>
{
{typeof (InvalidOperationException), 500},
{typeof (NotImplementedException), 500},
@@ -102,6 +100,8 @@ namespace Emby.Server.Implementations.HttpServer
{typeof (NotSupportedException), 500}
};
+ public override void Configure()
+ {
var requestFilters = _appHost.GetExports<IRequestFilter>().ToList();
foreach (var filter in requestFilters)
{
@@ -240,7 +240,12 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- httpRes.StatusCode = 500;
+ int statusCode;
+ if (!_mapExceptionToStatusCode.TryGetValue(ex.GetType(), out statusCode))
+ {
+ statusCode = 500;
+ }
+ httpRes.StatusCode = statusCode;
httpRes.ContentType = "text/html";
httpRes.Write(ex.Message);
@@ -518,6 +523,10 @@ namespace Emby.Server.Implementations.HttpServer
{
await handler.ProcessRequestAsync(httpReq, httpRes, operationName).ConfigureAwait(false);
}
+ else
+ {
+ ErrorHandler(new FileNotFoundException(), httpReq);
+ }
}
catch (Exception ex)
{
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index bbd556661..f65331ec7 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -34,19 +34,16 @@ namespace Emby.Server.Implementations.HttpServer
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IJsonSerializer _jsonSerializer;
- private readonly IXmlSerializer _xmlSerializer;
+ private readonly IMemoryStreamFactory _memoryStreamFactory;
/// <summary>
/// Initializes a new instance of the <see cref="HttpResultFactory" /> class.
/// </summary>
- /// <param name="logManager">The log manager.</param>
- /// <param name="fileSystem">The file system.</param>
- /// <param name="jsonSerializer">The json serializer.</param>
- public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer)
+ public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer, IMemoryStreamFactory memoryStreamFactory)
{
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
- _xmlSerializer = xmlSerializer;
+ _memoryStreamFactory = memoryStreamFactory;
_logger = logManager.GetLogger("HttpResultFactory");
}
@@ -59,17 +56,13 @@ namespace Emby.Server.Implementations.HttpServer
/// <returns>System.Object.</returns>
public object GetResult(object content, string contentType, IDictionary<string, string> responseHeaders = null)
{
- return GetHttpResult(content, contentType, responseHeaders);
+ return GetHttpResult(content, contentType, true, responseHeaders);
}
/// <summary>
/// Gets the HTTP result.
/// </summary>
- /// <param name="content">The content.</param>
- /// <param name="contentType">Type of the content.</param>
- /// <param name="responseHeaders">The response headers.</param>
- /// <returns>IHasHeaders.</returns>
- private IHasHeaders GetHttpResult(object content, string contentType, IDictionary<string, string> responseHeaders = null)
+ private IHasHeaders GetHttpResult(object content, string contentType, bool addCachePrevention, IDictionary<string, string> responseHeaders = null)
{
IHasHeaders result;
@@ -98,7 +91,7 @@ namespace Emby.Server.Implementations.HttpServer
}
else
{
- result = new HttpResult(content, contentType);
+ result = new HttpResult(content, contentType, HttpStatusCode.OK);
}
}
}
@@ -107,7 +100,11 @@ namespace Emby.Server.Implementations.HttpServer
responseHeaders = new Dictionary<string, string>();
}
- responseHeaders["Expires"] = "-1";
+ if (addCachePrevention)
+ {
+ responseHeaders["Expires"] = "-1";
+ }
+
AddResponseHeaders(result, responseHeaders);
return result;
@@ -184,8 +181,6 @@ namespace Emby.Server.Implementations.HttpServer
/// <returns></returns>
public object ToOptimizedResult<T>(IRequest request, T dto)
{
- request.Response.Dto = dto;
-
var compressionType = GetCompressionType(request);
if (compressionType == null)
{
@@ -204,6 +199,7 @@ 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))
@@ -213,12 +209,9 @@ namespace Emby.Server.Implementations.HttpServer
var compressedBytes = ms.ToArray();
- var httpResult = new HttpResult(compressedBytes, request.ResponseContentType)
- {
- Status = request.Response.StatusCode
- };
+ var httpResult = new StreamWriter(compressedBytes, request.ResponseContentType, _logger);
- httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture);
+ //httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture);
httpResult.Headers["Content-Encoding"] = compressionType;
return httpResult;
@@ -226,6 +219,16 @@ namespace Emby.Server.Implementations.HttpServer
}
}
+ private static Stream GetCompressionStream(Stream outputStream, string compressionType)
+ {
+ if (compressionType == "deflate")
+ return new DeflateStream(outputStream, CompressionMode.Compress, true);
+ if (compressionType == "gzip")
+ return new GZipStream(outputStream, CompressionMode.Compress, true);
+
+ throw new NotSupportedException(compressionType);
+ }
+
public static string GetRealContentType(string contentType)
{
return contentType == null
@@ -233,7 +236,7 @@ namespace Emby.Server.Implementations.HttpServer
: contentType.Split(';')[0].ToLower().Trim();
}
- public static string SerializeToXmlString(object from)
+ private string SerializeToXmlString(object from)
{
using (var ms = new MemoryStream())
{
@@ -253,16 +256,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private static Stream GetCompressionStream(Stream outputStream, string compressionType)
- {
- if (compressionType == "deflate")
- return new DeflateStream(outputStream, CompressionMode.Compress);
- if (compressionType == "gzip")
- return new GZipStream(outputStream, CompressionMode.Compress);
-
- throw new NotSupportedException(compressionType);
- }
-
/// <summary>
/// Gets the optimized result using cache.
/// </summary>
@@ -358,23 +351,7 @@ namespace Emby.Server.Implementations.HttpServer
return hasHeaders;
}
- IHasHeaders httpResult;
-
- var stream = result as Stream;
-
- if (stream != null)
- {
- httpResult = new StreamWriter(stream, contentType, _logger);
- }
- else
- {
- // Otherwise wrap into an HttpResult
- httpResult = new HttpResult(result, contentType ?? "text/html", HttpStatusCode.NotModified);
- }
-
- AddResponseHeaders(httpResult, responseHeaders);
-
- return httpResult;
+ return GetHttpResult(result, contentType, false, responseHeaders);
}
/// <summary>
@@ -603,7 +580,7 @@ namespace Emby.Server.Implementations.HttpServer
{
stream.Dispose();
- return GetHttpResult(new byte[] { }, contentType);
+ return GetHttpResult(new byte[] { }, contentType, true);
}
return new StreamWriter(stream, contentType, _logger)
@@ -630,13 +607,13 @@ namespace Emby.Server.Implementations.HttpServer
if (isHeadRequest)
{
- return GetHttpResult(new byte[] { }, contentType);
+ return GetHttpResult(new byte[] { }, contentType, true);
}
- return GetHttpResult(contents, contentType, responseHeaders);
+ return GetHttpResult(contents, contentType, true, responseHeaders);
}
- public static byte[] Compress(string text, string compressionType)
+ private byte[] Compress(string text, string compressionType)
{
if (compressionType == "deflate")
return Deflate(text);
@@ -647,12 +624,12 @@ namespace Emby.Server.Implementations.HttpServer
throw new NotSupportedException(compressionType);
}
- public static byte[] Deflate(string text)
+ private byte[] Deflate(string text)
{
return Deflate(Encoding.UTF8.GetBytes(text));
}
- public static byte[] Deflate(byte[] bytes)
+ private byte[] Deflate(byte[] bytes)
{
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
// Which means we must use MemoryStream since you have to use ToArray() on a closed Stream
@@ -666,12 +643,12 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- public static byte[] GZip(string text)
+ private byte[] GZip(string text)
{
return GZip(Encoding.UTF8.GetBytes(text));
}
- public static byte[] GZip(byte[] buffer)
+ private byte[] GZip(byte[] buffer)
{
using (var ms = new MemoryStream())
using (var zipStream = new GZipStream(ms, CompressionMode.Compress))
diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs
index de0b33fe3..9de86e9cc 100644
--- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpResponse.cs
@@ -77,8 +77,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
get { return _response.OutputStream; }
}
- public object Dto { get; set; }
-
public void Write(string text)
{
var bOutput = System.Text.Encoding.UTF8.GetBytes(text);
@@ -120,11 +118,6 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
}
}
- public void End()
- {
- Close();
- }
-
public void Flush()
{
_response.OutputStream.Flush();
diff --git a/Emby.Server.Implementations/HttpServer/StreamWriter.cs b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
index 15488abaa..33378949c 100644
--- a/Emby.Server.Implementations/HttpServer/StreamWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/StreamWriter.cs
@@ -25,6 +25,8 @@ namespace Emby.Server.Implementations.HttpServer
/// <value>The source stream.</value>
private Stream SourceStream { get; set; }
+ private byte[] SourceBytes { get; set; }
+
/// <summary>
/// The _options
/// </summary>
@@ -40,7 +42,6 @@ namespace Emby.Server.Implementations.HttpServer
public Action OnComplete { get; set; }
public Action OnError { get; set; }
- private readonly byte[] _bytes;
/// <summary>
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
@@ -73,14 +74,13 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="contentType">Type of the content.</param>
/// <param name="logger">The logger.</param>
public StreamWriter(byte[] source, string contentType, ILogger logger)
- : this(new MemoryStream(source), contentType, logger)
{
if (string.IsNullOrEmpty(contentType))
{
throw new ArgumentNullException("contentType");
}
- _bytes = source;
+ SourceBytes = source;
Logger = logger;
Headers["Content-Type"] = contentType;
@@ -92,9 +92,11 @@ namespace Emby.Server.Implementations.HttpServer
{
try
{
- if (_bytes != null)
+ var bytes = SourceBytes;
+
+ if (bytes != null)
{
- await responseStream.WriteAsync(_bytes, 0, _bytes.Length);
+ await responseStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
}
else
{