public override void ResponseHeaderAvailable(IHttpResponse response, ISessionContext context)
        {
            ServiceLog.Logger.Verbose(() => string.Format("{0}\r\n===RESPONSE=============\r\n{1}\r\n========================\r\n", context.Id, Encoding.UTF8.GetString(response.GetBuffer())));

            context.SendClientData(response.GetBuffer());

            //// Consult the response filters to see if any are interested in the entire body.
            //// Don't build the response body unless we have to; it's expensive.
            //// If any filters can make the judgement now, before we read the body, then use their response to
            //// short-circuit the body evaluation.
            //string filterResponse;
            //if (_filter.TryEvaluateResponseFilters(response,
            //                                         context.ClientConnection.ConnectionId,
            //                                         out filterResponse))
            //{
            //    // Filter active and does not need HTTP body
            //    if (filterResponse != null)
            //    {
            //        ServiceLog.Logger.Info("{0} *** PERFORMANCE HIT *** Response filter blocking content", context.Id);

            //        // Stop listening for more data from the server. We are creating our own response.
            //        // The session will terminate once this response is sent to the client.
            //        context.ChangeState(SessionStateType.ResponseHeaderFilter);
            //        context.SendClientData(Encoding.UTF8.GetBytes(filterResponse));
            //    }
            //    else
            //    {
            //        // Normal behavior. No filter activated.
            //        context.SendClientData(response.GetBuffer());
            //    }
            //}
            //else
            //{
            //    // Prepare to receive the entire HTTP body
            //    ServiceLog.Logger.Info("{0} *** PERFORMANCE HIT *** Response filter requires entire body. Building HTTP body.", context.Id);
            //    context.ChangeState(SessionStateType.ResponseBodyFilter);
            //}
        }
        public byte[] EvaluateResponseFiltersWithBody( IHttpResponse args, string connectionId, byte[] body )
        {
            byte[] filteredBody = null;

            if ( body != null && body.Length > 0 )
            {
                ServiceLog.Logger.Verbose( "Evaluating body filters" );

                // The body has been re-assembled. Remove the "chunked" header.
                args.Headers.RemoveKeyValue("transfer-encoding", "chunked");

                // Decompress the body so filters don't have to repeatedly do this themselves
                body = DecompressBody(args, body);

                ServiceLog.Logger.Verbose( () => Encoding.UTF8.GetString(body));

                foreach ( Func<IHttpResponse, string, byte[], byte[]> callback in _callbackList )
                {
                    filteredBody = callback(args, connectionId, body);

                    if ( filteredBody != null )
                    {
                        break;
                    }
                }
            }

            // Update the HTTP headers by adding the content length for the new body.
            // If the body was not modified by the filters then reset this to the
            // body that was passed in, which has possibly been decompressed.
            if ( filteredBody != null )
            {
                ServiceLog.Logger.Verbose("Response body has been modified by proxy server");
                args.Headers.UpsertKeyValue( "Content-Length", filteredBody.Length.ToString() );
            }
            else
            {
                ServiceLog.Logger.Verbose("Proxy server did not modify response body");
                filteredBody = body;
            }

            byte[] header = args.GetBuffer();

            byte[] returnBuffer = new byte[header.Length + filteredBody.Length];
            Array.Copy( header, returnBuffer, header.Length );
            Array.Copy( filteredBody, 0, returnBuffer, header.Length, filteredBody.Length );

            return returnBuffer;
        }
        public byte[] ApplyResponseBodyFilter(IHttpResponse response, byte[] body, IEnumerable<Func<IHttpResponse, string, byte[], byte[]>> bodyCallbacks)
        {
            byte[] filteredBody = null;

            if (body != null && body.Length > 0)
            {
                ServiceLog.Logger.Verbose("Evaluating body filters");

                // The body has been re-assembled. Remove the "chunked" header.
                response.Headers.RemoveKeyValue("transfer-encoding", "chunked");

                // Decompress the body so filters don't have to repeatedly do this themselves
                body = DecompressBody(response, body);

                ServiceLog.Logger.Verbose(() => Encoding.UTF8.GetString(body));

                foreach (Func<IHttpResponse, string, byte[], byte[]> callback in bodyCallbacks)
                {
                    filteredBody = callback(response, _clientConnectionId, body);

                    if (filteredBody != null)
                    {
                        break;
                    }
                }
            }

            // Update the HTTP headers by adding the content length for the new body.
            // If the body was not modified by the filters then reset this to the
            // body that was passed in, which has possibly been decompressed.
            if (filteredBody != null)
            {
                _accessLog.Write(_clientConnectionId, _request, AccessLogType.AccessBlocked);

                ServiceLog.Logger.Verbose("Response body has been modified by proxy server");
                response.Headers.UpsertKeyValue("Content-Length", filteredBody.Length.ToString());
            }
            else
            {
                _accessLog.Write(_clientConnectionId, _request, AccessLogType.AccessGranted);

                ServiceLog.Logger.Verbose("Proxy server did not modify response body");
                filteredBody = body;
            }

            byte[] header = response.GetBuffer();

            byte[] returnBuffer = new byte[header.Length + filteredBody.Length];
            Array.Copy(header, returnBuffer, header.Length);
            Array.Copy(filteredBody, 0, returnBuffer, header.Length, filteredBody.Length);

            return returnBuffer;
        }