private static void ValidateResult( HttpUnsortedRequest requestLine, string method, string requestUri, Version version, Dictionary <string, string> headers ) { Assert.Equal(new HttpMethod(method), requestLine.Method); Assert.Equal(requestUri, requestLine.RequestUri); Assert.Equal(version, requestLine.Version); if (headers != null) { Assert.Equal(headers.Count, requestLine.HttpHeaders.Count()); foreach (var header in headers) { Assert.True( requestLine.HttpHeaders.Contains(header.Key), "Parsed header did not contain expected key " + header.Key ); Assert.Equal( header.Value, requestLine.HttpHeaders.GetValues(header.Key).ElementAt(0) ); } } }
public void HttpRequestLineParserConstructorTest() { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); Assert.NotNull(requestLine); Assert.ThrowsArgumentGreaterThanOrEqualTo( () => new HttpRequestLineParser(requestLine, ParserData.MinRequestLineSize - 1), "maxRequestLineSize", ParserData.MinRequestLineSize.ToString(), ParserData.MinRequestLineSize - 1 ); HttpRequestLineParser parser = new HttpRequestLineParser( requestLine, ParserData.MinRequestLineSize ); Assert.NotNull(parser); Assert.ThrowsArgumentNull( () => { new HttpRequestLineParser(null, ParserData.MinRequestLineSize); }, "httpRequest" ); }
public void RequestHeaderParserNullBuffer() { HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result, ParserData.MinRequestLineSize, ParserData.MinHeaderSize); Assert.NotNull(parser); int bytesConsumed = 0; Assert.ThrowsArgumentNull(() => { parser.ParseBuffer(null, 0, ref bytesConsumed); }, "buffer"); }
private static void ValidateResult( HttpUnsortedRequest requestLine, string method, string requestUri, Version version ) { Assert.Equal(new HttpMethod(method), requestLine.Method); Assert.Equal(requestUri, requestLine.RequestUri); Assert.Equal(version, requestLine.Version); }
public void HttpRequestLineParserConstructorTest() { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); Assert.NotNull(requestLine); Assert.ThrowsArgumentGreaterThanOrEqualTo(() => new HttpRequestLineParser(requestLine, ParserData.MinRequestLineSize - 1), "maxRequestLineSize", ParserData.MinRequestLineSize.ToString(), ParserData.MinRequestLineSize - 1); HttpRequestLineParser parser = new HttpRequestLineParser(requestLine, ParserData.MinRequestLineSize); Assert.NotNull(parser); Assert.ThrowsArgumentNull(() => { new HttpRequestLineParser(null, ParserData.MinRequestLineSize); }, "httpRequest"); }
public void RequestHeaderParserMinimumBuffer() { byte[] data = CreateBuffer("G", "/", "HTTP/1.1", null); HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result, ParserData.MinRequestLineSize, ParserData.MinHeaderSize); Assert.NotNull(parser); int bytesConsumed = 0; ParserState state = parser.ParseBuffer(data, data.Length, ref bytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, bytesConsumed); ValidateResult(result, "G", "/", new Version("1.1"), null); }
public void RequestHeaderParserRejectsInvalidVersion(string invalidVersion) { byte[] data = CreateBuffer("GET", "/", invalidVersion, ParserData.ValidHeaders); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Invalid, state); } }
public void RequestLineParserRejectsLws() { byte[] data = CreateBuffer("GET", "/", "HTTP/1.1", true); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); HttpRequestLineParser parser = new HttpRequestLineParser(requestLine, data.Length); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Invalid, state); } }
/// <summary> /// Initializes a new instance of the <see cref="HttpRequestHeaderParser"/> class. /// </summary> /// <param name="httpRequest">The parsed HTTP request without any header sorting.</param> /// <param name="maxRequestLineSize">The max length of the HTTP request line.</param> /// <param name="maxHeaderSize">The max length of the HTTP header.</param> public HttpRequestHeaderParser(HttpUnsortedRequest httpRequest, int maxRequestLineSize, int maxHeaderSize) { if (httpRequest == null) { throw Error.ArgumentNull("httpRequest"); } _httpRequest = httpRequest; // Create request line parser _requestLineParser = new HttpRequestLineParser(_httpRequest, maxRequestLineSize); // Create header parser _headerParser = new InternetMessageFormatHeaderParser(_httpRequest.HttpHeaders, maxHeaderSize); }
/// <summary> /// Initializes a new instance of the <see cref="HttpRequestLineParser"/> class. /// </summary> /// <param name="httpRequest"><see cref="HttpUnsortedRequest"/> instance where the request line properties will be set as they are parsed.</param> /// <param name="maxRequestLineSize">Maximum length of HTTP header.</param> public HttpRequestLineParser(HttpUnsortedRequest httpRequest, int maxRequestLineSize) { // The minimum length which would be an empty header terminated by CRLF if (maxRequestLineSize < MinRequestLineSize) { throw Error.ArgumentMustBeGreaterThanOrEqualTo("maxRequestLineSize", maxRequestLineSize, MinRequestLineSize); } if (httpRequest == null) { throw Error.ArgumentNull("httpRequest"); } _httpRequest = httpRequest; _maximumHeaderLength = maxRequestLineSize; }
/// <summary> /// Initializes a new instance of the <see cref="HttpRequestLineParser"/> class. /// </summary> /// <param name="httpRequest"><see cref="HttpUnsortedRequest"/> instance where the request line properties will be set as they are parsed.</param> /// <param name="maxRequestLineSize">Maximum length of HTTP header.</param> public HttpRequestLineParser(HttpUnsortedRequest httpRequest, int maxRequestLineSize) { // The minimum length which would be an empty header terminated by CRLF if (maxRequestLineSize < MinRequestLineSize) { throw new ArgumentOutOfRangeException("maxRequestLineSize", maxRequestLineSize, RS.Format(Properties.Resources.ArgumentMustBeGreaterThanOrEqualTo, MinRequestLineSize)); } if (httpRequest == null) { throw new ArgumentNullException("httpRequest"); } _httpRequest = httpRequest; _maximumHeaderLength = maxRequestLineSize; }
public void RequestHeaderParserAcceptsValidVersion(Version version) { byte[] data = CreateBuffer("GET", "/", String.Format("HTTP/{0}", version.ToString(2)), ParserData.ValidHeaders); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(result, "GET", "/", version, ParserData.ValidHeaders); } }
public void RequestHeaderParserAcceptsStandardMethods(HttpMethod method) { byte[] data = CreateBuffer(method.ToString(), "/", "HTTP/1.1", ParserData.ValidHeaders); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(result, method.ToString(), "/", new Version("1.1"), ParserData.ValidHeaders); } }
public void RequestHeaderParserAcceptsCustomMethods(HttpMethod method) { byte[] data = CreateBuffer(method.ToString(), "/", "HTTP/1.1", ParserData.ValidHeaders); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest result = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(result); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(result, method.ToString(), "/", new Version("1.1"), ParserData.ValidHeaders); } }
public void RequestLineParserRejectsInvalidUri() { foreach (string invalidRequestUri in ParserData.InvalidRequestUris) { byte[] data = CreateBuffer("GET", invalidRequestUri, "HTTP/1.1"); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); HttpRequestLineParser parser = new HttpRequestLineParser(requestLine, 256); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Invalid, state); } } }
private static void ValidateResult( HttpUnsortedRequest requestLine, string method, string requestUri, Version version, Dictionary<string, string> headers) { Assert.Equal(new HttpMethod(method), requestLine.Method); Assert.Equal(requestUri, requestLine.RequestUri); Assert.Equal(version, requestLine.Version); if (headers != null) { Assert.Equal(headers.Count, requestLine.HttpHeaders.Count()); foreach (var header in headers) { Assert.True(requestLine.HttpHeaders.Contains(header.Key), "Parsed header did not contain expected key " + header.Key); Assert.Equal(header.Value, requestLine.HttpHeaders.GetValues(header.Key).ElementAt(0)); } } }
public void RequestLineParserAcceptsCustomMethods() { foreach (HttpMethod method in HttpUnitTestDataSets.CustomHttpMethods) { byte[] data = CreateBuffer(method.ToString(), "/", "HTTP/1.1"); for (var cnt = 1; cnt <= data.Length; cnt++) { HttpUnsortedRequest requestLine = new HttpUnsortedRequest(); HttpRequestLineParser parser = new HttpRequestLineParser(requestLine, data.Length); Assert.NotNull(parser); int totalBytesConsumed = 0; ParserState state = ParseBufferInSteps(parser, data, cnt, out totalBytesConsumed); Assert.Equal(ParserState.Done, state); Assert.Equal(data.Length, totalBytesConsumed); ValidateResult(requestLine, method.ToString(), "/", new Version("1.1")); } } }
/// <summary> /// Initializes a new instance of the <see cref="HttpRequestHeaderParser"/> class. /// </summary> /// <param name="httpRequest">The parsed HTTP request without any header sorting.</param> public HttpRequestHeaderParser(HttpUnsortedRequest httpRequest) : this(httpRequest, DefaultMaxRequestLineSize, DefaultMaxHeaderSize) { }
private static HttpRequestMessage CreateHttpRequestMessage(string uriScheme, HttpUnsortedRequest httpRequest, Stream contentStream, int rewind) { Contract.Assert(uriScheme != null, "URI scheme must be non null"); Contract.Assert(httpRequest != null, "httpRequest must be non null"); Contract.Assert(contentStream != null, "contentStream must be non null"); HttpRequestMessage httpRequestMessage = new HttpRequestMessage(); // Set method, requestURI, and version httpRequestMessage.Method = httpRequest.Method; httpRequestMessage.RequestUri = CreateRequestUri(uriScheme, httpRequest); httpRequestMessage.Version = httpRequest.Version; // Set the header fields and content if any httpRequestMessage.Content = CreateHeaderFields(httpRequest.HttpHeaders, httpRequestMessage.Headers, contentStream, rewind); return httpRequestMessage; }
/// <summary> /// Creates the request URI by combining scheme (provided) with parsed values of /// host and path. /// </summary> /// <param name="uriScheme">The URI scheme to use for the request URI.</param> /// <param name="httpRequest">The unsorted HTTP request.</param> /// <returns>A fully qualified request URI.</returns> private static Uri CreateRequestUri(string uriScheme, HttpUnsortedRequest httpRequest) { Contract.Assert(httpRequest != null, "httpRequest cannot be null."); Contract.Assert(uriScheme != null, "uriScheme cannot be null"); IEnumerable<string> hostValues; if (httpRequest.HttpHeaders.TryGetValues(FormattingUtilities.HttpHostHeader, out hostValues)) { int hostCount = hostValues.Count(); if (hostCount != 1) { throw Error.InvalidOperation(Resources.HttpMessageParserInvalidHostCount, FormattingUtilities.HttpHostHeader, hostCount); } } else { throw Error.InvalidOperation(Resources.HttpMessageParserInvalidHostCount, FormattingUtilities.HttpHostHeader, 0); } // We don't use UriBuilder as hostValues.ElementAt(0) contains 'host:port' and UriBuilder needs these split out into separate host and port. string requestUri = String.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", uriScheme, hostValues.ElementAt(0), httpRequest.RequestUri); return new Uri(requestUri); }
private static async Task<HttpRequestMessage> ReadAsHttpRequestMessageAsyncCore(this HttpContent content, string uriScheme, int bufferSize, int maxHeaderSize, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Stream stream = await content.ReadAsStreamAsync(); HttpUnsortedRequest httpRequest = new HttpUnsortedRequest(); HttpRequestHeaderParser parser = new HttpRequestHeaderParser(httpRequest, HttpRequestHeaderParser.DefaultMaxRequestLineSize, maxHeaderSize); ParserState parseStatus; byte[] buffer = new byte[bufferSize]; int bytesRead = 0; int headerConsumed = 0; while (true) { try { bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); } catch (Exception e) { throw new IOException(Resources.HttpMessageErrorReading, e); } try { parseStatus = parser.ParseBuffer(buffer, bytesRead, ref headerConsumed); } catch (Exception) { parseStatus = ParserState.Invalid; } if (parseStatus == ParserState.Done) { return CreateHttpRequestMessage(uriScheme, httpRequest, stream, bytesRead - headerConsumed); } else if (parseStatus != ParserState.NeedMoreData) { throw Error.InvalidOperation(Resources.HttpMessageParserError, headerConsumed, buffer); } else if (bytesRead == 0) { throw new IOException(Resources.ReadAsHttpMessageUnexpectedTermination); } } }
private static void ValidateResult(HttpUnsortedRequest requestLine, string method, string requestUri, Version version) { Assert.Equal(new HttpMethod(method), requestLine.Method); Assert.Equal(requestUri, requestLine.RequestUri); Assert.Equal(version, requestLine.Version); }
private static ParserState ParseRequestLine( byte[] buffer, int bytesReady, ref int bytesConsumed, ref HttpRequestLineState requestLineState, int maximumHeaderLength, ref int totalBytesConsumed, StringBuilder currentToken, HttpUnsortedRequest httpRequest) { Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseRequestLine()|(bytesReady - bytesConsumed) < 0"); Contract.Assert(maximumHeaderLength <= 0 || totalBytesConsumed <= maximumHeaderLength, "ParseRequestLine()|Headers already read exceeds limit."); // Remember where we started. int initialBytesParsed = bytesConsumed; int segmentStart; // Set up parsing status with what will happen if we exceed the buffer. ParserState parseStatus = ParserState.DataTooBig; int effectiveMax = maximumHeaderLength <= 0 ? Int32.MaxValue : (maximumHeaderLength - totalBytesConsumed + bytesConsumed); if (bytesReady < effectiveMax) { parseStatus = ParserState.NeedMoreData; effectiveMax = bytesReady; } Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length."); switch (requestLineState) { case HttpRequestLineState.RequestMethod: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != ' ') { if (buffer[bytesConsumed] < 0x21 || buffer[bytesConsumed] > 0x7a) { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string method = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(method); goto quit; } } if (bytesConsumed > segmentStart) { string method = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(method); } // Copy value out httpRequest.Method = new HttpMethod(currentToken.ToString()); currentToken.Clear(); // Move past the SP requestLineState = HttpRequestLineState.RequestUri; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.RequestUri; case HttpRequestLineState.RequestUri: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != ' ') { if (buffer[bytesConsumed] == '\r') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string addr = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(addr); goto quit; } } if (bytesConsumed > segmentStart) { string addr = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(addr); } // URI validation happens when we create the URI later. if (currentToken.Length == 0) { throw new FormatException(Properties.Resources.HttpMessageParserEmptyUri); } // Copy value out httpRequest.RequestUri = currentToken.ToString(); currentToken.Clear(); // Move past the SP requestLineState = HttpRequestLineState.BeforeVersionNumbers; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.BeforeVersionNumbers; case HttpRequestLineState.BeforeVersionNumbers: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '/') { if (buffer[bytesConsumed] < 0x21 || buffer[bytesConsumed] > 0x7a) { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string token = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(token); goto quit; } } if (bytesConsumed > segmentStart) { string token = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(token); } // Validate value string version = currentToken.ToString(); if (String.CompareOrdinal(FormattingUtilities.HttpVersionToken, version) != 0) { throw new FormatException(Error.Format(Properties.Resources.HttpInvalidVersion, version, FormattingUtilities.HttpVersionToken)); } currentToken.Clear(); // Move past the '/' requestLineState = HttpRequestLineState.MajorVersionNumber; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.MajorVersionNumber; case HttpRequestLineState.MajorVersionNumber: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '.') { if (buffer[bytesConsumed] < '0' || buffer[bytesConsumed] > '9') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string major = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(major); goto quit; } } if (bytesConsumed > segmentStart) { string major = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(major); } // Move past the "." currentToken.Append('.'); requestLineState = HttpRequestLineState.MinorVersionNumber; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.MinorVersionNumber; case HttpRequestLineState.MinorVersionNumber: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '\r') { if (buffer[bytesConsumed] < '0' || buffer[bytesConsumed] > '9') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string minor = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(minor); goto quit; } } if (bytesConsumed > segmentStart) { string minor = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(minor); } // Copy out value httpRequest.Version = Version.Parse(currentToken.ToString()); currentToken.Clear(); // Move past the CR requestLineState = HttpRequestLineState.AfterCarriageReturn; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.AfterCarriageReturn; case HttpRequestLineState.AfterCarriageReturn: if (buffer[bytesConsumed] != '\n') { parseStatus = ParserState.Invalid; goto quit; } parseStatus = ParserState.Done; bytesConsumed++; break; } quit: totalBytesConsumed += bytesConsumed - initialBytesParsed; return(parseStatus); }
private static ParserState ParseRequestLine( byte[] buffer, int bytesReady, ref int bytesConsumed, ref HttpRequestLineState requestLineState, int maximumHeaderLength, ref int totalBytesConsumed, StringBuilder currentToken, HttpUnsortedRequest httpRequest) { Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseRequestLine()|(bytesReady - bytesConsumed) < 0"); Contract.Assert(maximumHeaderLength <= 0 || totalBytesConsumed <= maximumHeaderLength, "ParseRequestLine()|Headers already read exceeds limit."); // Remember where we started. int initialBytesParsed = bytesConsumed; int segmentStart; // Set up parsing status with what will happen if we exceed the buffer. ParserState parseStatus = ParserState.DataTooBig; int effectiveMax = maximumHeaderLength <= 0 ? Int32.MaxValue : (maximumHeaderLength - totalBytesConsumed + bytesConsumed); if (bytesReady < effectiveMax) { parseStatus = ParserState.NeedMoreData; effectiveMax = bytesReady; } Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length."); switch (requestLineState) { case HttpRequestLineState.RequestMethod: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != ' ') { if (buffer[bytesConsumed] < 0x21 || buffer[bytesConsumed] > 0x7a) { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string method = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(method); goto quit; } } if (bytesConsumed > segmentStart) { string method = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(method); } // Copy value out httpRequest.Method = new HttpMethod(currentToken.ToString()); currentToken.Clear(); // Move past the SP requestLineState = HttpRequestLineState.RequestUri; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.RequestUri; case HttpRequestLineState.RequestUri: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != ' ') { if (buffer[bytesConsumed] == '\r') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string addr = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(addr); goto quit; } } if (bytesConsumed > segmentStart) { string addr = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(addr); } // URI validation happens when we create the URI later. if (currentToken.Length == 0) { throw new FormatException(Properties.Resources.HttpMessageParserEmptyUri); } // Copy value out httpRequest.RequestUri = currentToken.ToString(); currentToken.Clear(); // Move past the SP requestLineState = HttpRequestLineState.BeforeVersionNumbers; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.BeforeVersionNumbers; case HttpRequestLineState.BeforeVersionNumbers: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '/') { if (buffer[bytesConsumed] < 0x21 || buffer[bytesConsumed] > 0x7a) { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string token = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(token); goto quit; } } if (bytesConsumed > segmentStart) { string token = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(token); } // Validate value string version = currentToken.ToString(); if (String.CompareOrdinal(FormattingUtilities.HttpVersionToken, version) != 0) { throw new FormatException(Error.Format(Properties.Resources.HttpInvalidVersion, version, FormattingUtilities.HttpVersionToken)); } currentToken.Clear(); // Move past the '/' requestLineState = HttpRequestLineState.MajorVersionNumber; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.MajorVersionNumber; case HttpRequestLineState.MajorVersionNumber: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '.') { if (buffer[bytesConsumed] < '0' || buffer[bytesConsumed] > '9') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string major = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(major); goto quit; } } if (bytesConsumed > segmentStart) { string major = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(major); } // Move past the "." currentToken.Append('.'); requestLineState = HttpRequestLineState.MinorVersionNumber; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.MinorVersionNumber; case HttpRequestLineState.MinorVersionNumber: segmentStart = bytesConsumed; while (buffer[bytesConsumed] != '\r') { if (buffer[bytesConsumed] < '0' || buffer[bytesConsumed] > '9') { parseStatus = ParserState.Invalid; goto quit; } if (++bytesConsumed == effectiveMax) { string minor = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(minor); goto quit; } } if (bytesConsumed > segmentStart) { string minor = Encoding.UTF8.GetString(buffer, segmentStart, bytesConsumed - segmentStart); currentToken.Append(minor); } // Copy out value httpRequest.Version = Version.Parse(currentToken.ToString()); currentToken.Clear(); // Move past the CR requestLineState = HttpRequestLineState.AfterCarriageReturn; if (++bytesConsumed == effectiveMax) { goto quit; } goto case HttpRequestLineState.AfterCarriageReturn; case HttpRequestLineState.AfterCarriageReturn: if (buffer[bytesConsumed] != '\n') { parseStatus = ParserState.Invalid; goto quit; } parseStatus = ParserState.Done; bytesConsumed++; break; } quit: totalBytesConsumed += bytesConsumed - initialBytesParsed; return parseStatus; }