Пример #1
0
        //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();
            }
        }