//Called asynchronously when a request was successfully and we received the response public async Task HandleHttpSessionResponse(SessionEventArgs args) { //read response & headers from server await args.WebSession.ReceiveResponse(); try { if (!args.WebSession.Response.ResponseBodyRead) { args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream; } args.ReRequest = false; //If user requested call back then do it if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked) { Delegate[] invocationList = BeforeResponse.GetInvocationList(); Task[] handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((Func <object, SessionEventArgs, Task>)invocationList[i])(this, args); } await Task.WhenAll(handlerTasks); } if (args.ReRequest) { await HandleHttpSessionRequestInternal(null, args, null, null, true).ConfigureAwait(false); return; } args.WebSession.Response.ResponseLocked = true; //Write back to client 100-conitinue response if that's what server returned if (args.WebSession.Response.Is100Continue) { await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", "Continue", args.ProxyClient.ClientStreamWriter); await args.ProxyClient.ClientStreamWriter.WriteLineAsync(); } else if (args.WebSession.Response.ExpectationFailed) { await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", "Expectation Failed", args.ProxyClient.ClientStreamWriter); await args.ProxyClient.ClientStreamWriter.WriteLineAsync(); } //Write back response status to client await WriteResponseStatus(args.WebSession.Response.HttpVersion, args.WebSession.Response.ResponseStatusCode, args.WebSession.Response.ResponseStatusDescription, args.ProxyClient.ClientStreamWriter); if (args.WebSession.Response.ResponseBodyRead) { var isChunked = args.WebSession.Response.IsChunked; var contentEncoding = args.WebSession.Response.ContentEncoding; if (contentEncoding != null) { args.WebSession.Response.ResponseBody = await GetCompressedResponseBody(contentEncoding, args.WebSession.Response.ResponseBody); if (isChunked == false) { args.WebSession.Response.ContentLength = args.WebSession.Response.ResponseBody.Length; } else { args.WebSession.Response.ContentLength = -1; } } await WriteResponseHeaders(args.ProxyClient.ClientStreamWriter, args.WebSession.Response); await args.ProxyClient.ClientStream.WriteResponseBody(args.WebSession.Response.ResponseBody, isChunked); } else { await WriteResponseHeaders(args.ProxyClient.ClientStreamWriter, args.WebSession.Response); //Write body only if response is chunked or content length >0 //Is none are true then check if connection:close header exist, if so write response until server or client terminates the connection if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0 || !args.WebSession.Response.ResponseKeepAlive) { await args.WebSession.ServerConnection.StreamReader .WriteResponseBody(BUFFER_SIZE, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength); } //write response if connection:keep-alive header exist and when version is http/1.0 //Because in Http 1.0 server can return a response without content-length (expectation being client would read until end of stream) else if (args.WebSession.Response.ResponseKeepAlive && args.WebSession.Response.HttpVersion.Minor == 0) { await args.WebSession.ServerConnection.StreamReader .WriteResponseBody(BUFFER_SIZE, args.ProxyClient.ClientStream, args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength); } } await args.ProxyClient.ClientStream.FlushAsync(); } catch { Dispose(args.ProxyClient.ClientStream, args.ProxyClient.ClientStreamReader, args.ProxyClient.ClientStreamWriter, args); } finally { args.Dispose(); } }
//Called asynchronously when a request was successfully and we received the response public static async Task HandleHttpSessionResponse(SessionEventArgs args) { await args.WebSession.ReceiveResponse().ConfigureAwait(false); try { if (!args.WebSession.Response.ResponseBodyRead) { args.WebSession.Response.ResponseStream = args.WebSession.ServerConnection.Stream; } if (BeforeResponse != null && !args.WebSession.Response.ResponseLocked) { Delegate[] invocationList = BeforeResponse.GetInvocationList(); Task[] handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((Func <object, SessionEventArgs, Task>)invocationList[i])(null, args); } await Task.WhenAll(handlerTasks).ConfigureAwait(false); } args.WebSession.Response.ResponseLocked = true; if (args.WebSession.Response.Is100Continue) { await WriteResponseStatus(args.WebSession.Response.HttpVersion, "100", "Continue", args.Client.ClientStreamWriter); await args.Client.ClientStreamWriter.WriteLineAsync(); } else if (args.WebSession.Response.ExpectationFailed) { await WriteResponseStatus(args.WebSession.Response.HttpVersion, "417", "Expectation Failed", args.Client.ClientStreamWriter); await args.Client.ClientStreamWriter.WriteLineAsync(); } await WriteResponseStatus(args.WebSession.Response.HttpVersion, args.WebSession.Response.ResponseStatusCode, args.WebSession.Response.ResponseStatusDescription, args.Client.ClientStreamWriter); if (args.WebSession.Response.ResponseBodyRead) { var isChunked = args.WebSession.Response.IsChunked; var contentEncoding = args.WebSession.Response.ContentEncoding; if (contentEncoding != null) { args.WebSession.Response.ResponseBody = await GetCompressedResponseBody(contentEncoding, args.WebSession.Response.ResponseBody).ConfigureAwait(false); if (isChunked == false) { args.WebSession.Response.ContentLength = args.WebSession.Response.ResponseBody.Length; } else { args.WebSession.Response.ContentLength = -1; } } await WriteResponseHeaders(args.Client.ClientStreamWriter, args.WebSession.Response.ResponseHeaders).ConfigureAwait(false); await WriteResponseBody(args.Client.ClientStream, args.WebSession.Response.ResponseBody, isChunked).ConfigureAwait(false); } else { await WriteResponseHeaders(args.Client.ClientStreamWriter, args.WebSession.Response.ResponseHeaders); if (args.WebSession.Response.IsChunked || args.WebSession.Response.ContentLength > 0 || (args.WebSession.Response.HttpVersion.Major == 1 && args.WebSession.Response.HttpVersion.Minor == 0)) { await WriteResponseBody(args.WebSession.ServerConnection.StreamReader, args.Client.ClientStream, args.WebSession.Response.IsChunked, args.WebSession.Response.ContentLength).ConfigureAwait(false); } } await args.Client.ClientStream.FlushAsync(); } catch { Dispose(args.Client.TcpClient, args.Client.ClientStream, args.Client.ClientStreamReader, args.Client.ClientStreamWriter, args); } finally { args.Dispose(); } }