1

I try to get every request and response of my HttpListener logged.

For the HttpListenerContext.Request.InputStream, this was as simple as doing this:

var finfoIn = context.Request.GetType().GetField("m_RequestStream", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
context.Request.InputStream.CopyTo(memstreamIn);
memstreamIn.Seek(0, System.IO.SeekOrigin.Begin);
var reader = new System.IO.StreamReader(memstreamIn, Encoding.Unicode);
this.Log(reader.ReadToEnd()); //Actual log method that prints to console
memstreamIn.Seek(0, System.IO.SeekOrigin.Begin);
finfoIn.SetValue(context.Request, memstreamIn);

However, due to the HttpListenerContext.Response.OutputStream having the field type (internal) System.Net.HttpResponseStream, this above trick is not possible.

Anybody got some solution to allow logging for the OutputStream?

X39
  • 789
  • 6
  • 22
  • Why are you doing this? Do you need this logging in your final application? You know you can configure tracing to output all network data? Also, why exactly do you think this trick isn't possible for the output stream? – CodeCaster Sep 25 '18 at 10:14
  • This kind of logging is not required in the final application. Only for debugging during development (and testing) @CodeCaster (it is wrapped inside of a `#if DEBUG`) – X39 Sep 25 '18 at 10:18
  • Then see [How to: Configure Network Tracing](https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-configure-network-tracing). – CodeCaster Sep 25 '18 at 10:18
  • Problem with that is, if i understood it correctly, it only appears in the output window of eg. visual studio or inside of a file i choose. However, i need this to run through the log method instead (as that one adds some more crucial debug info for me to actually follow those requests) which is why i took this approach. – X39 Sep 25 '18 at 10:23
  • So, what happens if you try the same approach with the OutputStream? What is the actual problem? – CodeCaster Sep 25 '18 at 10:27
  • As described above, the field type is not the generic `System.IO.Stream` one like with the input but rather `System.Net.HttpResponseStream` which means i get invalid cast exceptions when calling `FieldInfo.SetValue` with the memory stream. The class itself also is not accessible due to its protection level being `internal`, so no simple wrapper class either – X39 Sep 25 '18 at 10:32
  • You can instantiate nonpublic types through reflection as well: https://stackoverflow.com/questions/2023193/instantiating-internal-class-with-private-constructor – CodeCaster Sep 25 '18 at 10:35

1 Answers1

-2

Here is a very simple example for debug:

HttpListener Listener = new HttpListener("http", 80);
Listener.Start();
HttpListenerContext ctx;
string s;
byte[] b;
int i;

while (true)
{
    ctx = Listener.GetContext();
    Debug.Print("Serving a page...");
    s = "";
    for (i = 0; i < 500; i++) s += "Hello!"; // a 5KB dumb page
    s += "";
    b = Encoding.UTF8.GetBytes(s);
    ctx.Response.ContentLength64 = b.Length;
    ctx.Response.ContentType = "text/html";
    ctx.Response.OutputStream.Write(b, 0, b.Length);
    ctx.Response.OutputStream.Close();           
    s = null;
    b = null;
    Debug.GC(true);
    Debug.Print("Done with the page.");    
}
Siavash
  • 2,813
  • 4
  • 29
  • 42