private async Task AcceptConnections() { try { #region Start-Listeners if (_ListenerHostnames != null) { foreach (string curr in _ListenerHostnames) { string prefix = null; if (_ListenerSsl) { prefix = "https://" + curr + ":" + _ListenerPort + "/"; } else { prefix = "http://" + curr + ":" + _ListenerPort + "/"; } _HttpListener.Prefixes.Add(prefix); } } else if (_ListenerUris != null) { foreach (string curr in _ListenerUris) { _HttpListener.Prefixes.Add(curr); } } _HttpListener.Start(); #endregion #region Listen-and-Process-Requests while (_HttpListener.IsListening && !_TokenSource.IsCancellationRequested) { HttpListenerContext listenerContext = await _HttpListener.GetContextAsync(); HttpContext ctx = null; Task unawaited = Task.Run(async() => { DateTime startTime = DateTime.Now; try { #region Build-Context Events.ConnectionReceived?.Invoke( listenerContext.Request.RemoteEndPoint.Address.ToString(), listenerContext.Request.RemoteEndPoint.Port); ctx = new HttpContext(listenerContext, Events); Events.RequestReceived?.Invoke( ctx.Request.SourceIp, ctx.Request.SourcePort, ctx.Request.Method.ToString(), ctx.Request.FullUrl); _Stats.IncrementRequestCounter(ctx.Request.Method); _Stats.ReceivedPayloadBytes += ctx.Request.ContentLength; #endregion #region Check-Access-Control if (!AccessControl.Permit(ctx.Request.SourceIp)) { Events.AccessControlDenied?.Invoke( ctx.Request.SourceIp, ctx.Request.SourcePort, ctx.Request.Method.ToString(), ctx.Request.FullUrl); listenerContext.Response.Close(); return; } #endregion #region Process-Preflight-Requests if (ctx.Request.Method == HttpMethod.OPTIONS) { if (OptionsRoute != null) { await OptionsRoute(ctx); return; } else { OptionsProcessor(listenerContext, ctx.Request); return; } } #endregion #region Pre-Routing-Handler bool terminate = false; if (PreRoutingHandler != null) { terminate = await PreRoutingHandler(ctx); if (terminate) { return; } } #endregion #region Content-Routes if (ctx.Request.Method == HttpMethod.GET || ctx.Request.Method == HttpMethod.HEAD) { if (ContentRoutes.Exists(ctx.Request.RawUrlWithoutQuery)) { await _ContentRouteProcessor.Process(ctx); return; } } #endregion #region Static-Routes Func <HttpContext, Task> handler = StaticRoutes.Match(ctx.Request.Method, ctx.Request.RawUrlWithoutQuery); if (handler != null) { await handler(ctx); return; } #endregion #region Dynamic-Routes handler = DynamicRoutes.Match(ctx.Request.Method, ctx.Request.RawUrlWithoutQuery); if (handler != null) { await handler(ctx); return; } #endregion #region Default-Route await _DefaultRoute(ctx); return; #endregion } catch (Exception eInner) { if (ctx == null || ctx.Request == null) { Events.ExceptionEncountered?.Invoke(null, 0, eInner); } else { Events.ExceptionEncountered?.Invoke(ctx.Request.SourceIp, ctx.Request.SourcePort, eInner); } } finally { if (ctx != null && ctx.Response != null && ctx.Response.ResponseSent) { Events.ResponseSent?.Invoke( ctx.Request.SourceIp, ctx.Request.SourcePort, ctx.Request.Method.ToString(), ctx.Request.FullUrl, ctx.Response.StatusCode, TotalMsFrom(startTime)); _Stats.SentPayloadBytes += ctx.Response.ContentLength; } } }, _Token); } #endregion } catch (Exception e) { Events.ExceptionEncountered?.Invoke(null, 0, e); } finally { Events.ServerStopped?.Invoke(); } }
private void AcceptConnections(CancellationToken token) { try { foreach (string curr in _ListenerHostnames) { string prefix = null; if (_ListenerSsl) { prefix = "https://" + curr + ":" + _ListenerPort + "/"; } else { prefix = "http://" + curr + ":" + _ListenerPort + "/"; } _HttpListener.Prefixes.Add(prefix); } _HttpListener.Start(); while (_HttpListener.IsListening) { ThreadPool.QueueUserWorkItem((c) => { if (token.IsCancellationRequested) { throw new OperationCanceledException(); } var context = c as HttpListenerContext; HttpRequest req = null; try { Events.ConnectionReceived( context.Request.RemoteEndPoint.Address.ToString(), context.Request.RemoteEndPoint.Port); // Populate HTTP request object req = new HttpRequest(context, ReadInputStream); if (req == null) { HttpResponse resp = new HttpResponse(req, 500, null, "text/plain", "Unable to parse HTTP request"); SendResponse(context, req, resp); return; } else { Events.RequestReceived(req.SourceIp, req.SourcePort, req.Method.ToString(), req.FullUrl); } // Check access control if (!AccessControl.Permit(req.SourceIp)) { Events.AccessControlDenied(req.SourceIp, req.SourcePort, req.Method.ToString(), req.FullUrl); context.Response.Close(); return; } // Process OPTIONS request if (req.Method == HttpMethod.OPTIONS && OptionsRoute != null) { OptionsProcessor(context, req); return; } // Send to handler Task.Run(() => { HttpResponse resp = null; Func <HttpRequest, HttpResponse> handler = null; #region Pre-Routing-Handler if (PreRoutingHandler != null) { resp = PreRoutingHandler(req); } #endregion #region Content-Routes if (req.Method == HttpMethod.GET || req.Method == HttpMethod.HEAD) { if (ContentRoutes.Exists(req.RawUrlWithoutQuery)) { resp = _ContentRouteProcessor.Process(req, ReadInputStream); } } #endregion #region Static-Dynamic-Default-Routes if (resp == null) { handler = StaticRoutes.Match(req.Method, req.RawUrlWithoutQuery); if (handler != null) { resp = handler(req); } else { handler = DynamicRoutes.Match(req.Method, req.RawUrlWithoutQuery); if (handler != null) { resp = handler(req); } else { resp = DefaultRouteProcessor(context, req); } } } #endregion #region Respond if (resp == null) { resp = new HttpResponse(req, 500, null, "text/plain", "Unable to generate repsonse"); SendResponse(context, req, resp); return; } else { Dictionary <string, string> headers = new Dictionary <string, string>(); if (!String.IsNullOrEmpty(resp.ContentType)) { headers.Add("content-type", resp.ContentType); } if (resp.Headers != null && resp.Headers.Count > 0) { foreach (KeyValuePair <string, string> curr in resp.Headers) { headers = Common.AddToDict(curr.Key, curr.Value, headers); } } SendResponse(context, req, resp); return; } #endregion }); } catch (Exception eInner) { if (req == null) { Events.ExceptionEncountered(null, 0, eInner); } else { Events.ExceptionEncountered(req.SourceIp, req.SourcePort, eInner); } } }, _HttpListener.GetContext()); } } catch (HttpListenerException) { Events.ServerStopped(); } catch (OperationCanceledException) { Events.ServerStopped(); } catch (Exception eOuter) { Events.ExceptionEncountered(null, 0, eOuter); } }
private void AcceptConnections(CancellationToken token) { try { #region Start-Listeners foreach (string curr in _ListenerHostnames) { string prefix = null; if (_ListenerSsl) { prefix = "https://" + curr + ":" + _ListenerPort + "/"; } else { prefix = "http://" + curr + ":" + _ListenerPort + "/"; } _HttpListener.Prefixes.Add(prefix); } _HttpListener.Start(); #endregion while (_HttpListener.IsListening) { ThreadPool.QueueUserWorkItem((c) => { if (token.IsCancellationRequested) { throw new OperationCanceledException(); } HttpListenerContext listenerContext = c as HttpListenerContext; HttpContext ctx = null; try { #region Build-Context-and-Send-Notification Events.ConnectionReceived( listenerContext.Request.RemoteEndPoint.Address.ToString(), listenerContext.Request.RemoteEndPoint.Port); ctx = new HttpContext(listenerContext, Events); Events.RequestReceived( ctx.Request.SourceIp, ctx.Request.SourcePort, ctx.Request.Method.ToString(), ctx.Request.FullUrl); #endregion #region Check-Access-Control if (!AccessControl.Permit(ctx.Request.SourceIp)) { Events.AccessControlDenied( ctx.Request.SourceIp, ctx.Request.SourcePort, ctx.Request.Method.ToString(), ctx.Request.FullUrl); listenerContext.Response.Close(); return; } #endregion #region Process-Preflight-Requests if (ctx.Request.Method == HttpMethod.OPTIONS && OptionsRoute != null) { OptionsProcessor(listenerContext, ctx.Request); return; } #endregion #region Process-Via-Routing Task.Run(() => { Func <HttpContext, Task> handler = null; #region Pre-Routing-Handler if (PreRoutingHandler != null) { if (PreRoutingHandler(ctx).Result) { return; } } #endregion #region Content-Routes if (ctx.Request.Method == HttpMethod.GET || ctx.Request.Method == HttpMethod.HEAD) { if (ContentRoutes.Exists(ctx.Request.RawUrlWithoutQuery)) { _ContentRouteProcessor.Process(ctx).RunSynchronously(); return; } } #endregion #region Static-Routes handler = StaticRoutes.Match(ctx.Request.Method, ctx.Request.RawUrlWithoutQuery); if (handler != null) { handler(ctx).RunSynchronously(); return; } #endregion #region Dynamic-Routes handler = DynamicRoutes.Match(ctx.Request.Method, ctx.Request.RawUrlWithoutQuery); if (handler != null) { handler(ctx).RunSynchronously(); return; } #endregion #region Default-Route _DefaultRoute(ctx).RunSynchronously(); return; #endregion }); #endregion } catch (Exception eInner) { if (ctx == null || ctx.Request == null) { Events.ExceptionEncountered(null, 0, eInner); } else { Events.ExceptionEncountered(ctx.Request.SourceIp, ctx.Request.SourcePort, eInner); } } }, _HttpListener.GetContext()); } } catch (HttpListenerException) { Events.ServerStopped(); } catch (OperationCanceledException) { Events.ServerStopped(); } catch (Exception eOuter) { Events.ExceptionEncountered(null, 0, eOuter); } }
private void AcceptConnections(CancellationToken token) { try { foreach (string curr in _ListenerHostnames) { string prefix = null; if (_ListenerSsl) { prefix = "https://" + curr + ":" + _ListenerPort + "/"; } else { prefix = "http://" + curr + ":" + _ListenerPort + "/"; } _HttpListener.Prefixes.Add(prefix); } _HttpListener.Start(); while (_HttpListener.IsListening) { ThreadPool.QueueUserWorkItem((c) => { if (token.IsCancellationRequested) { throw new OperationCanceledException(); } var context = c as HttpListenerContext; try { #region Populate-Http-Request-Object HttpRequest req = new HttpRequest(context, ReadInputStream); if (req == null) { HttpResponse resp = new HttpResponse( req, 500, null, "text/plain", Encoding.UTF8.GetBytes("Unable to parse your HTTP request")); SendResponse( context, req, resp); return; } #endregion #region Access-Control if (!AccessControl.Permit(req.SourceIp)) { context.Response.Close(); return; } #endregion #region Process-OPTIONS-Request if (req.Method == HttpMethod.OPTIONS && OptionsRoute != null) { OptionsProcessor(context, req); return; } #endregion #region Send-to-Handler Task.Run(() => { HttpResponse resp = null; Func <HttpRequest, HttpResponse> handler = null; #region Find-Route if (req.Method == HttpMethod.GET || req.Method == HttpMethod.HEAD) { if (ContentRoutes.Exists(req.RawUrlWithoutQuery)) { // content route found resp = _ContentRouteProcessor.Process(req); } } if (resp == null) { handler = StaticRoutes.Match(req.Method, req.RawUrlWithoutQuery); if (handler != null) { // static route found resp = handler(req); } else { // no static route, check for dynamic route handler = DynamicRoutes.Match(req.Method, req.RawUrlWithoutQuery); if (handler != null) { // dynamic route found resp = handler(req); } else { // process using default route resp = DefaultRouteProcessor(context, req); } } } #endregion #region Return if (resp == null) { resp = new HttpResponse( req, 500, null, "text/plain", Encoding.UTF8.GetBytes("Unable to generate response")); SendResponse( context, req, resp); return; } else { Dictionary <string, string> headers = new Dictionary <string, string>(); if (!String.IsNullOrEmpty(resp.ContentType)) { headers.Add("content-type", resp.ContentType); } if (resp.Headers != null && resp.Headers.Count > 0) { foreach (KeyValuePair <string, string> curr in resp.Headers) { headers = WatsonCommon.AddToDict(curr.Key, curr.Value, headers); } } SendResponse( context, req, resp); return; } #endregion }); #endregion } catch (Exception) { } finally { } }, _HttpListener.GetContext()); } } catch (Exception) { throw; } finally { } }