title: Writing a proxy server and client using sockets
body: <p>I'm wiriting a proxy server and I want it to be high performance, and scalabe, because of that I decided use a low level api like <code>System.Net.Sockets</code>. </p>
  
  <p>As of now I just implemented a simple http proxy server that receives a request from web browser, and simply forwards the request to the server and again forwards the response to the client. It turns out that it consumes <strong>100%</strong> of my laptop's <strong>CPU usage</strong>.</p>
  
  <p>I use the below code, that is simple and it can be improved, so my first question is how to optimize it in order not to eat the CPU usage? Here's the code:</p>
  
  <pre><code>    public void StartHandling()
      {
          while (!ThreadPool.QueueUserWorkItem(
                              new WaitCallback(Handler))) ;
      }
  
      private void Handler(object obj)
      {
          bool recvRequest = true;
          string EOL = "\r\n";
  
          string requestPayload = "";
          string requestTempLine = "";
          List&lt;string&gt; requestLines = new List&lt;string&gt;();
          byte[] requestBuffer = new byte[1];
          byte[] responseBuffer = new byte[1024];
  
          requestLines.Clear();
  
          try
          {
              //State 0: Handle Request from Client
              while (recvRequest)
              {
                  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[] pars = requestLines[0].Split(' ');
              string url;
              string remoteHost;
              string requestFile;
              int port;
              if (pars[0] == "GET")
              {
                  url = pars[1].Replace("http://", "");
                  if (url.IndexOf(':') &gt; 0)
                      throw new InvalidOperationException("Bad request!");
                  port = 80; // http port
              }
              else if (pars[0] == "CONNECT")
              {
                  url = pars[1].Replace("https://", "").Replace(":443", "");
                  if (url.IndexOf(':') &gt; 0)
                      throw new InvalidOperationException("Bad request!");
                  port = 443; // https port
              }
              else
                  throw new InvalidOperationException("Bad request!");
  
              remoteHost = url.Split('/')[0];
              requestFile = requestLines[0].Replace("https://", "").Replace("http://", "").Replace(remoteHost, "");
  
              requestLines[0] = requestFile;
  
              requestPayload = "";
              foreach (string line in requestLines)
              {
                  requestPayload += line;
                  requestPayload += EOL;
              }
  
              using (Socket destServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
              {
                  destServerSocket.Connect(remoteHost, port);
  
                  //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);
                  }
  
                  //int totalReceived = destServerSocket.Receive(responseBuffer);
                  //while (totalReceived != 0)
                  //{
                  //  clientSocket.Send(responseBuffer, totalReceived, SocketFlags.None);
                  //  totalReceived = destServerSocket.Receive(responseBuffer);
                  //}
  
                  destServerSocket.Disconnect(false);
                  clientSocket.Disconnect(false);
              }
  
          }
          catch (Exception e)
          {
              Console.WriteLine("Error Occured: " + e.Message);
              //Console.WriteLine(e.StackTrace);
          }
          finally
          {
              clientSocket.Dispose();
              Thread.CurrentThread.Abort();
          }
      }
  </code></pre>
  
  <p>My <strong>second question</strong> is how can I handle <strong>HTTPS</strong> requests? I actually forward the HTTPS request to the server like HTTP but it doesn't work that way.</p>