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.cs47
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpResultFactory.cs71
-rw-r--r--Emby.Server.Implementations/HttpServer/IHttpListener.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs4
4 files changed, 68 insertions, 56 deletions
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 0e1f5a551..322cdf4f0 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -91,16 +91,12 @@ namespace Emby.Server.Implementations.HttpServer
readonly Dictionary<Type, int> _mapExceptionToStatusCode = new Dictionary<Type, int>
{
- {typeof (InvalidOperationException), 500},
- {typeof (NotImplementedException), 500},
{typeof (ResourceNotFoundException), 404},
{typeof (FileNotFoundException), 404},
//{typeof (DirectoryNotFoundException), 404},
{typeof (SecurityException), 401},
{typeof (PaymentRequiredException), 402},
- {typeof (UnauthorizedAccessException), 500},
- {typeof (PlatformNotSupportedException), 500},
- {typeof (NotSupportedException), 500}
+ {typeof (ArgumentException), 400}
};
public override void Configure()
@@ -228,11 +224,30 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private void ErrorHandler(Exception ex, IRequest httpReq)
+ private int GetStatusCode(Exception ex)
+ {
+ if (ex is ArgumentException)
+ {
+ return 400;
+ }
+
+ int statusCode;
+ if (!_mapExceptionToStatusCode.TryGetValue(ex.GetType(), out statusCode))
+ {
+ statusCode = 500;
+ }
+
+ return statusCode;
+ }
+
+ private void ErrorHandler(Exception ex, IRequest httpReq, bool logException = true)
{
try
{
- _logger.ErrorException("Error processing request", ex);
+ if (logException)
+ {
+ _logger.ErrorException("Error processing request", ex);
+ }
var httpRes = httpReq.Response;
@@ -241,11 +256,7 @@ namespace Emby.Server.Implementations.HttpServer
return;
}
- int statusCode;
- if (!_mapExceptionToStatusCode.TryGetValue(ex.GetType(), out statusCode))
- {
- statusCode = 500;
- }
+ var statusCode = GetStatusCode(ex);
httpRes.StatusCode = statusCode;
httpRes.ContentType = "text/html";
@@ -264,7 +275,9 @@ namespace Emby.Server.Implementations.HttpServer
{
if (_listener != null)
{
+ _logger.Info("Stopping HttpListener...");
_listener.Stop();
+ _logger.Info("HttpListener stopped");
}
}
@@ -529,6 +542,10 @@ namespace Emby.Server.Implementations.HttpServer
ErrorHandler(new FileNotFoundException(), httpReq);
}
}
+ catch (OperationCanceledException ex)
+ {
+ ErrorHandler(ex, httpReq, false);
+ }
catch (Exception ex)
{
ErrorHandler(ex, httpReq);
@@ -698,19 +715,19 @@ namespace Emby.Server.Implementations.HttpServer
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
+
base.Dispose();
lock (_disposeLock)
{
if (_disposed) return;
+ _disposed = true;
+
if (disposing)
{
Stop();
}
-
- //release unmanaged resources here...
- _disposed = true;
}
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
index 995dc7b7b..e78446bc8 100644
--- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -203,20 +203,12 @@ 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))
- {
- ContentTypes.Instance.SerializeToStream(request, dto, compressionStream);
- compressionStream.Dispose();
-
- var compressedBytes = ms.ToArray();
+ ContentTypes.Instance.SerializeToStream(request, dto, ms);
+ ms.Position = 0;
- var httpResult = new StreamWriter(compressedBytes, request.ResponseContentType, _logger);
+ var responseHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- //httpResult.Headers["Content-Length"] = compressedBytes.Length.ToString(UsCulture);
- httpResult.Headers["Content-Encoding"] = compressionType;
-
- return httpResult;
- }
+ return GetCompressedResult(ms, compressionType, responseHeaders, false, request.ResponseContentType).Result;
}
}
@@ -591,45 +583,53 @@ namespace Emby.Server.Implementations.HttpServer
};
}
- string content;
-
using (var stream = await factoryFn().ConfigureAwait(false))
{
- using (var reader = new StreamReader(stream))
+ return await GetCompressedResult(stream, requestedCompressionType, responseHeaders, isHeadRequest, contentType).ConfigureAwait(false);
+ }
+ }
+
+ private async Task<IHasHeaders> GetCompressedResult(Stream stream,
+ string requestedCompressionType,
+ IDictionary<string,string> responseHeaders,
+ bool isHeadRequest,
+ string contentType)
+ {
+ using (var reader = new MemoryStream())
+ {
+ await stream.CopyToAsync(reader).ConfigureAwait(false);
+
+ reader.Position = 0;
+ var content = reader.ToArray();
+
+ if (content.Length >= 1024)
{
- content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ content = Compress(content, requestedCompressionType);
+ responseHeaders["Content-Encoding"] = requestedCompressionType;
}
- }
- var contents = Compress(content, requestedCompressionType);
+ responseHeaders["Content-Length"] = content.Length.ToString(UsCulture);
- responseHeaders["Content-Length"] = contents.Length.ToString(UsCulture);
- responseHeaders["Content-Encoding"] = requestedCompressionType;
+ if (isHeadRequest)
+ {
+ return GetHttpResult(new byte[] { }, contentType, true);
+ }
- if (isHeadRequest)
- {
- return GetHttpResult(new byte[] { }, contentType, true);
+ return GetHttpResult(content, contentType, true, responseHeaders);
}
-
- return GetHttpResult(contents, contentType, true, responseHeaders);
}
- private byte[] Compress(string text, string compressionType)
+ private byte[] Compress(byte[] bytes, string compressionType)
{
if (compressionType == "deflate")
- return Deflate(text);
+ return Deflate(bytes);
if (compressionType == "gzip")
- return GZip(text);
+ return GZip(bytes);
throw new NotSupportedException(compressionType);
}
- private byte[] Deflate(string text)
- {
- return Deflate(Encoding.UTF8.GetBytes(text));
- }
-
private byte[] Deflate(byte[] bytes)
{
// In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream
@@ -644,11 +644,6 @@ namespace Emby.Server.Implementations.HttpServer
}
}
- private byte[] GZip(string text)
- {
- return GZip(Encoding.UTF8.GetBytes(text));
- }
-
private byte[] GZip(byte[] buffer)
{
using (var ms = new MemoryStream())
diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
index 9f96a8e49..18df5682d 100644
--- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/IHttpListener.cs
@@ -12,7 +12,7 @@ namespace Emby.Server.Implementations.HttpServer
/// Gets or sets the error handler.
/// </summary>
/// <value>The error handler.</value>
- Action<Exception, IRequest> ErrorHandler { get; set; }
+ Action<Exception, IRequest, bool> ErrorHandler { get; set; }
/// <summary>
/// Gets or sets the request handler.
diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
index 4606d0e31..652fc4f83 100644
--- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
+++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
@@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
_httpRequestFactory = httpRequestFactory;
}
- public Action<Exception, IRequest> ErrorHandler { get; set; }
+ public Action<Exception, IRequest, bool> ErrorHandler { get; set; }
public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
public Action<WebSocketConnectingEventArgs> WebSocketConnecting { get; set; }
@@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.HttpServer.SocketSharp
_logger.ErrorException("Error processing request", ex);
httpReq = httpReq ?? GetRequest(context);
- ErrorHandler(ex, httpReq);
+ ErrorHandler(ex, httpReq, true);
return Task.FromResult(true);
}