public void ParseHttpVersion()
        {
            Assert.Equal(HttpVersion.VERSION_1_1, HttpVersion.Parse("1.1"));

            Assert.True(HttpVersion.TryParse("1.1", out _));

            Assert.False(HttpVersion.TryParse("1", out _));
            Assert.False(HttpVersion.TryParse("1.a", out _));
            Assert.False(HttpVersion.TryParse("a.1", out _));
        }
Beispiel #2
0
        public static HttpRequest Parse(string request)
        {
            string[] lines             = request.Split(new string[] { NewLine }, StringSplitOptions.None);
            string[] requestLineTokens = lines[0].Split(' ');

            if (requestLineTokens.Length != 3)
            {
                throw new BadRequestException(InvalidRequestLine);
            }

            string[] linkTokens = requestLineTokens[1].Split(new char[] { '?' }, 2);

            HttpMethod  method  = HttpMethod.Parse(requestLineTokens[0]);
            string      path    = linkTokens[0];
            HttpVersion version = HttpVersion.Parse(requestLineTokens[2]);

            HttpRequest httpRequest = new HttpRequest(method, path, version);


            if (linkTokens.Length == 2)
            {
                httpRequest.FormData = HttpFormData.Parse(linkTokens[1]);
            }

            int i = 0;

            try
            {
                while (!string.IsNullOrEmpty(lines[++i]))
                {
                    HttpHeader header = HttpHeader.Parse(lines[i]);

                    if (header.Name.ToLower() == "cookie")
                    {
                        string[] cookies = header.Value.Split(new string[] { "; " }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (var cookie in cookies)
                        {
                            string[] cookieKvp = cookie.Split('=');

                            if (cookieKvp.Length != 2)
                            {
                                throw new BadRequestException(InvalidCookieHeader);
                            }

                            httpRequest.AddCookie(new HttpCookie(cookieKvp[0], cookieKvp[1]));
                        }
                    }
                    else
                    {
                        httpRequest.AddHeader(header);
                    }
                }
            }
            catch (IndexOutOfRangeException ex)
            {
                throw new BadRequestException(NoEndOfHeaders, ex);
            }

            if (i < lines.Length - 1)
            {
                StringBuilder body = new StringBuilder();

                while (++i != lines.Length)
                {
                    string line = lines[i];

                    body.Append(line + NewLine);
                }

                httpRequest.Body = body.ToString()
                                   .TrimEnd(new char[] { '\r', '\n' });

                if (!string.IsNullOrEmpty(httpRequest.Body))
                {
                    httpRequest.FormData = HttpFormData.Parse(httpRequest.Body);
                }
            }

            return(httpRequest);
        }
Beispiel #3
0
        public Stream Decode(Stream inputStream)
        {
            List <byte> lineBuffer = new List <byte>();

            while (true)
            {
                byte b = (byte)inputStream.ReadByte();

                if (b < 0)
                {
                    Console.WriteLine("Malformed server response received, EOF reached unexpectedly");
                    return(null);
                }
                lineBuffer.Add(b);

                if (b != 10)                   //Keep collecting bytes if there's no linefeed (new line) \n indicated
                {
                    continue;
                }
                byte[] lineBufferArray = new byte[lineBuffer.Count];

                for (int i = 0; i < lineBufferArray.Length; i++)
                {
                    lineBufferArray[i] = lineBuffer[i];
                }
                string line = Encoding.ASCII.GetString(lineBufferArray).Trim(); //Build a string out of our collected bytes and trim off the line break
                lineBuffer.Clear();                                             //Clears the line buffer for the next read

                if (line == string.Empty)                                       //When an empty line is found it means we parsed all headers
                {
                    break;
                }
                if (line.Equals("0", StringComparison.Ordinal) ||
                    line.Equals(Delimiters.Linebreak, StringComparison.Ordinal))
                {
                    break;
                }
                if (line.StartsWith("HTTP", StringComparison.OrdinalIgnoreCase))                   //The status line of the response
                {
                    string[]      msgParts            = line.Split(" ");
                    string        httpProtocolVersion = msgParts[0];
                    string        responseCode        = msgParts[1];
                    StringBuilder responseMsgBuilder  = new StringBuilder();

                    for (int i = 2; i < msgParts.Length; i++)
                    {
                        responseMsgBuilder.Append(msgParts[i] + " ");
                    }
                    int      code     = MathUtil.ParseInt(responseCode);
                    HttpCode httpCode = HttpCode.GetForCode(code);
                    string   msg      = responseMsgBuilder.ToString().Trim();

                    if (string.IsNullOrEmpty(msg))
                    {
                        msg = httpCode.Message;
                    }
                    if (httpCode == HttpCode.Invalid)
                    {
                        msg = "[Unhandled code: " + code + "] - " + msg;
                    }
                    ResponseStatus = new ResponseStatus(HttpVersion.Parse(httpProtocolVersion), httpCode, msg);
                    continue;
                }
                string key   = StringFunc.Substring(line, 0, line.IndexOf(":")).Trim();
                string value = StringFunc.Substring(line, line.IndexOf(":") + 1, line.Length).Trim();

                if (!key.Equals(HeaderKeys.SetCookie, StringComparison.OrdinalIgnoreCase))
                {
                    Headers.Put(key, value);

                    if (HttpConfig.DebugMode)
                    {
                        Console.WriteLine("RESPONSE-HEADER => " + key + ": " + value);
                    }
                    continue;
                }
                Cookie cookie = ExtractCookie(value);
                Cookies.Add(cookie);

                if (HttpConfig.DebugMode)
                {
                    Console.WriteLine("RESPONSE-COOKIE => " + cookie.ToString());
                }
            }
            return(inputStream);
        }