예제 #1
0
        private void AcceptClient(IAsyncResult ar)
        {
            try
            {
                using (HTTPServerSession session = new HTTPServerSession(_socket.EndAccept(ar), _params))
                {
                    ManualResetEvent evt = ar.AsyncState as ManualResetEvent;
                    evt.Set();

                    while (session.HasMoreRequests)
                    {
                        try
                        {
                            HTTPServerResponse response = new HTTPServerResponse(session);
                            HTTPServerRequest  request  = new HTTPServerRequest(session);

                            response.Version   = request.Version;
                            response.KeepAlive = session.CanKeepAlive && request.KeepAlive && _params.KeepAlive;

                            try
                            {
                                IHTTPRequestHandler handler = _factory.CreateRequestHandler(request);
                                if (handler != null)
                                {
                                    if (request.ExpectsContinue)
                                    {
                                        response.SendContinue();
                                    }

                                    handler.HandleRequest(request, response);
                                    session.KeepAlive = response.KeepAlive && session.CanKeepAlive && _params.KeepAlive;
                                }
                                else
                                {
                                    SendErrorResponse(session, HTTPServerResponse.HTTPStatus.HTTP_NOT_IMPLEMENTED);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (!response.Sent)
                                {
                                    SendErrorResponse(session, HTTPServerResponse.HTTPStatus.HTTP_INTERNAL_SERVER_ERROR);
                                }

                                OnServerException(ex);
                                break;
                            }
                        }
                        catch (HTTPNoMessageException) { break; }
                        catch (HTTPMessageException)
                        {
                            SendErrorResponse(session, HTTPServerResponse.HTTPStatus.HTTP_BAD_REQUEST);
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            { }
        }
예제 #2
0
        protected override void Dispose(bool disposing)
        {
            LastProcessedUri = null;
            if (this.State != HTTPConnectionStates.WaitForProtocolShutdown)
            {
                if (this.connector != null)
                {
                    try
                    {
                        this.connector.Close();
                    }
                    catch
                    { }
                    this.connector = null;
                }

                if (this.requestHandler != null)
                {
                    try
                    {
                        this.requestHandler.Dispose();
                    }
                    catch
                    { }
                    this.requestHandler = null;
                }
            }
            else
            {
                // We have to connector to do not close its stream at any cost while disposing.
                // All references to this connection will be removed, so this and the connector may be finalized after some time.
                // But, finalizing (and disposing) the connector while the protocol is still active would be fatal,
                //  so we have to make sure that it will not happen. This also means that the protocol has the responsibility (as always had)
                //  to close the stream and TCP connection properly.
                if (this.connector != null)
                {
                    this.connector.LeaveOpen = true;
                }
            }

            base.Dispose(disposing);
        }
예제 #3
0
        protected override void ThreadFunc()
        {
            if (this.CurrentRequest.IsRedirected)
            {
                this.CurrentRequest.Timing.Add(TimingEventNames.Queued_For_Redirection);
            }
            else
            {
                this.CurrentRequest.Timing.Add(TimingEventNames.Queued);
            }

            if (this.connector != null && !this.connector.IsConnected)
            {
                // this will send the request back to the queue
                RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(CurrentRequest, RequestEvents.Resend));
                ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
                return;
            }

            if (this.connector == null)
            {
                this.connector = new Connections.TCPConnector();

                try
                {
                    this.connector.Connect(this.CurrentRequest);
                }
                catch (Exception ex)
                {
                    if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                    {
                        HTTPManager.Logger.Exception("HTTPConnection", "Connector.Connect", ex, this.Context, this.CurrentRequest.Context);
                    }


                    if (ex is TimeoutException)
                    {
                        this.CurrentRequest.State = HTTPRequestStates.ConnectionTimedOut;
                    }
                    else if (!this.CurrentRequest.IsTimedOut) // Do nothing here if Abort() got called on the request, its State is already set.
                    {
                        this.CurrentRequest.Exception = ex;
                        this.CurrentRequest.State     = HTTPRequestStates.Error;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));

                    return;
                }

#if !NETFX_CORE
                // data sending is buffered for all protocols, so when we put data into the socket we want to send them asap
                this.connector.Client.NoDelay = true;
#endif
                StartTime = DateTime.UtcNow;

                HTTPManager.Logger.Information("HTTPConnection", "Negotiated protocol through ALPN: '" + this.connector.NegotiatedProtocol + "'", this.Context, this.CurrentRequest.Context);

                switch (this.connector.NegotiatedProtocol)
                {
                case HTTPProtocolFactory.W3C_HTTP1:
                    this.requestHandler = new Connections.HTTP1Handler(this);
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HostProtocolSupport.HTTP1));
                    break;

#if (!UNITY_WEBGL || UNITY_EDITOR) && !BESTHTTP_DISABLE_ALTERNATE_SSL && !BESTHTTP_DISABLE_HTTP2
                case HTTPProtocolFactory.W3C_HTTP2:
                    this.requestHandler = new Connections.HTTP2.HTTP2Handler(this);
                    this.CurrentRequest = null;
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HostProtocolSupport.HTTP2));
                    break;
#endif

                default:
                    HTTPManager.Logger.Error("HTTPConnection", "Unknown negotiated protocol: " + this.connector.NegotiatedProtocol, this.Context, this.CurrentRequest.Context);

                    RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(CurrentRequest, RequestEvents.Resend));
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
                    return;
                }
            }

            this.requestHandler.Context.Add("Connection", this.GetHashCode());
            this.Context.Add("RequestHandler", this.requestHandler.GetHashCode());

            this.requestHandler.RunHandler();
            LastProcessTime = DateTime.Now;
        }
 /// <summary>
 /// 初始化CastleServiceHandler
 /// </summary>
 /// <param name="handler"></param>
 public HttpRequestHandlerFactory(IHTTPRequestHandler handler)
 {
     this.handler = handler;
 }
 /// <summary>
 /// 初始化CastleServiceHandler
 /// </summary>
 /// <param name="handler"></param>
 public HttpRequestHandlerFactory(IHTTPRequestHandler handler)
 {
     this.handler = handler;
 }
예제 #6
0
        protected override void ThreadFunc()
        {
            if (this.connector != null && !this.connector.IsConnected)
            {
                // this will semd the request back to the queue
                RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(CurrentRequest, RequestEvents.Resend));
                ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
                return;
            }

            if (this.connector == null)
            {
                this.connector = new Connections.TCPConnector();

                try
                {
                    this.connector.Connect(this.CurrentRequest);
                }
                catch (Exception ex)
                {
                    HTTPManager.Logger.Exception("HTTPConnection", "Connector.Connect", ex);

                    this.CurrentRequest.State = HTTPRequestStates.ConnectionTimedOut;
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));

                    return;
                }

#if !NETFX_CORE
                // data sending is buffered for all protocols, so when we put data into the socket we want to send them asap
                this.connector.Client.NoDelay = true;
#endif
                StartTime = DateTime.UtcNow;

                HTTPManager.Logger.Information("HTTPConnection", "Negotiated protocol through ALPN: '" + this.connector.NegotiatedProtocol + "'");

                switch (this.connector.NegotiatedProtocol)
                {
                case HTTPProtocolFactory.W3C_HTTP1:
                    this.requestHandler = new Connections.HTTP1Handler(this);
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HostProtocolSupport.HTTP1));
                    break;

#if (!UNITY_WEBGL || UNITY_EDITOR) && !BESTHTTP_DISABLE_ALTERNATE_SSL && !BESTHTTP_DISABLE_HTTP2
                case HTTPProtocolFactory.W3C_HTTP2:
                    this.requestHandler = new Connections.HTTP2.HTTP2Handler(this);
                    this.CurrentRequest = null;
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HostProtocolSupport.HTTP2));
                    break;
#endif

                default:
                    HTTPManager.Logger.Error("HTTPConnection", "Unknown negotiated protocol: " + this.connector.NegotiatedProtocol);
                    RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(CurrentRequest, RequestEvents.Resend));
                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
                    return;
                }
            }

            this.requestHandler.RunHandler();
            LastProcessTime = DateTime.Now;
        }