private async Task handleHttpSessionRequest(TcpServerConnection connection, SessionEventArgs args) { var cancellationToken = args.CancellationTokenSource.Token; var request = args.HttpClient.Request; request.Locked = true; var body = request.CompressBodyAndUpdateContentLength(); // set the connection and send request headers args.HttpClient.SetConnection(connection); await args.HttpClient.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, cancellationToken); // If a successful 100 continue request was made, inform that to the client and reset response if (request.ExpectationSucceeded) { var clientStreamWriter = args.ProxyClient.ClientStreamWriter; var response = args.HttpClient.Response; var headerBuilder = new HeaderBuilder(); headerBuilder.WriteResponseLine(response.HttpVersion, response.StatusCode, response.StatusDescription); headerBuilder.WriteHeaders(response.Headers); await clientStreamWriter.WriteHeadersAsync(headerBuilder, cancellationToken); await args.ClearResponse(cancellationToken); } // send body to server if available if (request.HasBody) { if (request.IsBodyRead) { var writer = args.HttpClient.Connection.StreamWriter; await writer.WriteBodyAsync(body !, request.IsChunked, cancellationToken); } else if (!request.ExpectationFailed) { // get the request body unless an unsuccessful 100 continue request was made HttpWriter writer = args.HttpClient.Connection.StreamWriter !; await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken); } } args.TimeLine["Request Sent"] = DateTime.Now; // parse and send response await handleHttpSessionResponse(args); }
/// <summary> /// Handle a specific session (request/response sequence) /// </summary> /// <param name="serverConnection">The tcp connection.</param> /// <param name="args">The session event arguments.</param> /// <returns></returns> private async Task HandleHttpSessionRequestInternal(TcpServerConnection serverConnection, SessionEventArgs args) { try { var cancellationToken = args.CancellationTokenSource.Token; var request = args.WebSession.Request; request.Locked = true; var body = request.CompressBodyAndUpdateContentLength(); // if expect continue is enabled then send the headers first // and see if server would return 100 conitinue if (request.ExpectContinue) { args.WebSession.SetConnection(serverConnection); await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, cancellationToken); } // If 100 continue was the response inform that to the client if (Enable100ContinueBehaviour) { var clientStreamWriter = args.ProxyClient.ClientStreamWriter; if (request.Is100Continue) { await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.Continue, "Continue", cancellationToken); await clientStreamWriter.WriteLineAsync(cancellationToken); } else if (request.ExpectationFailed) { await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.ExpectationFailed, "Expectation Failed", cancellationToken); await clientStreamWriter.WriteLineAsync(cancellationToken); } } // If expect continue is not enabled then set the connectio and send request headers if (!request.ExpectContinue) { args.WebSession.SetConnection(serverConnection); await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent, cancellationToken); } // check if content-length is > 0 if (request.ContentLength > 0) { if (request.IsBodyRead) { var writer = args.WebSession.ServerConnection.StreamWriter; await writer.WriteBodyAsync(body, request.IsChunked, cancellationToken); } else { if (!request.ExpectationFailed) { if (request.HasBody) { HttpWriter writer = args.WebSession.ServerConnection.StreamWriter; await args.CopyRequestBodyAsync(writer, TransformationMode.None, cancellationToken); } } } } // If not expectation failed response was returned by server then parse response if (!request.ExpectationFailed) { await HandleHttpSessionResponse(args); } } catch (Exception e) when(!(e is ProxyHttpException)) { throw new ProxyHttpException("Error occured whilst handling session request (internal)", e, args); } }
/// <summary> /// Handle a specific session (request/response sequence) /// </summary> /// <param name="connection"></param> /// <param name="args"></param> /// <returns>True if close the connection</returns> private async Task HandleHttpSessionRequestInternal(TcpConnection connection, SessionEventArgs args) { try { var request = args.WebSession.Request; request.RequestLocked = true; //if expect continue is enabled then send the headers first //and see if server would return 100 conitinue if (request.ExpectContinue) { args.WebSession.SetConnection(connection); await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent); } //If 100 continue was the response inform that to the client if (Enable100ContinueBehaviour) { var clientStreamWriter = args.ProxyClient.ClientStreamWriter; if (request.Is100Continue) { await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.Continue, "Continue"); await clientStreamWriter.WriteLineAsync(); } else if (request.ExpectationFailed) { await clientStreamWriter.WriteResponseStatusAsync(args.WebSession.Response.HttpVersion, (int)HttpStatusCode.ExpectationFailed, "Expectation Failed"); await clientStreamWriter.WriteLineAsync(); } } //If expect continue is not enabled then set the connectio and send request headers if (!request.ExpectContinue) { args.WebSession.SetConnection(connection); await args.WebSession.SendRequest(Enable100ContinueBehaviour, args.IsTransparent); } //check if content-length is > 0 if (request.ContentLength > 0) { //If request was modified by user if (request.IsBodyRead) { if (request.ContentEncoding != null) { request.Body = await GetCompressedResponseBody(request.ContentEncoding, request.Body); } var body = request.Body; //chunked send is not supported as of now request.ContentLength = body.Length; await args.WebSession.ServerConnection.StreamWriter.WriteAsync(body); } else { if (!request.ExpectationFailed) { //If its a post/put/patch request, then read the client html body and send it to server if (request.HasBody) { HttpWriter writer = args.WebSession.ServerConnection.StreamWriter; await args.CopyRequestBodyAsync(writer, false); } } } } //If not expectation failed response was returned by server then parse response if (!request.ExpectationFailed) { await HandleHttpSessionResponse(args); } } catch (Exception e) when(!(e is ProxyHttpException)) { throw new ProxyHttpException("Error occured whilst handling session request (internal)", e, args); } }