コード例 #1
0
        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)
                        );
                }
            }
        }
コード例 #2
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"
                );
        }
コード例 #3
0
 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");
 }
        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");
        }
コード例 #5
0
 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);
 }
コード例 #6
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");
        }
コード例 #7
0
        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);
            }
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
0
        /// <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;
        }
コード例 #14
0
        /// <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;
        }
コード例 #15
0
        /// <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;
        }
コード例 #16
0
        /// <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;
        }
        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 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);
            }
        }
コード例 #19
0
        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);
            }
        }
コード例 #20
0
        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);
            }
        }
コード例 #21
0
        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);
                }
            }
        }
コード例 #22
0
        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));
                }
            }
        }
コード例 #23
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"));
                }
            }
        }
コード例 #24
0
 /// <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)
 {
 }
コード例 #25
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"));
                }
            }
        }
コード例 #26
0
        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;
        }
コード例 #27
0
        /// <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);
        }
コード例 #28
0
        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);
                }
            }
        }
コード例 #29
0
 /// <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)
 {
 }
コード例 #30
0
        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);
                }
            }
        }
コード例 #31
0
        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);
            }
        }
コード例 #32
0
 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);
 }
コード例 #33
0
        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);
        }
コード例 #34
0
        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;
        }
コード例 #35
0
        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);
            }
        }