コード例 #1
0
ファイル: HTTPRequest.cs プロジェクト: bpaziaud/Hermod
        /// <summary>
        /// Create a new http request header based on the given string representation.
        /// </summary>
        /// <param name="RemoteSocket">The remote TCP/IP socket.</param>
        /// <param name="LocalSocket">The local TCP/IP socket.</param>
        /// <param name="HTTPServer">The HTTP server of the request.</param>
        /// <param name="HTTPHeader">A valid string representation of a http request header.</param>
        /// <param name="HTTPBody">The HTTP body as an array of bytes.</param>
        /// <param name="HTTPBodyStream">The HTTP body as an stream of bytes.</param>
        /// <param name="CancellationToken">A token to cancel the HTTP request processing.</param>
        /// <param name="EventTrackingId">An unique event tracking identification for correlating this request with other events.</param>
        private HTTPRequest(IPSocket RemoteSocket,
                            IPSocket LocalSocket,
                            HTTPServer HTTPServer,
                            String HTTPHeader,
                            Byte[]              HTTPBody        = null,
                            Stream HTTPBodyStream               = null,
                            CancellationToken?CancellationToken = null,
                            EventTracking_Id EventTrackingId    = null)

            : base(RemoteSocket,
                   LocalSocket,
                   HTTPHeader,
                   HTTPBody,
                   HTTPBodyStream,
                   CancellationToken,
                   EventTrackingId)

        {
            this._HTTPServer = HTTPServer;

            #region Parse HTTPMethod (first line of the http request)

            var _HTTPMethodHeader = FirstPDULine.Split(_SpaceSeparator, StringSplitOptions.RemoveEmptyEntries);

            // e.g: PROPFIND /file/file Name HTTP/1.1
            if (_HTTPMethodHeader.Length != 3)
            {
                throw new Exception("Bad request");
            }

            // Parse HTTP method
            // Propably not usefull to define here, as we can not send a response having an "Allow-header" here!
            this._HTTPMethod = (HTTPMethod.TryParseString(_HTTPMethodHeader[0], out _HTTPMethod))
                                   ? _HTTPMethod
                                   : HTTPMethod.Create(_HTTPMethodHeader[0]);

            #endregion

            #region Parse URL and QueryString (first line of the http request)

            var RawUrl     = _HTTPMethodHeader[1];
            var _ParsedURL = RawUrl.Split(_URLSeparator, 2, StringSplitOptions.None);
            this.URI = HttpUtility.UrlDecode(_ParsedURL[0]);

            if (URI.StartsWith("http", StringComparison.Ordinal) || URI.StartsWith("https", StringComparison.Ordinal))
            {
                URI = URI.Substring(URI.IndexOf("://", StringComparison.Ordinal) + 3);
                URI = URI.Substring(URI.IndexOf("/", StringComparison.Ordinal) + 1);
            }

            if (URI == "" || URI == null)
            {
                URI = "/";
            }

            // Parse QueryString after '?'
            if (RawUrl.IndexOf('?') > -1 && _ParsedURL[1].IsNeitherNullNorEmpty())
            {
                this._QueryString = QueryString.Parse(_ParsedURL[1]);
            }
            else
            {
                this._QueryString = QueryString.Empty;
            }

            #endregion

            #region Parse protocol name and -version (first line of the http request)

            var _ProtocolArray = _HTTPMethodHeader[2].Split(_SlashSeparator, 2, StringSplitOptions.RemoveEmptyEntries);
            this._ProtocolName = _ProtocolArray[0].ToUpper();

            if (ProtocolName.ToUpper() != "HTTP")
            {
                throw new Exception("Bad request");
            }

            HTTPVersion _HTTPVersion = null;

            if (HTTPVersion.TryParseVersionString(_ProtocolArray[1], out _HTTPVersion))
            {
                this._ProtocolVersion = _HTTPVersion;
            }

            if (ProtocolVersion != HTTPVersion.HTTP_1_0 && ProtocolVersion != HTTPVersion.HTTP_1_1)
            {
                throw new Exception("HTTP version not supported");
            }

            #endregion


            #region Check Host header

            // rfc 2616 - Section 19.6.1.1
            // A client that sends an HTTP/1.1 request MUST send a Host header.

            // rfc 2616 - Section 14.23
            // All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request)
            // status code to any HTTP/1.1 request message which lacks a Host header field.

            // rfc 2616 - Section 5.2 The Resource Identified by a Request
            // 1. If Request-URI is an absoluteURI, the host is part of the Request-URI.
            //    Any Host header field value in the request MUST be ignored.
            // 2. If the Request-URI is not an absoluteURI, and the request includes a
            //    Host header field, the host is determined by the Host header field value.
            // 3. If the host as determined by rule 1 or 2 is not a valid host on the server,
            //    the response MUST be a 400 (Bad Request) error message. (Not valid for proxies?!)
            if (!_HeaderFields.ContainsKey(HTTPHeaderField.Host.Name))
            {
                throw new Exception("The HTTP PDU does not have a HOST header!");
            }

            // rfc 2616 - 3.2.2
            // If the port is empty or not given, port 80 is assumed.
            var HostHeader = _HeaderFields[HTTPHeaderField.Host.Name].ToString().
                             Split(_ColonSeparator, StringSplitOptions.RemoveEmptyEntries).
                             Select(v => v.Trim()).
                             ToArray();

            UInt16 HostPort = 80;

            if (HostHeader.Length == 1)
            {
                _HeaderFields[HTTPHeaderField.Host.Name] = _HeaderFields[HTTPHeaderField.Host.Name].ToString();// + ":80"; ":80" will cause side effects!
            }
            else if ((HostHeader.Length == 2 && !UInt16.TryParse(HostHeader[1], out HostPort)) || HostHeader.Length > 2)
            {
                throw new Exception("Bad request");
            }

            #endregion
        }
コード例 #2
0
 /// <summary>
 /// Set the protocol version.
 /// </summary>
 /// <param name="ProtocolVersion">The protocol version.</param>
 public HTTPRequestBuilder SetProtocolVersion(HTTPVersion ProtocolVersion)
 {
     this.ProtocolVersion = ProtocolVersion;
     return(this);
 }