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; }