Beispiel #1
0
        internal System.IO.Stream GetSaveStream(HTTPResponse response)
        {
            if (!HTTPCacheService.IsSupported)
            {
                return(null);
            }

            LastAccess = DateTime.UtcNow;

            string path = GetPath();

            if (HTTPManager.IOService.FileExists(path))
            {
                Delete();
            }

            // Path name too long, we don't want to get exceptions
            if (path.Length > HTTPManager.MaxPathLength)
            {
                return(null);
            }

            // First write out the headers
            using (Stream writer = HTTPManager.IOService.CreateFileStream(GetPath(), FileStreamModes.Create))
            {
                writer.WriteLine("HTTP/1.1 {0} {1}", response.StatusCode, response.Message);
                foreach (var kvp in response.Headers)
                {
                    for (int i = 0; i < kvp.Value.Count; ++i)
                    {
                        writer.WriteLine("{0}: {1}", kvp.Key, kvp.Value[i]);
                    }
                }

                writer.WriteLine();
            }

            // If caching is enabled and the response is from cache, and no content-length header set, then we set one to the response.
            if (response.IsFromCache && !response.HasHeader("content-length"))
            {
                response.AddHeader("content-length", BodyLength.ToString());
            }

            SetUpCachingValues(response);

            // then create the stream with Append FileMode
            return(HTTPManager.IOService.CreateFileStream(GetPath(), FileStreamModes.Append));
        }
Beispiel #2
0
        private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
        {
            if (State != States.Closed)
            {
                if (State == States.Closing || req.State == HTTPRequestStates.Aborted)
                {
                    SetClosed("OnRequestFinished");
                }
                else
                {
                    string text = string.Empty;
                    bool   flag = true;
                    switch (req.State)
                    {
                    case HTTPRequestStates.Processing:
                        flag = !resp.HasHeader("content-length");
                        break;

                    case HTTPRequestStates.Finished:
                        if (resp.StatusCode == 200 && !resp.HasHeaderWithValue("content-type", "text/event-stream"))
                        {
                            text = "No Content-Type header with value 'text/event-stream' present.";
                            flag = false;
                        }
                        if (flag && resp.StatusCode != 500 && resp.StatusCode != 502 && resp.StatusCode != 503 && resp.StatusCode != 504)
                        {
                            flag = false;
                            text = $"Request Finished Successfully, but the server sent an error. Status Code: {resp.StatusCode}-{resp.Message} Message: {resp.DataAsText}";
                        }
                        break;

                    case HTTPRequestStates.Error:
                        text = "Request Finished with Error! " + ((req.Exception == null) ? "No Exception" : (req.Exception.Message + "\n" + req.Exception.StackTrace));
                        break;

                    case HTTPRequestStates.Aborted:
                        text = "OnRequestFinished - Aborted without request. EventSource's State: " + State;
                        break;

                    case HTTPRequestStates.ConnectionTimedOut:
                        text = "Connection Timed Out!";
                        break;

                    case HTTPRequestStates.TimedOut:
                        text = "Processing the request Timed Out!";
                        break;
                    }
                    if (State < States.Closing)
                    {
                        if (!string.IsNullOrEmpty(text))
                        {
                            CallOnError(text, "OnRequestFinished");
                        }
                        if (flag)
                        {
                            Retry();
                        }
                        else
                        {
                            SetClosed("OnRequestFinished");
                        }
                    }
                    else
                    {
                        SetClosed("OnRequestFinished");
                    }
                }
            }
        }
Beispiel #3
0
        private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
        {
            if (this.State == States.Closed)
            {
                return;
            }

            if (this.State == States.Closing ||
                req.State == HTTPRequestStates.Aborted)
            {
                SetClosed("OnRequestFinished");

                return;
            }

            string reason = string.Empty;

            // In some cases retry is prohibited
            bool canRetry = true;

            switch (req.State)
            {
            // The server sent all the data it's wanted.
            case HTTPRequestStates.Processing:
                canRetry = !resp.HasHeader("content-length");
                break;

            // The request finished without any problem.
            case HTTPRequestStates.Finished:
                // HTTP 200 OK responses that have a Content-Type specifying an unsupported type, or that have no Content-Type at all, must cause the user agent to fail the connection.
                if (resp.StatusCode == 200 && !resp.HasHeaderWithValue("content-type", "text/event-stream"))
                {
                    reason   = "No Content-Type header with value 'text/event-stream' present.";
                    canRetry = false;
                }

                // HTTP 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, and 504 Gateway Timeout responses, and any network error that prevents the connection
                //  from being established in the first place (e.g. DNS errors), must cause the user agent to asynchronously reestablish the connection.
                // Any other HTTP response code not listed here must cause the user agent to fail the connection.
                if (canRetry &&
                    resp.StatusCode != 500 &&
                    resp.StatusCode != 502 &&
                    resp.StatusCode != 503 &&
                    resp.StatusCode != 504)
                {
                    canRetry = false;

                    reason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
                                           resp.StatusCode,
                                           resp.Message,
                                           resp.DataAsText);
                }
                break;

            // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
            case HTTPRequestStates.Error:
                reason = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception");
                break;

            // The request aborted, initiated by the user.
            case HTTPRequestStates.Aborted:
                // If the state is Closing, then it's a normal behaviour, and we close the EventSource
                reason = "OnRequestFinished - Aborted without request. EventSource's State: " + this.State;
                break;

            // Connecting to the server is timed out.
            case HTTPRequestStates.ConnectionTimedOut:
                reason = "Connection Timed Out!";
                break;

            // The request didn't finished in the given time.
            case HTTPRequestStates.TimedOut:
                reason = "Processing the request Timed Out!";
                break;
            }

            // If we are not closing the EventSource, then we will try to reconnect.
            if (this.State < States.Closing)
            {
                if (!string.IsNullOrEmpty(reason))
                {
                    CallOnError(reason, "OnRequestFinished");
                }

                if (canRetry)
                {
                    Retry();
                }
                else
                {
                    SetClosed("OnRequestFinished");
                }
            }
            else
            {
                SetClosed("OnRequestFinished");
            }
        }
        private void OnInternalRequestUpgraded(HTTPRequest req, HTTPResponse resp)
        {
            HTTPManager.Logger.Information("WebSocket", "Internal request upgraded!", this.Context);
            webSocket = resp as WebSocketResponse;

            if (webSocket == null)
            {
                if (OnError != null)
                {
                    string reason = string.Empty;
                    if (req.Exception != null)
                    {
                        reason = req.Exception.Message + " " + req.Exception.StackTrace;
                    }

                    OnError(this, reason);
                }

                this.State = WebSocketStates.Closed;
                return;
            }

            // If Close called while we connected
            if (this.State == WebSocketStates.Closed)
            {
                webSocket.CloseStream();
                return;
            }

            if (!resp.HasHeader("sec-websocket-accept"))
            {
                this.State = WebSocketStates.Closed;
                webSocket.CloseStream();

                if (OnError != null)
                {
                    OnError(this, "No Sec-Websocket-Accept header is sent by the server!");
                }
                return;
            }

            webSocket.WebSocket = this;

            if (this.Extensions != null)
            {
                for (int i = 0; i < this.Extensions.Length; ++i)
                {
                    var ext = this.Extensions[i];

                    try
                    {
                        if (ext != null && !ext.ParseNegotiation(webSocket))
                        {
                            this.Extensions[i] = null; // Keep extensions only that successfully negotiated
                        }
                    }
                    catch (Exception ex)
                    {
                        HTTPManager.Logger.Exception("WebSocket", "ParseNegotiation", ex, this.Context);

                        // Do not try to use a defective extension in the future
                        this.Extensions[i] = null;
                    }
                }
            }

            this.State = WebSocketStates.Open;
            if (OnOpen != null)
            {
                try
                {
                    OnOpen(this);
                }
                catch (Exception ex)
                {
                    HTTPManager.Logger.Exception("WebSocket", "OnOpen", ex, this.Context);
                }
            }

            webSocket.OnText = (ws, msg) =>
            {
                if (OnMessage != null)
                {
                    OnMessage(this, msg);
                }
            };

            webSocket.OnBinary = (ws, bin) =>
            {
                if (OnBinary != null)
                {
                    OnBinary(this, bin);
                }
            };

            webSocket.OnClosed = (ws, code, msg) =>
            {
                this.State = WebSocketStates.Closed;

                if (OnClosed != null)
                {
                    OnClosed(this, code, msg);
                }
            };

            if (OnIncompleteFrame != null)
            {
                webSocket.OnIncompleteFrame = (ws, frame) =>
                {
                    if (OnIncompleteFrame != null)
                    {
                        OnIncompleteFrame(this, frame);
                    }
                }
            }
            ;

            if (StartPingThread)
            {
                webSocket.StartPinging(Math.Max(PingFrequency, 100));
            }

            webSocket.StartReceive();
        }
Beispiel #5
0
        private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
        {
            if (this.State == States.Closed)
                return;

            if (this.State == States.Closing)
            {
                SetClosed("OnRequestFinished");

                return;
            }

            string reason = string.Empty;

            // In some cases retry is prohibited
            bool canRetry = true;

            switch (req.State)
            {
                // The server sent all the data it's wanted.
                case HTTPRequestStates.Processing:
                    canRetry = !resp.HasHeader("content-length");
                    break;

                // The request finished without any problem.
                case HTTPRequestStates.Finished:
                    // HTTP 200 OK responses that have a Content-Type specifying an unsupported type, or that have no Content-Type at all, must cause the user agent to fail the connection.
                    if (resp.StatusCode == 200 && !resp.HasHeaderWithValue("content-type", "text/event-stream"))
                    {
                        reason = "No Content-Type header with value 'text/event-stream' present.";
                        canRetry = false;
                    }

                    // HTTP 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, and 504 Gateway Timeout responses, and any network error that prevents the connection 
                    //  from being established in the first place (e.g. DNS errors), must cause the user agent to asynchronously reestablish the connection.
                    // Any other HTTP response code not listed here must cause the user agent to fail the connection.
                    if (canRetry &&
                        resp.StatusCode != 500 &&
                        resp.StatusCode != 502 &&
                        resp.StatusCode != 503 &&
                        resp.StatusCode != 504)
                    {
                        canRetry = false;

                        reason = string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
                                                        resp.StatusCode,
                                                        resp.Message,
                                                        resp.DataAsText);
                    }
                    break;

                // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
                case HTTPRequestStates.Error:
                    reason = "Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception");
                    break;

                // The request aborted, initiated by the user.
                case HTTPRequestStates.Aborted:
                    // If the state is Closing, then it's a normal behaviour, and we close the EventSource
                    reason = "OnRequestFinished - Aborted without request. EventSource's State: " + this.State;
                    break;

                // Ceonnecting to the server is timed out.
                case HTTPRequestStates.ConnectionTimedOut:
                    reason = "Connection Timed Out!";
                    break;

                // The request didn't finished in the given time.
                case HTTPRequestStates.TimedOut:
                    reason = "Processing the request Timed Out!";
                    break;
            }

            // If we are not closing the EventSource, then we will try to reconnect.
            if (this.State < States.Closing)
            {
                if (!string.IsNullOrEmpty(reason))
                    CallOnError(reason, "OnRequestFinished");

                if (canRetry)
                    Retry();
                else
                    SetClosed("OnRequestFinished");
            }
            else
                SetClosed("OnRequestFinished");
        }