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) { } }
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); }
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; }
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; }