public static CustomHttpRequest Parse(string str)
        {
            string[]          stringLines = str.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
            CustomHttpRequest request     = new CustomHttpRequest();

            string body = "";

            bool foundStartLine = false;
            bool foundBody      = false;

            for (int i = 0; i < stringLines.Length; i++)
            {
                string line = stringLines[i];

                if (!foundBody)
                {
                    if (line.Length < 0 && line.Trim().Length > 0)
                    {
                        throw new System.Web.HttpException(400, "Bad Request");
                    }

                    //If we haven't found the start line
                    if (!foundStartLine && line.Length < 1)
                    {
                        continue;
                    }
                    //If this is the start line
                    else if (!foundStartLine)
                    {
                        string[] startLineParts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        if (startLineParts.Length < 2)
                        {
                            throw new System.Web.HttpException(400, "Bad Request");
                        }

                        request._method        = startLineParts[0];
                        request._requestTarget = new Uri(new Uri("http://localhost"), startLineParts[1]);
                        if (startLineParts.Length > 2)
                        {
                            request._httpVersion = startLineParts[2];
                        }

                        foundStartLine = true;
                    }
                    //If this is the separator between the header and the body
                    else if (line.Length < 1)
                    {
                        foundBody = true;
                        continue;
                    }
                    //This is a header field
                    else
                    {
                        int semicolonPosition = line.IndexOf(':');
                        if (semicolonPosition == -1)
                        {
                            throw new System.Web.HttpException(400, "Bad Request");
                        }
                        string key = line.Substring(0, semicolonPosition);
                        if (key.Contains(" "))
                        {
                            throw new System.Web.HttpException(400, "Bad Request");
                        }
                        string value = line.Substring(semicolonPosition + 1).Trim();
                        if (request._headers[key] == null)
                        {
                            request._headers.Add(key, value);
                        }
                        else
                        {
                            request._headers[key] += "," + value;
                        }
                    }
                }
                else if (foundBody)
                {
                    body += "\r\n" + line;
                }
            }
            request._body = body;

            //Parse POST request if needed
            if (request.Method.ToLower() == "post")
            {
                request._postData = new Dictionary <string, string>();
                if (request.Body.Trim().Length > 0)
                {
                    string   rawData  = request.Body.Trim();
                    string[] rawParts = rawData.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string rawPart in rawParts)
                    {
                        string part        = rawPart.Trim();
                        int    equalsIndex = part.IndexOf('=');
                        string key         = null;
                        string value       = null;
                        if (equalsIndex < 0)
                        {
                            continue;
                        }
                        else
                        {
                            key = part.Substring(0, equalsIndex);
                            if (part.Length > equalsIndex + 1)
                            {
                                value = part.Substring(equalsIndex + 1);
                                value = System.Web.HttpUtility.UrlDecode(value);
                            }
                            else
                            {
                                value = string.Empty;
                            }
                        }

                        if (!request._postData.ContainsKey(key))
                        {
                            request._postData.Add(key, value);
                        }
                    }
                }
            }

            //Parse cookies if needed
            if (request.Headers["Cookie"] != null)
            {
                string[] cookies = request.Headers["Cookie"].Split(new char[] { ';' });
                foreach (string cookie in cookies)
                {
                    string trimmedCookie  = cookie.Trim();
                    int    equalsPosition = trimmedCookie.IndexOf('=');
                    if (equalsPosition == -1)
                    {
                        continue;
                    }

                    string key   = trimmedCookie.Substring(0, equalsPosition).Trim();
                    string value = trimmedCookie.Substring(equalsPosition + 1).Trim();
                    request._cookies.Add(key, value);
                }
            }

            return(request);
        }
Exemplo n.º 2
0
        protected void handleClient(TcpClient client)
        {
            NetworkStream stream = client.GetStream();

            try
            {
                byte[] data          = new byte[client.ReceiveBufferSize];
                int    numBytesRead  = stream.Read(data, 0, client.ReceiveBufferSize);
                string requestString = new UTF8Encoding().GetString(data, 0, numBytesRead);

                CustomHttpRequest httpRequest      = CustomHttpRequest.Parse(requestString);
                WebServerRequest  webServerRequest = new WebServerRequest();
                webServerRequest.Cookies = httpRequest.Cookies;
                webServerRequest.Body    = httpRequest.Body;
                webServerRequest.Path    = httpRequest.RequestTarget.LocalPath;

                //Parse additional data
                Dictionary <string, List <string> > queryParts = ParseQuery(httpRequest.RequestTarget.Query);
                object additionalData = null;
                if (httpRequest.Method == "POST")
                {
                    if (httpRequest.PostData.ContainsKey(dataKey))
                    {
                        additionalData = httpRequest.PostData[dataKey];
                    }
                    else
                    {
                        additionalData = httpRequest.PostData;
                    }
                }
                else
                {
                    if (queryParts.ContainsKey(dataKey) && queryParts[dataKey].Count > 0)
                    {
                        additionalData = queryParts[dataKey].First();
                    }
                }
                webServerRequest.Data = additionalData;

                CustomHttpResponse response = new CustomHttpResponse(generateResponse(webServerRequest));
                response.ToStream(stream);
            }
            catch (System.Web.HttpException ex)
            {
                new CustomHttpResponse(ex).ToStream(stream);
            }
            catch
            {
                if (client.Connected)
                {
                    try
                    {
                        CustomHttpResponse response = new CustomHttpResponse();
                        response.StatusCode = "500 Internal Server Error";
                        response.ToStream(stream);
                    }
                    catch { }
                }
            }

            client.Close();
        }