aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-07-15 13:13:55 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-07-15 13:13:55 -0400
commit2e91d69d20e49f971d9890674d3016351ee87ccd (patch)
tree5ce0f330f639434127ada9ccae290bbf5cf400ba /MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs
parent61aa25c3585d5f7acf1b88ddaf30a8b04e0c466e (diff)
update async stream writing
Diffstat (limited to 'MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs')
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs285
1 files changed, 0 insertions, 285 deletions
diff --git a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs b/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs
deleted file mode 100644
index 31c0e87b3..000000000
--- a/MediaBrowser.Server.Implementations/HttpServer/NetListener/HttpListenerServer.cs
+++ /dev/null
@@ -1,285 +0,0 @@
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Logging;
-using ServiceStack;
-using ServiceStack.Host.HttpListener;
-using ServiceStack.Web;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Implementations.HttpServer.NetListener
-{
- public class HttpListenerServer : IHttpListener
- {
- private readonly ILogger _logger;
- private HttpListener _listener;
- private readonly ManualResetEventSlim _listenForNextRequest = new ManualResetEventSlim(false);
-
- public Action<Exception, IRequest> ErrorHandler { get; set; }
- public Action<WebSocketConnectEventArgs> WebSocketHandler { get; set; }
- public Func<IHttpRequest, Uri, Task> RequestHandler { get; set; }
-
- private readonly Action<string> _endpointListener;
-
- public HttpListenerServer(ILogger logger, Action<string> endpointListener)
- {
- _logger = logger;
- _endpointListener = endpointListener;
- }
-
- private List<string> UrlPrefixes { get; set; }
-
- public void Start(IEnumerable<string> urlPrefixes)
- {
- UrlPrefixes = urlPrefixes.ToList();
-
- if (_listener == null)
- _listener = new HttpListener();
-
- //HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First());
-
- foreach (var prefix in UrlPrefixes)
- {
- _logger.Info("Adding HttpListener prefix " + prefix);
- _listener.Prefixes.Add(prefix);
- }
-
- _listener.Start();
-
- Task.Factory.StartNew(Listen, TaskCreationOptions.LongRunning);
- }
-
- private bool IsListening
- {
- get { return _listener != null && _listener.IsListening; }
- }
-
- // Loop here to begin processing of new requests.
- private void Listen()
- {
- while (IsListening)
- {
- if (_listener == null) return;
- _listenForNextRequest.Reset();
-
- try
- {
- _listener.BeginGetContext(ListenerCallback, _listener);
- _listenForNextRequest.Wait();
- }
- catch (Exception ex)
- {
- _logger.Error("Listen()", ex);
- return;
- }
- if (_listener == null) return;
- }
- }
-
- // Handle the processing of a request in here.
- private void ListenerCallback(IAsyncResult asyncResult)
- {
- _listenForNextRequest.Set();
-
- var listener = asyncResult.AsyncState as HttpListener;
- HttpListenerContext context;
-
- if (listener == null) return;
- var isListening = listener.IsListening;
-
- try
- {
- if (!isListening)
- {
- _logger.Debug("Ignoring ListenerCallback() as HttpListener is no longer listening"); return;
- }
- // The EndGetContext() method, as with all Begin/End asynchronous methods in the .NET Framework,
- // blocks until there is a request to be processed or some type of data is available.
- context = listener.EndGetContext(asyncResult);
- }
- catch (Exception ex)
- {
- // You will get an exception when httpListener.Stop() is called
- // because there will be a thread stopped waiting on the .EndGetContext()
- // method, and again, that is just the way most Begin/End asynchronous
- // methods of the .NET Framework work.
- var errMsg = ex + ": " + IsListening;
- _logger.Warn(errMsg);
- return;
- }
-
- Task.Factory.StartNew(() => InitTask(context));
- }
-
- private void InitTask(HttpListenerContext context)
- {
- try
- {
- var task = this.ProcessRequestAsync(context);
- task.ContinueWith(x => HandleError(x.Exception, context), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
-
- if (task.Status == TaskStatus.Created)
- {
- task.RunSynchronously();
- }
- }
- catch (Exception ex)
- {
- HandleError(ex, context);
- }
- }
-
- private Task ProcessRequestAsync(HttpListenerContext context)
- {
- var request = context.Request;
-
- LogHttpRequest(request);
-
- if (request.IsWebSocketRequest)
- {
- return ProcessWebSocketRequest(context);
- }
-
- if (string.IsNullOrEmpty(context.Request.RawUrl))
- return ((object)null).AsTaskResult();
-
- var operationName = context.Request.GetOperationName();
-
- var httpReq = GetRequest(context, operationName);
-
- return RequestHandler(httpReq, request.Url);
- }
-
- /// <summary>
- /// Processes the web socket request.
- /// </summary>
- /// <param name="ctx">The CTX.</param>
- /// <returns>Task.</returns>
- private async Task ProcessWebSocketRequest(HttpListenerContext ctx)
- {
-#if !__MonoCS__
- try
- {
- var webSocketContext = await ctx.AcceptWebSocketAsync(null).ConfigureAwait(false);
-
- if (WebSocketHandler != null)
- {
- WebSocketHandler(new WebSocketConnectEventArgs
- {
- WebSocket = new NativeWebSocket(webSocketContext.WebSocket, _logger),
- Endpoint = ctx.Request.RemoteEndPoint.ToString()
- });
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("AcceptWebSocketAsync error", ex);
- ctx.Response.StatusCode = 500;
- ctx.Response.Close();
- }
-#endif
- }
-
- private void HandleError(Exception ex, HttpListenerContext context)
- {
- var operationName = context.Request.GetOperationName();
- var httpReq = GetRequest(context, operationName);
-
- if (ErrorHandler != null)
- {
- ErrorHandler(ex, httpReq);
- }
- }
-
- private static ListenerRequest GetRequest(HttpListenerContext httpContext, string operationName)
- {
- var req = new ListenerRequest(httpContext, operationName, RequestAttributes.None);
- req.RequestAttributes = req.GetAttributes();
-
- return req;
- }
-
- /// <summary>
- /// Logs the HTTP request.
- /// </summary>
- /// <param name="request">The request.</param>
- private void LogHttpRequest(HttpListenerRequest request)
- {
- var endpoint = request.LocalEndPoint;
-
- if (endpoint != null)
- {
- var address = endpoint.ToString();
-
- _endpointListener(address);
- }
-
- LogRequest(_logger, request);
- }
-
- /// <summary>
- /// Logs the request.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="request">The request.</param>
- private static void LogRequest(ILogger logger, HttpListenerRequest request)
- {
- var log = new StringBuilder();
-
- var logHeaders = true;
-
- if (logHeaders)
- {
- var headers = string.Join(",", request.Headers.AllKeys.Where(i => !string.Equals(i, "cookie", StringComparison.OrdinalIgnoreCase) && !string.Equals(i, "Referer", StringComparison.OrdinalIgnoreCase)).Select(k => k + "=" + request.Headers[k]));
-
- log.AppendLine("Ip: " + request.RemoteEndPoint + ". Headers: " + headers);
- }
-
- var type = request.IsWebSocketRequest ? "Web Socket" : "HTTP " + request.HttpMethod;
-
- logger.LogMultiline(type + " " + request.Url, LogSeverity.Debug, log);
- }
-
- public void Stop()
- {
- if (_listener != null)
- {
- foreach (var prefix in UrlPrefixes)
- {
- _listener.Prefixes.Remove(prefix);
- }
-
- _listener.Close();
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- private bool _disposed;
- private readonly object _disposeLock = new object();
- protected virtual void Dispose(bool disposing)
- {
- if (_disposed) return;
-
- lock (_disposeLock)
- {
- if (_disposed) return;
-
- if (disposing)
- {
- Stop();
- }
-
- //release unmanaged resources here...
- _disposed = true;
- }
- }
- }
-} \ No newline at end of file