Represents a structure where partial HTTP data can accumulate as it is transmitted until transmission is complete.
The HTTPPartialData class holds HTTP data as it is transmitted. It verifies the transmitted data is valid HTTP and provides properties to signal the message was completely received or to signal an error.
Example #1
0
        /// <summary>
        /// Initializes a new instance of the SetTransferRequest class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public SetTransferRequest(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            lastModified = DateTime.MinValue;
            if (headers["LAST-MODIFIED"] != null)
            {
                long v;
                if (long.TryParse(headers["LAST-MODIFIED"], out v))
                {
                    try
                    {
                        lastModified = new DateTime(v);
                    }
                    catch
                    {
                        lastModified = DateTime.MinValue;
                    }
                }
            }

            lockDate = null;
            if (headers["LOCKDATE"] != null)
            {
                long v;
                if (long.TryParse(headers["LOCKDATE"], out v))
                {
                    try
                    {
                        lockDate = new DateTime(v);
                    }
                    catch
                    {
                        lockDate = null;
                    }
                }
            }

            lockAge = null;
            if (headers["LOCKAGE"] != null)
            {
                int v;
                if (int.TryParse(headers["LOCKAGE"], out v))
                {
                    try
                    {
                        lockAge = new TimeSpan(0,0,v);
                    }
                    catch
                    {
                        lockAge = null;
                    }
                }
            }

            id = Guid.Empty;
            if (headers["X-ID"] != null)
            {
                try
                {
                    id = new Guid(headers["X-ID"]);
                }
                catch
                {
                    id = Guid.Empty;
                }

            }

            //Validate
            if (!isError)
            {
                //This message requires a resource + modified date
                if (verb.Resource == string.Empty || lastModified == DateTime.MinValue)
                {
                    isError = true;
                }

                //Lockdate + LockCookie + LockAge must be set if any is set
                if ((((lockDate == null) && (lockCookie == null) && (lockAge == null)) ^
                    ((lockDate == null) || (lockCookie == null) || (lockAge == null))) == true)
                {
                    isError = true;
                }

                //LockCookie must be valid
                if (lockCookie.HasValue && LockCookie.Value > MAX_LockCookieValue) isError = true;

                //ID must be present
                if (id == Guid.Empty) isError = true;
            }
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the UnauthorizedResponse class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public UnauthorizedResponse(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            string www_auth = headers["WWW-AUTHENTICATE"];

            if (www_auth != null)
            {
                //Split comma-delimited directives
                string[] directives = www_auth.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                //first check for and remove 'Digest' from the first line
                if (directives.Length > 0 && directives[0].Trim().ToUpperInvariant().StartsWith("DIGEST"))
                {
                    directives[0] = directives[0].Trim().Substring(6); //remove digest word

                    //Read realm, qop and nonce
                    foreach (string line in directives)
                    {
                        string key, value;
                        GetKeyValue(line, '=', out key, out value);

                        switch(key.ToUpperInvariant().Trim())
                        {
                            case "REALM":
                                realm = Unquote( value).Trim();
                                break;

                            case "QOP":
                                qop = Unquote( value).Trim();
                                break;

                            case "NONCE":
                                nonce = Unquote( value).Trim();
                                if (!IsValidBase64(nonce)) nonce = null;
                                break;
                        }

                    }

                }

            }

            //Validate
            if (!isError)
            {
                //This message requires an empty content-length, qop, nonce and realm
                if (body.Length != 0 || qop == null || nonce == null || realm == null)
                {
                    isError = true;
                }
            }
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the ServiceUnavailableResponse class
 /// </summary>
 /// <param name="Data">The HTTPPartialData to create object from</param>
 /// <param name="Service">State server instance</param>
 public ServiceUnavailableResponse(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
     //Validate
     if (!isError)
     {
         //This message requires an empty content length
         if (body.Length != 0)
         {
             isError = true;
         }
     }
 }
Example #4
0
        /// <summary>
        /// Initializes a new instance of the SetRequest class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public SetRequest(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            if (lockCookie == null) lockCookie = 0; //set 0 as default lock-cookie value

            //Validate
            if (!isError)
            {
                //This message requires a resource and a lock cookie
                if (verb.Resource == string.Empty || lockCookie == null )
                {
                    isError = true;
                }
            }
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the HTTPMessage class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public HTTPMessage(HTTPPartialData HTTPData)
        {
            if (HTTPData.IsError)
            {
                throw new ArgumentException("HTTP Partial data has an error", "HTTPData");
            }

            if (!HTTPData.IsComplete)
            {
                throw new ArgumentException("HTTP Partial data is not complete", "HTTPData");
            }

            socket = HTTPData.HandlerSocket;
            byte[][] lines = HTTPData.Lines;

            if (lines.Length == 0)
            {
                isError = true;
            }
            else
            {
                requestStatusLine = Encoding.UTF8.GetString(lines[0], 0, lines[0].Length - 2); //compensate for CRLF
            }

            //Get HTTP Method Information
            try
            {
                verb = new HTTPMethod(requestStatusLine);
            }
            catch
            {
                isError = true;
                verb = null;
            }

            //Get Headers
            for (int i = 1; i < lines.Length; i++)
            {
                byte[] line = lines[i];
                if (line.Length > 2) //skip CRLF-only lines
                {
                    int index = Array.IndexOf(line, (byte)58);//':' character

                    if (index < 1)
                    {
                        isError = true;
                        continue;
                    }

                    string name = Encoding.UTF8.GetString(line, 0, index);
                    string value = string.Empty;

                    if (index < (line.Length - 3)) //compensate for CR and LF
                    {
                        value = Encoding.UTF8.GetString(line, index + 1, line.Length - (index + 3));
                    }

                    headers.Add(name.Trim().ToUpperInvariant(), value.Trim());
                }

            }

            //Get Body Data
            body = HTTPData.Content == null ? new byte[0] { } : HTTPData.Content;

            //Pickup Host
            host = headers["HOST"];
            if (host == null && verb.Type == HTTPMessageType.Request)
            {
                isError = true;
            }

            //look for Content-Length and compare it with body length

            string cLen = headers["CONTENT-LENGTH"] ;
            if (cLen == null || cLen.Trim() == string.Empty)
            {
                if (body.Length != 0) isError = true;
            }
            else
            {
                int v;
                if (int.TryParse(cLen, out v))
                {
                    if (v != body.Length) isError = true;
                }
                else
                {
                    isError = true;
                }

            }
        }
Example #6
0
        /// <summary>
        /// Initializes a new instance of the ServiceResponse class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public ServiceResponse(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            actionFlags = headers["ACTIONFLAGS"];
            aspNetVersion = headers["X-ASPNET-VERSION"];

            assocID = null;
            if (headers["X-ASSOC-ID"] != null)
            {
                try
                {
                    assocID = new Guid(headers["X-ASSOC-ID"]);
                }
                catch
                {
                    assocID = null;
                }

            }
        }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the ServiceMessage class
        /// </summary>
        /// <param name="HTTPData">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public ServiceMessage(HTTPPartialData HTTPData, StateServer Service)
            : base(HTTPData)
        {
            service = Service;

            //Get other information
            timeout = null;

            if (headers["TIMEOUT"] != null)
            {
                int v;
                int.TryParse(headers["TIMEOUT"], out v);
                timeout = v;
            }

            lockCookie = null;
            if (headers["LOCKCOOKIE"] != null)
            {
                uint v;
                uint.TryParse(headers["LOCKCOOKIE"], out v);
                lockCookie = v;
            }

            int plainTextSize = -1;
            bool encrypted  = false;
            if (headers["CONTENT-TYPE"] != null)
            {
                string[] directives = headers["CONTENT-TYPE"].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                if(directives[0].Trim().ToUpperInvariant() == @"APPLICATION/X-ENCRYPTED") encrypted = true;
                foreach (string directive in directives)
                {
                    if (directive.Trim().ToUpperInvariant().StartsWith("PLAINTEXT-LENGTH"))
                    {
                        if (!int.TryParse(directive.Trim().Substring(16).Replace("=", string.Empty).Trim(), out plainTextSize))
                        {
                            isError = true;
                        }
                    }
                }

                if(encrypted && plainTextSize < 0) isError = true;
            }

            if (!isError)
            {
                if (socket.IsAuthenticated && service.Settings.EncryptPeerData)
                {
                    if (body.Length > 0 )
                    {
                        if (!encrypted)
                        {
                            Diags.LogMessageUnprotectedError(this);
                            isError = true;
                        }
                        else
                        {
                            try
                            {
                                body = service.Authenticator.Unprotect(body, socket.SessionKey, plainTextSize);
                            }
                            catch (Exception ex)
                            {
                                Diags.LogMessageContentCipherError(this, ex);
                                isError = true;
                            }

                        }
                    }
                }
                else
                {
                    if (encrypted)
                    {
                        Diags.LogMessageProtectedError(this);
                        isError = true;
                    }
                }
            }
        }
Example #8
0
 //short exportCount = 0;
 /// <summary>
 /// Initializes a new instance of the GetRequest class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public GetRequest(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
     //Validate
     if (!isError)
     {
         //This message requires a resource
         if (verb.Resource == string.Empty)
         {
             isError = true;
         }
     }
 }
Example #9
0
 /// <summary>
 /// Initializes a new instance of the PingReplyMessage class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public PingReplyMessage(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
 }
Example #10
0
 //short exportCount = 0;
 /// <summary>
 /// Initializes a new instance of the ReleaseExclusiveRequest class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public ReleaseExclusiveRequest(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
     //Validate
     if (!isError)
     {
         //This message requires a resource and a lock cookie
         if (verb.Resource == string.Empty || lockCookie == null )
         {
             isError = true;
         }
     }
 }
Example #11
0
        /// <summary>
        /// Initializes a new instance of the PeerMessage class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public PeerMessage(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            maxForwards = null;
            if (headers["MAX-FORWARDS"] != null)
            {
                uint v;
                uint.TryParse(headers["MAX-FORWARDS"], out v);
                maxForwards = v;
            }

            id = null;
            if (headers["X-ID"] != null)
            {
                try
                {
                    id = new Guid(headers["X-ID"]);
                }
                catch
                {
                    id = null;
                }

            }

            if (headers["X-BROADCAST-ID"] != null)
            {
                try
                {
                    broadcastID = new Guid(headers["X-BROADCAST-ID"].Trim());
                }
                catch
                { isError = true; }
            }
            else
            {
                broadcastID = Guid.Empty;
            }
        }
Example #12
0
        /// <summary>
        /// Initializes a new instance of the OKResponse class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public OKResponse(HTTPPartialData Data, StateServer Service)
            : base(Data,Service)
        {
            string auth_info = headers["AUTHENTICATION-INFO"];

            if (auth_info != null)
            {
                //Split comma-delimited directives
                string[] directives = auth_info.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                //Read rspauth, qop, cnonce and ncount
                foreach (string line in directives)
                {

                    string key, value;
                    GetKeyValue(line, '=', out key, out value);

                    switch (key.ToUpperInvariant().Trim())
                    {
                        case "RSPAUTH":
                            authInfo_rspauth = Unquote(value).Trim();
                            if (!IsValidBase64(authInfo_rspauth)) authInfo_rspauth = null;
                            break;

                        case "QOP":
                            authInfo_qop = Unquote(value).Trim();
                            break;

                        case "CNONCE":
                            authInfo_cnonce = Unquote(value).Trim();
                            if (!IsValidBase64(authInfo_cnonce)) authInfo_cnonce = null;
                            break;

                        case "NC":
                            Int32.TryParse(Unquote(value), System.Globalization.NumberStyles.HexNumber, null, out authInfo_ncount);
                            break;
                    }

                }

            }

            //Validate
            if (!isError)
            {
                //If there is an authentication-info header and the rspauth, qop, or cnonce directive is missing,
                //then there is an error.
                if (auth_info != null && (authInfo_rspauth == null || authInfo_cnonce == null || authInfo_qop == null))
                {
                    isError = true;
                }
            }
        }
Example #13
0
 /// <summary>
 /// Initializes a new instance of the BeginAuthRequest class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public BeginAuthRequest(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
 }
Example #14
0
 /// <summary>
 /// Initializes a new instance of the UnknownResponse class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public UnknownResponse(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
 }
Example #15
0
        /// <summary>
        /// Initializes a new instance of the CompleteAuthRequest class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public CompleteAuthRequest(HTTPPartialData Data, StateServer Service)
            : base(Data, Service)
        {
            string www_auth = headers["AUTHORIZATION"];

            if (www_auth != null)
            {
                //Split comma-delimited directives
                string[] directives = www_auth.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                //first check for and remove 'Digest' from the first line
                if (directives.Length > 0 && directives[0].Trim().ToUpperInvariant().StartsWith("DIGEST"))
                {
                    directives[0] = directives[0].Trim().Substring(6); //remove digest word

                    //Read realm, qop and nonce
                    foreach (string line in directives)
                    {
                        string key, value;
                        GetKeyValue(line, '=', out key, out value);

                        switch (key.ToUpperInvariant().Trim())
                        {
                            case "USERNAME":
                                username = Unquote(value).Trim();
                                break;

                            case "REALM":
                                realm = Unquote(value).Trim();
                                break;

                            case "QOP":
                                qop = Unquote(value).Trim();
                                break;

                            case "NONCE":
                                nonce = Unquote(value).Trim();
                                if (!IsValidBase64(nonce)) nonce = null;
                                break;

                            case "CNONCE":
                                cnonce = Unquote(value).Trim();
                                if (!IsValidBase64(cnonce)) cnonce = null;
                                break;

                            case "URI":
                                uri = Unquote(value);
                                break;

                            case "RESPONSE":
                                response = Unquote(value).Trim();
                                if (!IsValidBase64(response)) response = null;
                                break;

                            case "NC":
                                Int32.TryParse(Unquote(value),System.Globalization.NumberStyles.HexNumber,null, out ncount);
                                break;

                            case "ALGORITHM":
                                algorithm = Unquote(value).Trim();
                                break;

                        }

                    }

                }

            }

            //Validate
            if (!isError)
            {
                //This message requires username, realm, qop, nonce, cnonce, response and uri
                if (username == null || qop == null || nonce == null || cnonce == null || realm == null || response == null || uri == null)
                {
                    isError = true;
                }
            }
        }
Example #16
0
 /// <summary>
 /// Initializes a new instance of the BadMessage class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public BadMessage(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
 }
Example #17
0
        /// <summary>
        /// Initializes a new instance of the ServiceRequest class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public ServiceRequest(HTTPPartialData Data, StateServer Service)
            : base(Data,Service)
        {
            extraFlags = headers["EXTRAFLAGS"];

            //ExtraFlags only accepts 0 and 1 -- if any other value is set, set it to null
            if (extraFlags != null)
            {
                extraFlags = extraFlags.Trim();
                if (extraFlags != "0" && extraFlags != "1")
                {
                    extraFlags = null;
                }
            }
        }
Example #18
0
 /// <summary>
 /// Initializes a new instance of the GetTransferMessage class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public GetTransferMessage(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
     //Validate
     if (!isError)
     {
         //This message requires a resource, a maxForwards and an ID
         if (verb.Resource == string.Empty || maxForwards == null || id == null)
         {
             isError = true;
         }
     }
 }
Example #19
0
 /// <summary>
 /// Initializes a new instance of the BadRequestResponse class
 /// </summary>
 /// <param name="Data">The HTTPPartialData class to load this instance from</param>
 /// <param name="Service">State server instance</param>
 public BadRequestResponse(HTTPPartialData Data, StateServer Service)
     : base(Data, Service)
 {
     //No Validation required
 }