Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Definitely use an <code>IHttpModule</code> and implement the <code>BeginRequest</code> and <code>EndRequest</code> events.</p> <p>All of the "raw" data is present between <code>HttpRequest</code> and <code>HttpResponse</code>, it just isn't in a single raw format. Here are the parts needed to build Fiddler-style dumps (about as close to raw HTTP as it gets):</p> <pre><code>request.HttpMethod + " " + request.RawUrl + " " + request.ServerVariables["SERVER_PROTOCOL"] request.Headers // loop through these "key: value" request.InputStream // make sure to reset the Position after reading or later reads may fail </code></pre> <p>For the response:</p> <pre><code>"HTTP/1.1 " + response.Status response.Headers // loop through these "key: value" </code></pre> <p>Note that <strong>you cannot read the response stream</strong> so you have to add a filter to the Output stream and capture a copy.</p> <p>In your <code>BeginRequest</code>, you will need to add a response filter:</p> <pre><code>HttpResponse response = HttpContext.Current.Response; OutputFilterStream filter = new OutputFilterStream(response.Filter); response.Filter = filter; </code></pre> <p>Store <code>filter</code> where you can get to it in the <code>EndRequest</code> handler. I suggest in <code>HttpContext.Items</code>. There can then get the full response data in <code>filter.ReadStream()</code>.</p> <p>Then implement <code>OutputFilterStream</code> using the Decorator pattern as a wrapper around a stream:</p> <pre><code>/// &lt;summary&gt; /// A stream which keeps an in-memory copy as it passes the bytes through /// &lt;/summary&gt; public class OutputFilterStream : Stream { private readonly Stream InnerStream; private readonly MemoryStream CopyStream; public OutputFilterStream(Stream inner) { this.InnerStream = inner; this.CopyStream = new MemoryStream(); } public string ReadStream() { lock (this.InnerStream) { if (this.CopyStream.Length &lt;= 0L || !this.CopyStream.CanRead || !this.CopyStream.CanSeek) { return String.Empty; } long pos = this.CopyStream.Position; this.CopyStream.Position = 0L; try { return new StreamReader(this.CopyStream).ReadToEnd(); } finally { try { this.CopyStream.Position = pos; } catch { } } } } public override bool CanRead { get { return this.InnerStream.CanRead; } } public override bool CanSeek { get { return this.InnerStream.CanSeek; } } public override bool CanWrite { get { return this.InnerStream.CanWrite; } } public override void Flush() { this.InnerStream.Flush(); } public override long Length { get { return this.InnerStream.Length; } } public override long Position { get { return this.InnerStream.Position; } set { this.CopyStream.Position = this.InnerStream.Position = value; } } public override int Read(byte[] buffer, int offset, int count) { return this.InnerStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { this.CopyStream.Seek(offset, origin); return this.InnerStream.Seek(offset, origin); } public override void SetLength(long value) { this.CopyStream.SetLength(value); this.InnerStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { this.CopyStream.Write(buffer, offset, count); this.InnerStream.Write(buffer, offset, count); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload