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 _)); }
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); }
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); }