示例#1
0
        /// <summary>
        /// Creates a JSON string of the response and data including fields indicating success and data MD5.
        /// </summary>
        /// <returns>String containing JSON representation of the HTTP response.</returns>
        public string ToJson()
        {
            Dictionary <string, object> ret = new Dictionary <string, object>();

            ret.Add("success", Success);
            if (Data != null)
            {
                ret.Add("md5", WatsonCommon.CalculateMd5(Data.ToString()));
                ret.Add("data", Data);
            }
            return(WatsonCommon.SerializeJson(ret));
        }
示例#2
0
        /// <summary>
        /// Creates a byte array containing the HTTP response (useful for sockets apps what want to transmit the response directly).
        /// </summary>
        /// <returns></returns>
        public byte[] ToHttpBytes()
        {
            byte[] ret = null;

            string statusLine = ProtocolVersion + " " + StatusCode + " " + StatusDescription + "\r\n";

            ret = AppendBytes(ret, Encoding.UTF8.GetBytes(statusLine));

            if (!String.IsNullOrEmpty(ContentType))
            {
                string contentTypeLine = "Content-Type: " + ContentType + "\r\n";
                ret = AppendBytes(ret, Encoding.UTF8.GetBytes(contentTypeLine));
            }

            if (Headers != null && Headers.Count > 0)
            {
                foreach (KeyValuePair <string, string> currHeader in Headers)
                {
                    if (String.IsNullOrEmpty(currHeader.Key))
                    {
                        continue;
                    }
                    if (currHeader.Key.ToLower().Trim().Equals("content-type"))
                    {
                        continue;
                    }

                    string headerLine = currHeader.Key + ": " + currHeader.Value + "\r\n";
                    ret = AppendBytes(ret, Encoding.UTF8.GetBytes(headerLine));
                }
            }

            ret = AppendBytes(ret, Encoding.UTF8.GetBytes("\r\n"));

            if (Data != null)
            {
                if (Data is byte[])
                {
                    ret = AppendBytes(ret, (byte[])Data);
                }
                else if (Data is string)
                {
                    ret = AppendBytes(ret, Encoding.UTF8.GetBytes((string)Data));
                }
                else
                {
                    ret = AppendBytes(ret, Encoding.UTF8.GetBytes(WatsonCommon.SerializeJson(Data)));
                }
            }

            return(ret);
        }
示例#3
0
        /// <summary>
        /// Retrieve a string-formatted, human-readable copy of the HttpResponse instance.
        /// </summary>
        /// <returns>String-formatted, human-readable copy of the HttpResponse instance.</returns>
        public override string ToString()
        {
            string ret = "";

            ret += "--- HTTP Response ---" + Environment.NewLine;
            ret += TimestampUtc.ToString("MM/dd/yyyy HH:mm:ss") + " " + SourceIp + ":" + SourcePort + " to " + DestIp + ":" + DestPort + "  " + Method + " " + RawUrlWithoutQuery + Environment.NewLine;
            ret += "  Success : " + Success + Environment.NewLine;
            ret += "  Content : " + ContentType + " (" + ContentLength + " bytes)" + Environment.NewLine;
            if (Headers != null && Headers.Count > 0)
            {
                ret += "  Headers : " + Environment.NewLine;
                foreach (KeyValuePair <string, string> curr in Headers)
                {
                    ret += "    " + curr.Key + ": " + curr.Value + Environment.NewLine;
                }
            }
            else
            {
                ret += "  Headers : none" + Environment.NewLine;
            }

            if (Data != null)
            {
                ret += "  Data    : " + Environment.NewLine;
                if (Data is byte[])
                {
                    ret += Encoding.UTF8.GetString(((byte[])Data)) + Environment.NewLine;
                }
                else if (Data is string)
                {
                    ret += Data + Environment.NewLine;
                }
                else
                {
                    ret += WatsonCommon.SerializeJson(Data) + Environment.NewLine;
                }
            }
            else
            {
                ret += "  Data    : [null]" + Environment.NewLine;
            }

            return(ret);
        }
        private void SendResponse(
            HttpListenerContext context,
            HttpRequest req,
            object data,
            Dictionary <string, string> headers,
            int status)
        {
            int responseLen = 0;
            HttpListenerResponse response = null;

            try
            {
                #region Set-Variables

                if (data != null)
                {
                    if (data is string)
                    {
                        if (!String.IsNullOrEmpty(data.ToString()))
                        {
                            responseLen = data.ToString().Length;
                        }
                    }
                    else if (data is byte[])
                    {
                        if ((byte[])data != null)
                        {
                            if (((byte[])data).Length > 0)
                            {
                                responseLen = ((byte[])data).Length;
                            }
                        }
                    }
                    else
                    {
                        responseLen = (WatsonCommon.SerializeJson(data)).Length;
                    }
                }

                #endregion

                #region Status-Code-and-Description

                response            = context.Response;
                response.StatusCode = status;

                switch (status)
                {
                case 200:
                    response.StatusDescription = "OK";
                    break;

                case 201:
                    response.StatusDescription = "Created";
                    break;

                case 301:
                    response.StatusDescription = "Moved Permanently";
                    break;

                case 302:
                    response.StatusDescription = "Moved Temporarily";
                    break;

                case 304:
                    response.StatusDescription = "Not Modified";
                    break;

                case 400:
                    response.StatusDescription = "Bad Request";
                    break;

                case 401:
                    response.StatusDescription = "Unauthorized";
                    break;

                case 403:
                    response.StatusDescription = "Forbidden";
                    break;

                case 404:
                    response.StatusDescription = "Not Found";
                    break;

                case 405:
                    response.StatusDescription = "Method Not Allowed";
                    break;

                case 429:
                    response.StatusDescription = "Too Many Requests";
                    break;

                case 500:
                    response.StatusDescription = "Internal Server Error";
                    break;

                case 501:
                    response.StatusDescription = "Not Implemented";
                    break;

                case 503:
                    response.StatusDescription = "Service Unavailable";
                    break;

                default:
                    response.StatusDescription = "Unknown Status";
                    break;
                }

                #endregion

                #region Response-Headers

                response.AddHeader("Access-Control-Allow-Origin", "*");
                response.ContentType = req.ContentType;

                int headerCount = 0;

                if (headers != null)
                {
                    if (headers.Count > 0)
                    {
                        headerCount = headers.Count;
                    }
                }

                if (headerCount > 0)
                {
                    foreach (KeyValuePair <string, string> curr in headers)
                    {
                        response.AddHeader(curr.Key, curr.Value);
                    }
                }

                #endregion

                #region Handle-HEAD-Request

                if (String.Compare(req.Method.ToLower(), "head") == 0)
                {
                    data = null;
                }

                #endregion

                #region Send-Response

                Stream output = response.OutputStream;

                try
                {
                    if (data != null)
                    {
                        #region Response-Body-Attached

                        if (data is string)
                        {
                            #region string

                            if (!String.IsNullOrEmpty(data.ToString()))
                            {
                                if (data.ToString().Length > 0)
                                {
                                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(data.ToString());
                                    response.ContentLength64 = buffer.Length;
                                    output.Write(buffer, 0, buffer.Length);
                                    output.Close();
                                }
                            }

                            #endregion
                        }
                        else if (data is byte[])
                        {
                            #region byte-array

                            response.ContentLength64 = responseLen;
                            output.Write((byte[])data, 0, responseLen);
                            output.Close();

                            #endregion
                        }
                        else
                        {
                            #region other

                            response.ContentLength64 = responseLen;
                            output.Write(Encoding.UTF8.GetBytes(WatsonCommon.SerializeJson(data)), 0, responseLen);
                            output.Close();

                            #endregion
                        }

                        #endregion
                    }
                    else
                    {
                        #region No-Response-Body

                        response.ContentLength64 = 0;
                        output.Flush();
                        output.Close();

                        #endregion
                    }
                }
                catch (HttpListenerException)
                {
                    Logging.Log("Remote endpoint " + req.SourceIp + ":" + req.SourcePort + " appears to have disconnected");
                }
                finally
                {
                    if (response != null)
                    {
                        response.Close();
                    }
                }

                #endregion

                return;
            }
            catch (IOException)
            {
                Logging.Log("Remote endpoint " + req.SourceIp + ":" + req.SourcePort + " appears to have terminated connection prematurely (outer IOException)");
                return;
            }
            catch (HttpListenerException)
            {
                Logging.Log("Remote endpoint " + req.SourceIp + ":" + req.SourcePort + " appears to have terminated connection prematurely (outer HttpListenerException)");
                return;
            }
            catch (Exception e)
            {
                Logging.LogException("SendResponse", e);
                return;
            }
            finally
            {
                if (req != null)
                {
                    if (req.TimestampUtc != null)
                    {
                        Logging.Log("Thread " + req.ThreadId + " sending " + responseLen + "B status " + status + " " + req.SourceIp + ":" + req.SourcePort + " for " + req.Method + " " + req.RawUrlWithoutQuery + " (" + WatsonCommon.TotalMsFrom(req.TimestampUtc) + "ms)");
                    }
                }

                if (response != null)
                {
                    response.Close();
                }
            }
        }
        private byte[] BuildSuccessResponse(
            int status,
            object data)
        {
            Dictionary <string, object> ret = new Dictionary <string, object>();

            ret.Add("data", data);
            ret.Add("success", true);
            ret.Add("http_status", status);

            switch (status)
            {
                // see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

                #region Official

            case 100:
                ret.Add("http_text", "Continue");
                break;

            case 101:
                ret.Add("http_text", "Switching Protocols");
                break;

            case 102:
                ret.Add("http_text", "Processing");
                break;

            case 200:
                ret.Add("http_text", "OK");
                break;

            case 201:
                ret.Add("http_text", "Created");
                break;

            case 202:
                ret.Add("http_text", "Accepted");
                break;

            case 203:
                ret.Add("http_text", "Non-Authoritative Information");
                break;

            case 204:
                ret.Add("http_text", "No Content");
                break;

            case 205:
                ret.Add("http_text", "Reset Content");
                break;

            case 206:
                ret.Add("http_text", "Partial Content");
                break;

            case 207:
                ret.Add("http_text", "Multi-Status");
                break;

            case 208:
                ret.Add("http_text", "Already Reported");
                break;

            case 226:
                ret.Add("http_text", "IM Used");
                break;

            case 300:
                ret.Add("http_text", "Multiple Choices");
                break;

            case 301:
                ret.Add("http_text", "Moved Permanently");
                break;

            case 302:
                ret.Add("http_text", "Moved Temporarily");
                break;

            case 303:
                ret.Add("http_text", "See Other");
                break;

            case 304:
                ret.Add("http_text", "Not Modified");
                break;

            case 305:
                ret.Add("http_text", "Use Proxy");
                break;

            case 306:
                ret.Add("http_text", "Switch Proxy");
                break;

            case 307:
                ret.Add("http_text", "Temporary Redirect");
                break;

            case 308:
                ret.Add("http_text", "Permanent Redirect");
                break;

            case 400:
                ret.Add("http_text", "Bad Request");
                break;

            case 401:
                ret.Add("http_text", "Unauthorized");
                break;

            case 402:
                ret.Add("http_text", "Payment Required");
                break;

            case 403:
                ret.Add("http_text", "Forbidden");
                break;

            case 404:
                ret.Add("http_text", "Not Found");
                break;

            case 405:
                ret.Add("http_text", "Method Not Allowed");
                break;

            case 406:
                ret.Add("http_text", "Not Acceptable");
                break;

            case 407:
                ret.Add("http_text", "Proxy Authentication Required");
                break;

            case 408:
                ret.Add("http_text", "Request Timeout");
                break;

            case 409:
                ret.Add("http_text", "Conflict");
                break;

            case 410:
                ret.Add("http_text", "Gone");
                break;

            case 411:
                ret.Add("http_text", "Length Required");
                break;

            case 412:
                ret.Add("http_text", "Precondition Failed");
                break;

            case 413:
                ret.Add("http_text", "Payload Too Large");
                break;

            case 414:
                ret.Add("http_text", "URI Too Long");
                break;

            case 415:
                ret.Add("http_text", "Unsupported Media Type");
                break;

            case 416:
                ret.Add("http_text", "Range Not Satisfiable");
                break;

            case 417:
                ret.Add("http_text", "Expectation Failed");
                break;

            case 418:
                ret.Add("http_text", "I'm a Teapot :)");
                break;

            case 421:
                ret.Add("http_text", "Misdirected Request");
                break;

            case 422:
                ret.Add("http_text", "Unprocessable Entity");
                break;

            case 423:
                ret.Add("http_text", "Locked");
                break;

            case 424:
                ret.Add("http_text", "Failed Dependency");
                break;

            case 426:
                ret.Add("http_text", "Upgrade Required");
                break;

            case 428:
                ret.Add("http_text", "Precondition Required");
                break;

            case 429:
                ret.Add("http_text", "Too Many Requests");
                break;

            case 431:
                ret.Add("http_text", "Request Header Fields Too Large");
                break;

            case 451:
                ret.Add("http_text", "Unavailable for Legal Reasons");
                break;

            case 500:
                ret.Add("http_text", "Internal Server Error");
                break;

            case 501:
                ret.Add("http_text", "Not Implemented");
                break;

            case 502:
                ret.Add("http_text", "Bad Gateway");
                break;

            case 503:
                ret.Add("http_text", "Service Unavailable");
                break;

            case 504:
                ret.Add("http_text", "Gateway Timeout");
                break;

            case 505:
                ret.Add("http_text", "HTTP Version Not Supported");
                break;

            case 506:
                ret.Add("http_text", "Variant Also Negotiates");
                break;

            case 507:
                ret.Add("http_text", "Insufficient Storage");
                break;

            case 508:
                ret.Add("http_text", "Loop Detected");
                break;

            case 510:
                ret.Add("http_text", "Not Extended");
                break;

            case 511:
                ret.Add("http_text", "Network Authentication Required");
                break;

                #endregion

                #region Unofficial

            case 103:
                ret.Add("http_text", "Checkpoint or Early Hints");
                break;

            case 420:
                ret.Add("http_text", "Method Failure or Enhance Your Calm");
                break;

            case 450:
                ret.Add("http_text", "Blocked By Parental Controls");
                break;

            case 498:
                ret.Add("http_text", "Invalid Token");
                break;

            case 499:
                ret.Add("http_text", "Token Required or Client Closed Request");
                break;

            case 509:
                ret.Add("http_text", "Bandwidth Limit Exceeded");
                break;

            case 530:
                ret.Add("http_text", "Site Is Frozen");
                break;

            case 598:
                ret.Add("http_text", "Network Read Timeout Error");
                break;

            case 599:
                ret.Add("http_text", "Network Connect Timeout Error");
                break;

                #endregion

                #region IIS

            case 440:
                ret.Add("http_text", "Login Timeout");
                break;

            case 449:
                ret.Add("http_text", "Retry With");
                break;

                #endregion

                #region nginx

            case 444:
                ret.Add("http_text", "No Response");
                break;

            case 495:
                ret.Add("http_text", "SSL Certificate Error");
                break;

            case 496:
                ret.Add("http_text", "SSL Certificate Required");
                break;

            case 497:
                ret.Add("http_text", "HTTP Request Sent To HTTPS Port");
                break;

                #endregion

                #region Cloudflare

            case 520:
                ret.Add("http_text", "Unknown Error");
                break;

            case 521:
                ret.Add("http_text", "Web Server Is Down");
                break;

            case 522:
                ret.Add("http_text", "Connection Timed Out");
                break;

            case 523:
                ret.Add("http_text", "Origin Is Unreachable");
                break;

            case 524:
                ret.Add("http_text", "A Timeout Occurred");
                break;

            case 525:
                ret.Add("http_text", "SSL Handshake Failed");
                break;

            case 526:
                ret.Add("http_text", "Invalid SSL Certificate");
                break;

            case 527:
                ret.Add("http_text", "Railgun Error");
                break;

                #endregion

            default:
                ret.Add("http_text", "Unknown Status");
                break;
            }

            string json = WatsonCommon.SerializeJson(ret);
            return(Encoding.UTF8.GetBytes(json));
        }
        private byte[] BuildErrorResponse(
            int status,
            string text,
            byte[] data)
        {
            Dictionary <string, object> ret = new Dictionary <string, object>();

            ret.Add("data", data);
            ret.Add("success", false);
            ret.Add("http_status", status);

            switch (status)
            {
            case 200:
                ret.Add("http_text", "OK");
                break;

            case 201:
                ret.Add("http_text", "Created");
                break;

            case 301:
                ret.Add("http_text", "Moved Permanently");
                break;

            case 302:
                ret.Add("http_text", "Moved Temporarily");
                break;

            case 304:
                ret.Add("http_text", "Not Modified");
                break;

            case 400:
                ret.Add("http_text", "Bad Request");
                break;

            case 401:
                ret.Add("http_text", "Unauthorized");
                break;

            case 403:
                ret.Add("http_text", "Forbidden");
                break;

            case 404:
                ret.Add("http_text", "Not Found");
                break;

            case 405:
                ret.Add("http_text", "Method Not Allowed");
                break;

            case 429:
                ret.Add("http_text", "Too Many Requests");
                break;

            case 500:
                ret.Add("http_text", "Internal Server Error");
                break;

            case 501:
                ret.Add("http_text", "Not Implemented");
                break;

            case 503:
                ret.Add("http_text", "Service Unavailable");
                break;

            default:
                ret.Add("http_text", "Unknown Status");
                break;
            }

            ret.Add("text", text);
            string json = WatsonCommon.SerializeJson(ret);

            return(Encoding.UTF8.GetBytes(json));
        }
        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");
            }
        }
示例#8
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;

                        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
            {
            }
        }
示例#9
0
        /// <summary>
        /// Create a new HttpResponse object.
        /// </summary>
        /// <param name="req">The HttpRequest object for which this request is being created.</param>
        /// <param name="success">Indicates whether or not the request was successful.</param>
        /// <param name="status">The HTTP status code to return to the requestor (client).</param>
        /// <param name="headers">User-supplied headers to include in the response.</param>
        /// <param name="contentType">User-supplied content-type to include in the response.</param>
        /// <param name="data">The data to return to the requestor in the response body.  This must be either a byte[] or string.</param>
        /// <param name="rawResponse">Indicates whether or not the response Data should be enapsulated in a JSON object containing standard fields including 'success'.</param>
        public HttpResponse(HttpRequest req, bool success, int status, Dictionary <string, string> headers, string contentType, object data, bool rawResponse)
        {
            if (req == null)
            {
                throw new ArgumentNullException(nameof(req));
            }

            #region Set-Base-Variables

            TimestampUtc       = req.TimestampUtc;
            SourceIp           = req.SourceIp;
            SourcePort         = req.SourcePort;
            DestIp             = req.DestIp;
            DestPort           = req.DestPort;
            Method             = req.Method;
            RawUrlWithoutQuery = req.RawUrlWithoutQuery;

            Success     = success;
            Headers     = headers;
            ContentType = contentType;
            if (String.IsNullOrEmpty(ContentType))
            {
                ContentType = "application/json";
            }

            StatusCode  = status;
            RawResponse = rawResponse;
            Data        = data;

            #endregion

            #region Set-Status

            switch (status)
            {
            case 200:
                StatusDescription = "OK";
                break;

            case 201:
                StatusDescription = "Created";
                break;

            case 204:
                StatusDescription = "No Content";
                break;

            case 301:
                StatusDescription = "Moved Permanently";
                break;

            case 302:
                StatusDescription = "Moved Temporarily";
                break;

            case 304:
                StatusDescription = "Not Modified";
                break;

            case 400:
                StatusDescription = "Bad Request";
                break;

            case 401:
                StatusDescription = "Unauthorized";
                break;

            case 403:
                StatusDescription = "Forbidden";
                break;

            case 404:
                StatusDescription = "Not Found";
                break;

            case 405:
                StatusDescription = "Method Not Allowed";
                break;

            case 429:
                StatusDescription = "Too Many Requests";
                break;

            case 500:
                StatusDescription = "Internal Server Error";
                break;

            case 501:
                StatusDescription = "Not Implemented";
                break;

            case 503:
                StatusDescription = "Service Unavailable";
                break;

            default:
                StatusDescription = "Unknown";
                return;
            }

            #endregion

            #region Check-Data

            if (Data != null)
            {
                if (Data is byte[])
                {
                    ContentLength = ((byte[])Data).Length;
                }
                else if (Data is string)
                {
                    ContentLength = ((string)Data).Length;
                }
                else
                {
                    ContentLength = (WatsonCommon.SerializeJson(Data)).Length;
                    Data          = WatsonCommon.SerializeJson(Data);
                }
            }
            else
            {
                ContentLength = 0;
            }

            #endregion
        }