private void sendResponse() { logger.Debug("{0} send response", _connectionToken.Substring(0, 6)); //send response _workStatus = SessionWorkStatus.SendingResponseHeader; //append connection header if need if (_clientKeepAlive && !_serverKeepAlive) { _lastResponseHeader.Connection = "close"; } if (_lastProcessor.ResponseBodyLength > 0) { //send response with body _session.Send(_lastResponseHeader, _lastProcessor.ResponseBodyLength); } else if (_lastProcessor.ResponseBodyLength == 0) { //send response header only _session.Send(_lastResponseHeader); } else { //NOTE:: //send response in "chunked" transfer encoding mode(with unknow body length) _session.Send(_lastResponseHeader, long.MaxValue); } }
/// <summary> /// Start session and enter receiving request status /// </summary> public void StartSession() { //start receive request _workStatus = SessionWorkStatus.ReceivingRequestHeader; HttpRequestHeader requestHeader = new HttpRequestHeader(); _session.Receive(requestHeader, _bodyBuffer, 0, _bodyBuffer.Length); }
private void processRequest(ReceiveHeaderCompleteEventArgs e) { logger.Debug("{0} process request", _connectionToken.Substring(0, 6)); if (_lastProcessor != null) { _lastProcessor.Close(); } HttpRequestHeader requestHeader = (HttpRequestHeader)e.LastReceiveHeader; logger.Debug("{0} receive new request: {1}, url: {2}", _connectionToken.Substring(0, 6), requestHeader.Method, requestHeader.Url); //check if keep connection alive _clientKeepAlive = (requestHeader.Connection == null || String.Compare(requestHeader.Connection, "keep-alive", true) == 0); _lastResponseHeader = new HttpResponseHeader(); _lastResponseHeader.Date = DateTime.Now.ToUniversalTime(); _lastResponseHeader.Server = HttpServiceControler.SERVER_NAME; HandlerContext context = new HandlerContext( requestHeader, _lastResponseHeader, _bindEndPoint, _bindEndPointName, _clientIp, _connectionToken); _lastProcessor = _processorFactory.CreateProcessor(context); _lastProcessor.ProcessRequest(context); //request contains body if (requestHeader.ContentLength > 0) { if (_lastProcessor.RequestBodyAcceptable) { //continue to receive reqeust body _workStatus = SessionWorkStatus.ReceivingRequestBody; e.TotalPlanReceivingLength = requestHeader.ContentLength; } else { //NOTE:: //can not accept request body, because //some http method (GET,HEAD,DELETE) should not contain request body //or POST,PUT access deny. logger.Warn("{0} processor {1} can not accept request body", _connectionToken.Substring(0, 6), _lastProcessor.GetType().Name); Close(); } } else { sendResponse(); } }
private void session_SendComplete(object sender, SendCompleteEventArgs e) { logger.Debug("{0} response sent.", _connectionToken.Substring(0, 6)); _lastActiveTime = DateTime.Now; if (_lastProcessor.ResponseBodyLength != 0) { int length = 0; byte[] buffer; int offset; try { length = _lastProcessor.SubmitResponseBody( out buffer, out offset); } catch (Exception ex) { //exception occur while get response body from processer logger.Warn("{0} exception occur while get response body from processer {1}, message: {2}", _connectionToken.Substring(0, 6), _lastProcessor.GetType().Name, ex.Message); Close(); return; } if (length > 0) { _workStatus = SessionWorkStatus.SendingResponseBody; _session.ContinueSendingBody(buffer, offset, length); return; } } //close session if does not keep alive //NOTE::Let client to close the connection, otherwise, server will //generate lots of TIME_WAIT sockets ////if (!_serverKeepAlive) ////{ //// Close(); ////} ////else ////{ //continue receive next request _workStatus = SessionWorkStatus.ReceivingRequestHeader; HttpRequestHeader requestHeader = new HttpRequestHeader(); _session.Receive(requestHeader, _bodyBuffer, 0, _bodyBuffer.Length); ////} }
private void session_ReceiveBodyComplete(object sender, ReceiveBodyCompleteEventArgs e) { logger.Debug("{0} receive body complete", _connectionToken.Substring(0, 6)); _lastActiveTime = DateTime.Now; _workStatus = SessionWorkStatus.Busy; try { _lastProcessor.RequestBodyArrival(e.Data, e.DataLength); if (e.TotalHasReceivedLength >= e.TotalPlanReceivingLength) { //all body receive complete _lastProcessor.AllRequestBodyReceived(); } } catch (Exception ex) { //exception occur while append request body to handler, //only PUT and POST will occur. logger.Warn("{0} append request to processor {1} body error: {2}", _connectionToken.Substring(0, 6), _lastProcessor.GetType().Name, ex.Message); Close(); return; } if (e.TotalHasReceivedLength >= e.TotalPlanReceivingLength) { //handle complete, send response sendResponse(); } else { //continue to receive body _workStatus = SessionWorkStatus.ReceivingRequestBody; _session.ContinueReceivingBody(_bodyBuffer, 0, _bodyBuffer.Length); } }
private void session_ReceiveHeaderComplete(object sender, ReceiveHeaderCompleteEventArgs e) { logger.Debug("{0} receive header complete", _connectionToken.Substring(0, 6)); _lastActiveTime = DateTime.Now; _workStatus = SessionWorkStatus.Busy; try { processRequest(e); } catch (Exception ex) { HttpRequestHeader request = (HttpRequestHeader)e.LastReceiveHeader; //for debug logger.Error("{0} unhandle exception occur while processing request: \r\n{1}:{2}\r\n{3}", _connectionToken.Substring(0, 6), request.Method, request.Url, ex.Message); Close(); } }