internal HttpRequestLine(HttpSocket hs)
        {
            string line;

            do
            {
                line = hs.ReadAsciiLine().Trim();
            }while (line.Length == 0);

            string[] items = line.Split(sp,
                                        StringSplitOptions.RemoveEmptyEntries);
            if (items.Length != 3)
            {
                throw new HttpProtocolBroken("Unrecognized request line '" +
                                             line + "'");
            }

            RequestLine     = line;
            Method          = items[0];
            URI             = items[1];
            ProtocolVersion = ParserHelper.ParseProtocolVersion(items[2]);
        }
        internal HttpStatusLine(HttpSocket hs)
        {
            string line;

            do
            {
                line = hs.ReadAsciiLine().Trim();
            }while (line.Length == 0);
            string[] items = line.Split(sp,
                                        StringSplitOptions.RemoveEmptyEntries);
            // Note: the status line has three items: the HTTP protocol
            // version, the status code, and the reason phrase.
            // Only the reason phrase may be empty.
            if (items.Length < 2)
            {
                throw new HttpProtocolBroken("Unrecognized status line '" +
                                             line + "'");
            }

            ProtocolVersion = ParserHelper.ParseProtocolVersion(
                items[0]);

            string code = items[1];

            if (code.Length != 3 ||
                !char.IsDigit(code[0])) // we only test the first character
            {
                throw new HttpProtocolBroken("Invalid status code '" +
                                             code + "'");
            }

            //string Reason = rest of the string; // we don't need it

            StatusCode = int.Parse(code);
            StatusLine = line;
        }
Beispiel #3
0
        /// <summary>
        /// Read and parse HTTP headers from a connected socket
        /// </summary>
        public HttpHeaders(HttpSocket source) : this()
        {
            StringBuilder sb = new StringBuilder(512);

            while (true)
            {
                var line = source.ReadAsciiLine();
                if (line.Length == 0)
                {
                    break;
                }
                sb.Append(line);
                sb.Append("\r\n"); // Note: if the header newline was
                // incorrectly formatted (i.e. LF instead of CRLF),
                // we correct it here. This is one point where our
                // proxy is not fully transparent.

                var iSplit = line.IndexOf(':');
                if (iSplit <= 0)
                {
                    throw new HttpProtocolBroken("No colon in HTTP header");
                }

                // Header names are case-insensitive, but only some header
                // values are.
                string HeaderName  = line.Substring(0, iSplit).Trim().ToLower();
                string HeaderValue = line.Substring(iSplit + 1).Trim();
                if (IsHeaderValueCaseInsensitive(HeaderName))
                {
                    HeaderValue = HeaderValue.ToLower();
                }

                string previous_value = null;
                if (Headers.TryGetValue(HeaderName, out previous_value))
                {
                    // Duplicate headers: concatenate them
                    // (RFC 2616, section 4.2)

                    // However, this should only occur if the value of that
                    // header is a comma-separated list. In the real world,
                    // it has been observed that headers with
                    // non-comma-separated values, such as Content-Length, *are*
                    // in some rare cases repeated, so we should not concatenate
                    // the values.
                    if (!HeaderName.Equals("content-length"))
                    {
                        Headers[HeaderName] = previous_value + "," + HeaderValue;
                    }
                }
                else
                {
                    Headers[HeaderName] = HeaderValue;
                }
            }

            HeadersInOrder = sb.ToString();

            // Parse a subset of the header values.
            // If headers are added, don't forget to update RemoveHeader
            // as well.
            Connection       = ParseMultipleStringValues("connection");
            ContentEncoding  = ParseStringValue("content-encoding");
            ContentLength    = ParseIntValue("content-length");
            Host             = ParseStringValue("host");
            ProxyConnection  = ParseMultipleStringValues("proxy-connection");
            Referer          = ParseStringValue("referer");
            TransferEncoding = ParseMultipleStringValues("transfer-encoding");
        }