HttpListener Proxy

Just in case you find a use for some web proxy code…

 

I wrote a HttpListener proxy based on the HttpListener MSDN docs, and the web request code I did for something else. I had to do this because I needed to use the X-Plane updater from work which let me specify only an anonymous proxy, not the authenticated type that is at work. Here’s the code I got working for streaming binary data (note the HttpListener MSDN code only works for text as I discovered).

 

To test it I guess you could set a proxy in your web browser as 127.0.0.1:8080. The code below is the complete program.

 

using System;

using System.Net;

using System.Collections.Generic;

using System.Text;

using System.IO;

 

namespace HttpListenerProxy

{

      class RequestData

      {

            public HttpWebRequest WebRequest;

            public HttpListenerContext Context;

 

            public RequestData(HttpWebRequest request, HttpListenerContext context)

            {

                  WebRequest = request;

                  Context = context;

            }

      }

 

      class Program

      {

            static void Main(string[] args)

            {

                  // Create a listener.

                  HttpListener listener = new HttpListener();

                  listener.Prefixes.Add("http://*:8080/");

 

                  listener.Start();

                  try

                  {

                        while (true)

                        {

                              Console.WriteLine("Listening…");

                              // Note: The GetContext method blocks while waiting for a request.

                              HttpListenerContext context = listener.GetContext();

                              string requestString = context.Request.RawUrl;

                              Console.WriteLine("Got request for " + requestString);

                              HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString);

                              request.KeepAlive = false;

                              request.Proxy.Credentials = CredentialCache.DefaultCredentials;

                              request.Timeout = 200000;

 

                              RequestData requestData = new RequestData(request, context);

                              IAsyncResult result = (IAsyncResult)request.BeginGetResponse(new AsyncCallback(RespCallback), requestData);

                        }

                  }

                  catch (Exception e)

                  {

                        Console.WriteLine("\nMain Exception raised!");

                        Console.WriteLine("Source :{0} ", e.Source);

                        Console.WriteLine("Message :{0} ", e.Message);

                  }

 

                  listener.Stop();

            }

 

            static void RespCallback(IAsyncResult asynchronousResult)

            {

                  try

                  {

 

                        // State of request is asynchronous.

                        RequestData requestData = (RequestData)asynchronousResult.AsyncState;

                        Console.WriteLine("Got back response from " + requestData.Context.Request.Url.AbsoluteUri);

 

                        using(HttpWebResponse response = (HttpWebResponse)requestData.WebRequest.EndGetResponse(asynchronousResult))

                        using (Stream receiveStream = response.GetResponseStream())

                        {

                              HttpListenerResponse responseOut = requestData.Context.Response;

 

                              // Need to get the length of the response before it can be forwarded on

                              responseOut.ContentLength64 = response.ContentLength;

                              int bytesCopied = CopyStream(receiveStream, responseOut.OutputStream);

                              responseOut.OutputStream.Close();

                              Console.WriteLine("Copied {0} bytes", bytesCopied);

                        }

                  }

                  catch (Exception e)

                  {

                        Console.WriteLine("\nMain Exception raised!");

                        Console.WriteLine("Source :{0} ", e.Source);

                        Console.WriteLine("Message :{0} ", e.Message);

                  }

            }

 

            public static int CopyStream(Stream input, Stream output)

            {

                  byte[] buffer = new byte[32768];

                  int bytesWritten = 0;

                  while (true)

                  {

                        int read = input.Read(buffer, 0, buffer.Length);

                        if (read <= 0)

                              break;

                        output.Write(buffer, 0, read);

                        bytesWritten += read;

                  }

                  return bytesWritten;

            }

      }

}

 

This entry was posted in Uncategorized. Bookmark the permalink.

1 Response to HttpListener Proxy

  1. xyz says:

    lauda road to some where else .Your code is not working
    for both https and http requests

Leave a comment