public async virtual Task <bool> ProcessRequest(HttpContext httpContext) { IHttpHandler handler = ResolveHandler(httpContext); // no handler found if (handler == null) { httpContext.Response.StatusCode = HttpStatusCode.NotFound; return(false); } else { // process request by handler if (handler.CanProcessRequest(httpContext)) { return(await handler.ProcessRequest(httpContext)); } else { httpContext.Response.StatusCode = HttpStatusCode.MethodNotAllowed; httpContext.Response.Body = null; } } return(false); }
private async void ProcessRequestAsync(TcpClient requestClient) { HttpRequest httpRequest = null; bool badRequest = false; try { // parse incoming request httpRequest = await HttpRequest.ParseAsync(requestClient); } catch { // error parsing incoming request (bad request) httpRequest = new HttpRequest(); badRequest = true; } // create an HTTP context for the current request var httpContext = new HttpContext(httpRequest); if (badRequest) { this.LogMessage("Bad request to " + httpContext.Request.URL); httpContext.Response.StatusCode = HttpStatusCode.BadRequest; httpContext.Response.Body = null; } else { this.LogMessage("Request to " + httpContext.Request.URL); try { // Resolve Request handler for the request IHttpHandler handler = this.ResolveHandler(httpContext); // no handler found if (handler == null) { httpContext.Response.StatusCode = HttpStatusCode.NotFound; } else { // process request by handler if (handler.CanProcessRequest(httpContext)) { await handler.ProcessRequest(httpContext); } else { httpContext.Response.StatusCode = HttpStatusCode.MethodNotAllowed; httpContext.Response.Body = null; } } } catch { httpContext.Response.StatusCode = HttpStatusCode.InternalServerError; httpContext.Response.Body = null; } } // Build HttpResponse // build the status line var responseHeaderBuilder = new StringBuilder("HTTP/1.1 "); responseHeaderBuilder.Append(((int)httpContext.Response.StatusCode).ToString()); responseHeaderBuilder.Append(" "); responseHeaderBuilder.AppendLine(Utils.MapStatusCodeToReason(httpContext.Response.StatusCode)); // build header section httpContext.Response.Headers["Content-Type"] = httpContext.Response.ContentType; int bodyLength = (!string.IsNullOrEmpty(httpContext.Response.Body)) ? httpContext.Response.Body.Length : 0; if (bodyLength > 0) { httpContext.Response.Headers["Content-Length"] = bodyLength.ToString(); } httpContext.Response.Headers["Connection"] = "close"; foreach (string responseHeaderKey in httpContext.Response.Headers.Keys) { responseHeaderBuilder.Append(responseHeaderKey); responseHeaderBuilder.Append(": "); responseHeaderBuilder.AppendLine(httpContext.Response.Headers[responseHeaderKey]); } // line blank seperation header-body responseHeaderBuilder.AppendLine(); // start sending status line and headers byte[] buffer = Encoding.UTF8.GetBytes(responseHeaderBuilder.ToString()); try { using (var streamWriter = new StreamWriter(requestClient.GetStream())) { await streamWriter.WriteAsync(responseHeaderBuilder.ToString()); await streamWriter.FlushAsync(); //// send body, if it exists if (bodyLength > 0) { await streamWriter.WriteAsync(httpContext.Response.Body); await streamWriter.FlushAsync(); } else // no body, streamed response { if (httpContext.Response.Stream != null) { byte[] sendBuffer = new byte[512]; int sendBytes = 0; while ((sendBytes = httpContext.Response.Stream.Read(sendBuffer, 0, sendBuffer.Length)) > 0) { byte[] outBuffer = new byte[sendBytes]; using (var binaryWriter = new BinaryWriter(requestClient.GetStream())) { binaryWriter.Write(sendBuffer); binaryWriter.Flush(); } } httpContext.Response.CloseStream(); } } } } catch (Exception e) { Debug.WriteLine("Exception: " + e.Message + " " + e.InnerException); } }