Пример #1
0
        /// <summary>
        /// Parses a HTTP header by reading the input stream
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="config">The server configuration.</param>
        /// <param name="idletime">The maximum idle time.</param>
        /// <param name="timeouttask">A task that signals request timeout.</param>
        /// <param name="stoptask">A task that signals server stop.</param>
        internal async Task Parse(BufferedStreamReader reader, ServerConfig config, TimeSpan idletime, Task timeouttask, Task stoptask)
        {
            await reader.ReadHeaders(
                config.MaxRequestLineSize,
                config.MaxRequestHeaderSize,
                idletime,
                HandleLine,
                timeouttask,
                stoptask
                );

            if (this.ContentLength > config.MaxPostSize)
            {
                throw new HttpException(HttpStatusCode.PayloadTooLarge);
            }

            // Disable HTTP/1.0 unless explictly allowed
            if (!config.AllowLegacyHttp && this.HttpVersion == HTTP_VERSION_1_0)
            {
                throw new HttpException(HttpStatusCode.HTTPVersionNotSupported);
            }

            // Enforce HTTP/1.1 requiring a header
            if (this.HttpVersion != HTTP_VERSION_1_0 && string.IsNullOrWhiteSpace(this.Headers["Host"]))
            {
                throw new HttpException(HttpStatusCode.BadRequest, "Host header missing");
            }

            if (config.AllowHttpMethodOverride)
            {
                string newmethod;
                this.Headers.TryGetValue("X-HTTP-Method-Override", out newmethod);
                if (!string.IsNullOrWhiteSpace(newmethod))
                {
                    this.Method = newmethod;
                }
            }

            if (!string.IsNullOrWhiteSpace(config.AllowedSourceIPHeaderValue))
            {
                string realip;
                this.Headers.TryGetValue(config.AllowedSourceIPHeaderValue, out realip);
                if (!string.IsNullOrWhiteSpace(realip))
                {
                    this.RemoteEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(realip), ((System.Net.IPEndPoint) this.RemoteEndPoint).Port);
                }
            }

            await ParseFormData(reader, config, idletime, timeouttask, stoptask);
        }
Пример #2
0
        /// <summary>
        /// Parses a HTTP header by reading the input stream
        /// </summary>
        /// <returns>An awaitable task.</returns>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="config">The server configuration.</param>
        /// <param name="idletime">The maximum idle time.</param>
        /// <param name="timeouttask">A task that signals request timeout.</param>
        /// <param name="stoptask">A task that signals server stop.</param>
        internal async Task Parse(BufferedStreamReader reader, ServerConfig config, TimeSpan idletime, Task timeouttask, Task stoptask)
        {
            await reader.ReadHeaders(
                config.MaxRequestLineSize,
                config.MaxRequestHeaderSize,
                idletime,
                HandleLine,
                timeouttask,
                stoptask
                );

            if (this.ContentLength > config.MaxPostSize)
            {
                throw new HttpException(HttpStatusCode.PayloadTooLarge);
            }

            if (config.AllowHttpMethodOverride)
            {
                string newmethod;
                this.Headers.TryGetValue("X-HTTP-Method-Override", out newmethod);
                if (!string.IsNullOrWhiteSpace(newmethod))
                {
                    this.Method = newmethod;
                }
            }

            if (!string.IsNullOrWhiteSpace(config.AllowedSourceIPHeaderValue))
            {
                string realip;
                this.Headers.TryGetValue(config.AllowedSourceIPHeaderValue, out realip);
                if (!string.IsNullOrWhiteSpace(realip))
                {
                    this.RemoteEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(realip), ((System.Net.IPEndPoint) this.RemoteEndPoint).Port);
                }
            }

            await ParseFormData(reader, config, idletime, timeouttask, stoptask);
        }
Пример #3
0
        private async Task ParseMultiPart(Func <IDictionary <string, string>, Stream, Task> itemparser, BufferedStreamReader reader, ServerConfig config, TimeSpan idletime, Task timeouttask, Task stoptask)
        {
            if ((this.ContentType ?? "").StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
            {
                if (this.ContentLength > config.MaxPostSize)
                {
                    throw new HttpException(HttpStatusCode.PayloadTooLarge);
                }

                var startpos = reader.Position;
                var trail    = new byte[2];
                var parts    = this.ContentType.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                var bndpart  = parts.FirstOrDefault(x => x.Trim().StartsWith("boundary", StringComparison.OrdinalIgnoreCase)) ?? string.Empty;
                var boundary = bndpart.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
                if (string.IsNullOrWhiteSpace(boundary))
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }

                // Since we have read the headers, we have consumed the initial CRLF
                // so we adjust the initial boundary reading to skip the CRLF
                var itemboundary = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary);
                var tmp          = await reader.RepeatReadAsync(itemboundary.Length - 2, idletime, timeouttask, stoptask);

                if (!Enumerable.SequenceEqual(itemboundary.Skip(2), tmp))
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }

                await reader.RepeatReadAsync(trail, 0, 2, idletime, timeouttask, stoptask);

                if (trail[0] != '\r' || trail[1] != '\n')
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }

                do
                {
                    var headers = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase).WithDefaultValue(null);

                    await reader.ReadHeaders(
                        config.MaxRequestLineSize,
                        config.MaxRequestHeaderSize,
                        idletime,
                        line =>
                    {
                        var components = line.Split(new char[] { ':' }, 2);
                        if (components.Length != 2 || string.IsNullOrWhiteSpace(components[0]))
                        {
                            throw new HttpException(HttpStatusCode.BadRequest);
                        }

                        headers[components[0].Trim()] = (components[1] ?? string.Empty).Trim();
                    },
                        timeouttask,
                        stoptask
                        );

                    await itemparser(headers, reader.GetDelimitedSubStream(itemboundary, idletime, timeouttask, stoptask));

                    await reader.RepeatReadAsync(trail, 0, 2, idletime, timeouttask, stoptask);
                }while (trail[0] == '\r' && trail[1] == '\n');


                if (trail[0] != '-' || trail[1] != '-')
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }

                await reader.RepeatReadAsync(trail, 0, 2, idletime, timeouttask, stoptask);

                if (trail[0] != '\r' || trail[1] != '\n')
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }

                if (this.ContentLength > 0 && this.ContentLength != (reader.Position - startpos))
                {
                    throw new HttpException(HttpStatusCode.BadRequest);
                }
            }
        }