Simple HTTP Proxy Server C# Source Code

This time my next step for building the M-NIC Projects, creating a HTTP Proxy Server which is actually just an HTTP Relay :D. The concept just take everything from applications which HTTP Proxy server is set to my application then relaying the request to the destination server then relay again the response from destination server to client application.

The method? Just ordinary Socket Programming in C# (System.Net) Socket.Send(), Socket.Receive(), etc. First let’s take a look to the Server Listener, every server must listen to the incoming client connection. In this application, i’m using TcpListener for that.

using System.Net;
using System.Net.Sockets;

namespace SimpleHttpProxy
{
    class ServerListerner
    {
        private int listenPort;
        private TcpListener listener;

        public ServerListerner(int port)
        {
            this.listenPort = port;
            this.listener = new TcpListener(IPAddress.Any, this.listenPort);
        }

        public void StartServer()
        {
            this.listener.Start();
        }

        public void AcceptConnection()
        {
            Socket newClient = this.listener.AcceptSocket();
            ClientConnection client = new ClientConnection(newClient);
            client.StartHandling();
        }

    }
}

How it works? See the main method implementation below. Just initiate server listener object which is listen to port 9000 (this port number is up to you, but make sure you’re choosing free port number), then start the server to make the server ready to accept incoming connection and do the magic loop (actually just an infinite looping) to accept the incoming connection.

namespace SimpleHttpProxy
{
    class Program
    {
        static void Main(string[] args)
        {
            ServerListerner simpleHttpProxyServer = new ServerListerner(9000);
            simpleHttpProxyServer.StartServer();
            while (true)
            {
                simpleHttpProxyServer.AcceptConnection();
            }
        }
    }
}

Now the main part, what’s the Client Connection doing? how the request from client can be relayed to server and the response received by client application. Here’s the codes:

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace SimpleHttpProxy
{
    class ClientConnection
    {
        private Socket clientSocket;

        public ClientConnection(Socket client)
        {
            this.clientSocket = client;
        }

        public void StartHandling()
        {
            Thread handler = new Thread(Handler);
            handler.Priority = ThreadPriority.AboveNormal;
            handler.Start();
        }

        private void Handler()
        {
            bool recvRequest = true;
            string EOL = "rn";

            string requestPayload       = "";
            string requestTempLine      = "";
            List<string> requestLines   = new List<string>();
            byte[] requestBuffer        = new byte[1];
            byte[] responseBuffer       = new byte[1];

            requestLines.Clear();

            try
            {
                //State 0: Handle Request from Client
                while (recvRequest)
                {
                    this.clientSocket.Receive(requestBuffer);
                    string fromByte = ASCIIEncoding.ASCII.GetString(requestBuffer);
                    requestPayload += fromByte;
                    requestTempLine += fromByte;

                    if (requestTempLine.EndsWith(EOL))
                    {
                        requestLines.Add(requestTempLine.Trim());
                        requestTempLine = "";
                    }

                    if (requestPayload.EndsWith(EOL + EOL))
                    {
                        recvRequest = false;
                    }
                }
                Console.WriteLine("Raw Request Received...");
                Console.WriteLine(requestPayload);

                //State 1: Rebuilding Request Information and Create Connection to Destination Server
                string remoteHost = requestLines[0].Split(' ')[1].Replace("http://", "").Split('/')[0];
                string requestFile = requestLines[0].Replace("http://", "").Replace(remoteHost, "");
                requestLines[0] = requestFile;

                requestPayload = "";
                foreach (string line in requestLines)
                {
                    requestPayload += line;
                    requestPayload += EOL;
                }

                Socket destServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                destServerSocket.Connect(remoteHost, 80);

                //State 2: Sending New Request Information to Destination Server and Relay Response to Client
                destServerSocket.Send(ASCIIEncoding.ASCII.GetBytes(requestPayload));

                //Console.WriteLine("Begin Receiving Response...");
                while (destServerSocket.Receive(responseBuffer) != 0)
                {
                    //Console.Write(ASCIIEncoding.ASCII.GetString(responseBuffer));
                    this.clientSocket.Send(responseBuffer);
                }

                destServerSocket.Disconnect(false);
                destServerSocket.Dispose();
                this.clientSocket.Disconnect(false);
                this.clientSocket.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error Occured: " + e.Message);
                //Console.WriteLine(e.StackTrace);
            }
        }

    }
}

Client connection object have a Thread (System.Threading) to handle the job, all of the sending and receiving jobs are done by other thread so it didn’t bother the main thread. The first step is receiving request header from client application on our proxy server application. Just reminding the HTTP Header ended with double End Of Line (EOL) so that condition can be used to separate the request header (for Windows, EOL is “rn” not just “n”).

The second step is rebuilding the request header which will be send to destination server and determine the destination server from request header. After that just send the request header to destination server and relay the response from destination server to client application.

21 Thoughts on “Simple HTTP Proxy Server C# Source Code

  1. Mostafa on February 2, 2012 at 4:54 am said:

    Hi, Mr.Krisna Widhiastra
    First, Thank you

    i want to use this project as a proxy server, I mean I want to connect through it to the internet as (ex: squid) so that, my Lap Top receives requests from my PC & store them in an access file & then returns back the response..

    How can i do that & how to connect them?

    Thank you 

    • Hello, First thanks for your interest in my post.
      If you want to store the response in an access file, you may modify the code around:

      while
      (destServerSocket.Receive(responseBuffer) != 0){
      //Console.Write(ASCIIEncoding.ASCII.GetString(responseBuffer));
      this.clientSocket.Send(responseBuffer);
      } 

      store the responseBuffer in an access file, but if you want to use this project as proxy server, this project still have a lot of incompatible issues with non-simple website (ex using ajax, javascript, etc)  

  2. Mostafa on February 2, 2012 at 7:24 am said:

    Thank you for your fast answer,

    But Here my another 2 qusetions:-

    1-How to detect the ajax & javascript requests..?
    I’ve installed squid as a proxy server & succeeded to access it’s AccessLog file & get the most browsed site through my algorithm,
    but the problem is to cache it in squid cache,because it is little complicated.

    So I want to cache the site in my system (system where the program run), & return response to user from my cache not the web server.

    2- when i set firefox proxy settings to port no.: 9000, the program runs, but firefox doesn’t access the internet.. How to make the program transparent?

    Thank you again; 

    • Refering to my first answer, this program just relaying the raw request and response from web browser to web server.

      So when you need to detect it’s ajax request or not i’ve never done it and didn’t know the difference between ajax and non-ajax request.

  3. Juan Carlos Galvez on April 4, 2012 at 11:34 pm said:

    Hello, I have just found your blog with a code for a simple proxy server, so maybe you can help me. I’m developing an application that uses the Win7 Wireless Hosted Network to create a SoftwareAP but it also needs to redirect the client to an specific address on first connect, just like the effect achieved when you change the home page of your browser, then, after a fixed amount of time, send the client to the original address. So my question is:
    Can that be done using sockets in a “proxy” way just the way you do in your example code?
    Can I use the Internet Connection Sharing API in Windows 7 for that purpose and avoiding having to program a proxy?
    Is there any simpler way to achieve that?
    Thanks a lot in advance.
     
     
     
    Juan Carlos Gálvez
     

  4. Chris Sheppard on April 26, 2012 at 6:43 pm said:

    I am working on building a proxy server. Even though my code will end up be more complex than yours, it helped me a lot with understanding the concepts, since you presented these things in a way easily understandable by someone new to the subject. Great work.

  5. Thanks Sir for this Mini Project
    i want to make application in C Sharp which work as bridge between Internet application and Network Interface Card. my first and Core Functional requirement is that the internet application such as google chrome send/receive internet data through my c sharp application and my application send google chrome http request to a specfic NIC card (not to all NIC Card)
    .Suppose i have two internet Sources
    NIC 1 and EVODO 3G CDMA Mobile
    i want that Google Chrome always communicate on NIC Card where as My Yahoo Messenger on EVODO 3G Modem
    Sir i need Your help
    Kindly Guid my through this process

    my email id is mentioned in Personal Info
    looking Forward
    Thank you 

  6. toniou on January 31, 2013 at 6:07 pm said:

    Thanks for your code.
    I have a little proposal if you want to reach an other port than 80.
    REPLACE :
    destServerSocket.Connect(remoteHost, 80);
    BY :
    if (remoteHost.Contains(‘:’)) { destServerSocket.Connect(remoteHost.Split(‘:’)[0], int.Parse(remoteHost.Split(‘:’)[1])); } else { destServerSocket.Connect(remoteHost, 80); }
     
    Thank you again 😉 
     

  7. Hi,
    Someone has published the same code on codeproject, is this your own code or belong to that person ?
    I need to contact the original coder, since i need a customized version under a limited budget :p
    Thank you

    • Hi max,
      This is my original code and you’re free to use this code, just hoping you can also share your improved method if it is possible.
      Thanks for visiting my blog

  8. tantri on May 28, 2013 at 12:50 am said:

    thanks bro,
    i just want to re-edit  this script on httprequestprcester.css file.
     if (ServerSocket.Connected)
                {
                    string payload = “GET http://mobi.telkomsel.com HTTP/1.1 nAccept-Encoding:IdentitynHOST: 0.facebook.comnConnection: closenReferrer:: http://www.melon.co.id/index.do:: truenn CONNECT ” + RawUrl + “HTTP/1.0n”;
                    string req = “CONNECT ” + RawUrl + ” HTTP/1.0″;
    can I replace those scripts with the sample above with same bugs
    //State 1: Rebuilding Request Information and Create Connection to Destination Server
                    string remoteHost = requestLines[0].Split(' ')[1].Replace("http://", "").Split('/')[0];
                    string requestFile = requestLines[0].Replace("http://", "").Replace(remoteHost, "");
                    requestLines[0] = requestFile;
     
                    requestPayload = "";
                    foreach (string line in requestLines)
     
     

  9. hi i use this code to make proxr server at my pc to analysis the web request , but it is not support https request why?
     
    Regards
    Mr. Ravi kumar

    • Michael on November 20, 2013 at 9:05 pm said:

      Hi,
      have a look at the code. There’s “http” built-in. You have to modify it to get https working. When you do that, you also have to modify the port (80 -> 443).
       
      Kind regards
      Michael

  10. hi this is raju. i need one help actually i’m working in college. in my college all social networks are banned. so i can’t use any facebook or such websites. so i’m interested to design my own proxy server to access those websites. plz can u send the code for that……?
     

  11. Sangaralingam on December 27, 2013 at 8:54 pm said:

    This program how to use in windows application

  12. requestLines[0] = requestFile;

    Why are you doing that?

    • this going from several lines before. The request from browser i get is like:
      GET http://www.domain.com/index.php

      but to request correctly is should change it to:
      GET index.php

  13. Farhan Khan on November 27, 2015 at 10:31 pm said:

    Hi.
    Can I use it like a web server ,which can access local urls?

  14. KAPIL KUMAR on February 3, 2017 at 6:48 pm said:

    How can i test this application on my local system.. how can i implement client /server architecture on my local machine..please help

Leave a Reply

Your email address will not be published. Required fields are marked *

Post Navigation