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();
            }
        }
Example #2
0
        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
            {
                if (ListenerSsl)
                {
                    ListenerPrefix = "https://" + ListenerIp + ":" + ListenerPort + "/";
                }
                else
                {
                    ListenerPrefix = "http://" + ListenerIp + ":" + ListenerPort + "/";
                }
                Http.Prefixes.Add(ListenerPrefix);
                Http.Start();

                while (Http.IsListening)
                {
                    ThreadPool.QueueUserWorkItem((c) =>
                    {
                        if (token.IsCancellationRequested)
                        {
                            throw new OperationCanceledException();
                        }

                        var context = c as HttpListenerContext;

                        try
                        {
                            #region Populate-Http-Request-Object

                            HttpRequest currRequest = new HttpRequest(context);
                            if (currRequest == null)
                            {
                                Logging.Log("Unable to populate HTTP request object on thread ID " + Thread.CurrentThread.ManagedThreadId + ", returning 400");
                                SendResponse(
                                    context,
                                    currRequest,
                                    BuildErrorResponse(500, "Unable to parse your request.", null),
                                    WatsonCommon.AddToDict("content-type", "application/json", null),
                                    400);
                                return;
                            }

                            Logging.Log("Thread " + currRequest.ThreadId + " " + currRequest.SourceIp + ":" + currRequest.SourcePort + " " + currRequest.Method + " " + currRequest.RawUrlWithoutQuery);

                            #endregion

                            #region Process-OPTIONS-Request

                            if (currRequest.Method.ToLower().Trim().Contains("option") &&
                                OptionsRoute != null)
                            {
                                Logging.Log("Thread " + Thread.CurrentThread.ManagedThreadId + " OPTIONS request received");
                                OptionsProcessor(context, currRequest);
                                return;
                            }

                            #endregion

                            #region Send-to-Handler

                            if (DebugRestRequests)
                            {
                                Logging.Log(currRequest.ToString());
                            }

                            Task.Run(() =>
                            {
                                HttpResponse currResponse = null;
                                Func <HttpRequest, HttpResponse> handler = null;

                                #region Find-Route

                                if (currRequest.Method.ToLower().Equals("get") || currRequest.Method.ToLower().Equals("head"))
                                {
                                    if (ContentRoutes.Exists(currRequest.RawUrlWithoutQuery))
                                    {
                                        // content route found
                                        currResponse = ContentProcessor.Process(currRequest);
                                    }
                                }

                                if (currResponse == null)
                                {
                                    handler = StaticRoutes.Match(currRequest.Method, currRequest.RawUrlWithoutQuery);
                                    if (handler != null)
                                    {
                                        // static route found
                                        currResponse = handler(currRequest);
                                    }
                                    else
                                    {
                                        // no static route, check for dynamic route
                                        handler = DynamicRoutes.Match(currRequest.Method, currRequest.RawUrlWithoutQuery);
                                        if (handler != null)
                                        {
                                            // dynamic route found
                                            currResponse = handler(currRequest);
                                        }
                                        else
                                        {
                                            // process using default route
                                            currResponse = DefaultRouteProcessor(context, currRequest);
                                        }
                                    }
                                }

                                #endregion

                                #region Return

                                if (currResponse == null)
                                {
                                    Logging.Log("Null response from handler for " + currRequest.SourceIp + ":" + currRequest.SourcePort + " " + currRequest.Method + " " + currRequest.RawUrlWithoutQuery);
                                    SendResponse(
                                        context,
                                        currRequest,
                                        BuildErrorResponse(500, "Unable to generate response", null),
                                        WatsonCommon.AddToDict("content-type", "application/json", null),
                                        500);
                                    return;
                                }
                                else
                                {
                                    if (DebugRestResponses)
                                    {
                                        Logging.Log(currResponse.ToString());
                                    }

                                    Dictionary <string, string> headers = new Dictionary <string, string>();
                                    if (!String.IsNullOrEmpty(currResponse.ContentType))
                                    {
                                        headers.Add("content-type", currResponse.ContentType);
                                    }

                                    if (currResponse.Headers != null && currResponse.Headers.Count > 0)
                                    {
                                        foreach (KeyValuePair <string, string> curr in currResponse.Headers)
                                        {
                                            headers = WatsonCommon.AddToDict(curr.Key, curr.Value, headers);
                                        }
                                    }

                                    if (currResponse.RawResponse)
                                    {
                                        SendResponse(
                                            context,
                                            currRequest,
                                            currResponse.Data,
                                            headers,
                                            currResponse.StatusCode);
                                        return;
                                    }
                                    else
                                    {
                                        SendResponse(
                                            context,
                                            currRequest,
                                            currResponse.ToJsonBytes(),
                                            headers,
                                            currResponse.StatusCode);
                                        return;
                                    }
                                }

                                #endregion
                            });

                            #endregion
                        }
                        catch (Exception)
                        {
                        }
                        finally
                        {
                        }
                    }, Http.GetContext());
                }
            }
            catch (Exception eOuter)
            {
                Logging.LogException("AcceptConnections", eOuter);
                throw;
            }
            finally
            {
                Logging.Log("Exiting");
            }
        }
Example #4
0
        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
            {
                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
            {
            }
        }