Пример #1
0
        internal HttpResponseHeader(DataReader reader, IEnumerable<KeyDataPair<string>> headers, int responseCode, string message, HttpVersion version)
        {
            _reader = reader;
            Headers = new List<KeyDataPair<string>>(headers);
            ResponseCode = responseCode;
            Message = message;
            Version = version;

            if (ResponseCode != 304)
            {
                ContentLength = HttpParser.GetContentLength(Headers);
                ChunkedEncoding = HttpParser.IsChunkedEncoding(Headers);
                HasBody = true;
            }

            // Always trust a content-length if it exists
            if (Headers.Count(p => p.Name.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) == 0)
            {
                // Otherwise if version unknown, 1.0 or connection will close set then indicate we will read to the end
                if (Version.IsVersionUnknown || Version.IsVersion10 || (Headers.Count(p => p.Name.Equals("Connection", StringComparison.OrdinalIgnoreCase) && p.Value.Equals("close", StringComparison.OrdinalIgnoreCase)) > 0))
                {
                    ReadToEnd = true;
                }
            }
        }
Пример #2
0
        internal HttpRequestHeader(DataReader reader, IEnumerable<KeyDataPair<string>> headers, string method, string path, HttpVersion version)
        {
            _reader = reader;
            Headers = new List<KeyDataPair<string>>(headers);
            Method = method;
            Path = path;
            Version = version;

            // These methods can't have a content length
            if(IsGet || IsHead)
            {
                ContentLength = 0;
            }
            else
            {
                ContentLength = HttpParser.GetContentLength(Headers);
            }
        }
Пример #3
0
        /// <summary>
        /// Try and parse a string to a version
        /// </summary>
        /// <param name="version">The version string (should be HTTP/X.Y)</param>
        /// <param name="ret">The output parameter for the version</param>
        /// <returns>True if successfully parsed the verison</returns>        
        public static bool TryParse(string version, out HttpVersion ret)
        {
            Regex re = new Regex(@"^http/([0-9])+\.([0-9]+)$", RegexOptions.IgnoreCase);
            Match m = re.Match(version);
            ret = new HttpVersion();
            bool success = false;

            if (m.Success)
            {
                int major;
                int minor;

                if (int.TryParse(m.Groups[1].Value, out major) && int.TryParse(m.Groups[2].Value, out minor))
                {
                    ret = new HttpVersion(major, minor);
                    success = true;
                }
            }

            return success;
        }
Пример #4
0
        /// <summary>
        /// Read the response header
        /// </summary>
        /// <param name="reader">The data reader to read from</param>        
        /// <param name="strictParsing">Use strict parsing rules</param>
        /// <param name="logger">The logger to write errors to</param>
        /// <exception cref="EndOfStreamException">Thrown when stream ends</exception>
        /// <returns>The http response header</returns>
        public static HttpResponseHeader ReadResponseHeader(DataReader reader, bool strictParsing, Logger logger)
        {
            // Read just first 4 chars
            string header = reader.ReadLine(BinaryEncoding.Instance, TextLineEnding.LineFeed, 4);

            // If no more data left then we end here
            if (header.Length == 0)
            {
                throw new EndOfStreamException();
            }

            if (strictParsing)
            {
                CheckLineEnding(header);
            }

            if (header.Equals("http", StringComparison.OrdinalIgnoreCase))
            {
                // Read to end of line
                header = header + reader.ReadLine();

                HttpVersion ver = new HttpVersion(1, 0);
                string[] values = header.Trim().Split(new char[] { ' ' }, 3);

                if (values.Length < 2)
                {
                    throw new HttpStreamParserException(String.Format(Properties.Resources.HttpParser_ResponseHeaderInvalid, header));
                }

                if (!HttpVersion.TryParse(values[0], out ver))
                {
                    throw new HttpStreamParserException(Properties.Resources.HttpParser_InvalidHttpVersionString);
                }

                int responseCode;

                if (!int.TryParse(values[1], out responseCode))
                {
                    throw new HttpStreamParserException(Properties.Resources.HttpParser_InvalidHttpResponseCode);
                }

                return new HttpResponseHeader(reader, ReadHeaders(reader, strictParsing, logger),
                    responseCode, values.Length > 2 ? values[2] : String.Empty, ver);
            }
            else
            {
                // Case where server probably responded with simple response even when we sent a full one
                return new HttpResponseHeader(reader, header);
            }
        }
Пример #5
0
        private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, IEnumerable<KeyDataPair<string>> sendHeaders, DataAdapterToStream stm)
        {
            if (request != null)
            {
                FlushRequest(request);
            }

            HttpResponseDataChunk response = new HttpResponseDataChunk();

            if (_config.Version10Proxy && !version.IsVersionUnknown)
            {
                response.Version = HttpVersion.Version10;
            }
            else
            {
                response.Version = version;
            }

            response.ResponseCode = responseCode;
            response.Message = message;
            response.FinalChunk = true;
            response.Body = new byte[0];

            List<KeyDataPair<string>> headers = new List<KeyDataPair<string>>(sendHeaders);

            headers.Add(new KeyDataPair<string>("X-Proxy-Server", "CANAPE"));

            if (response.Body.Length > 0)
            {
                headers.Add(new KeyDataPair<string>("Content-Type", "text/html"));
            }

            response.Headers = headers.ToArray();

            if (method.Equals("HEAD", StringComparison.OrdinalIgnoreCase))
            {
                response.HeadResponse = true;
            }
            else if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase))
            {
                response.ConnectResponse = true;
            }

            response.WriteChunk(new DataWriter(stm));
        }
Пример #6
0
 private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, DataAdapterToStream stm)
 {
     ReturnResponse(request, responseCode, message, method, version, new KeyDataPair<string>[0], stm);
 }
Пример #7
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="headers">List of headers</param>
 /// <param name="version">The HTTP version</param>
 protected HttpDataChunk(IEnumerable<KeyDataPair<string>> headers, HttpVersion version)
 {
     Headers = headers.ToArray();
     Version = version;
     Body = new byte[0];
 }
Пример #8
0
        internal HttpRequestHeader(DataReader reader, IEnumerable <KeyDataPair <string> > headers, string method, string path, HttpVersion version)
        {
            _reader = reader;
            Headers = new List <KeyDataPair <string> >(headers);
            Method  = method;
            Path    = path;
            Version = version;

            // These methods can't have a content length
            if (IsGet || IsHead)
            {
                ContentLength = 0;
            }
            else
            {
                ContentLength = HttpParser.GetContentLength(Headers);
            }
        }
Пример #9
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="headers">List of headers</param>
 /// <param name="version">The HTTP version</param>
 protected HttpDataChunk(IEnumerable <HttpHeader> headers, HttpVersion version)
 {
     Headers = headers.ToArray();
     Version = version;
     Body    = new byte[0];
 }
Пример #10
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="headers">List of headers</param>
 /// <param name="version">The HTTP version</param>
 protected HttpDataChunk(IEnumerable <KeyDataPair <string> > headers, HttpVersion version)
 {
     Headers = headers.ToArray();
     Version = version;
     Body    = new byte[0];
 }
Пример #11
0
            private HttpResponseDataChunk BuildError(int error, string message, string method, HttpVersion version)
            {
                HttpResponseDataChunk response = new HttpResponseDataChunk();

                response.Version = version;
                response.ResponseCode = error;
                response.Message = message;
                response.FinalChunk = true;
                response.Body = new byte[0];

                List<KeyDataPair<string>> headers = new List<KeyDataPair<string>>();

                headers.Add(new KeyDataPair<string>("X-Proxy-Server", "CANAPE"));
                response.Headers = headers.ToArray();

                if (method.Equals("HEAD", StringComparison.OrdinalIgnoreCase))
                {
                    response.HeadResponse = true;
                }
                else if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase))
                {
                    response.ConnectResponse = true;
                }

                return response;
            }