import java.io.*;
import java.net.Socket;
import java.net.SocketException;

/**
 * Created by Xinan on 14/9/15.
 */
public class RequestHandlerThread extends Thread {

  final private Socket clientSocket;
  final private int BUFFER_SIZE;

  public RequestHandlerThread(Socket clientSocket) {
    this(clientSocket, 65536);
  }

  public RequestHandlerThread(Socket clientSocket, int bufferSize) {
    this.clientSocket = clientSocket;
    BUFFER_SIZE = bufferSize;
  }

  public void run() {
    try {
      HttpRequest clientRequest = new HttpRequest(clientSocket.getInputStream());
      BufferedOutputStream clientOut = new BufferedOutputStream(clientSocket.getOutputStream(), BUFFER_SIZE);
      System.out.printf("[%s] %s\n", clientSocket.getInetAddress().getCanonicalHostName(), clientRequest);

      Socket serverSocket = new Socket(clientRequest.getHost(), 80);

      BufferedInputStream serverIn = new BufferedInputStream(serverSocket.getInputStream(), BUFFER_SIZE);
      BufferedOutputStream serverOut = new BufferedOutputStream(serverSocket.getOutputStream(), BUFFER_SIZE);
      serverOut.write(clientRequest.toByteBuffer());
      serverOut.flush();

      int bytesRead;
      byte[] buffer = new byte[BUFFER_SIZE];
      while ((bytesRead = serverIn.read(buffer)) > 0) {
        clientOut.write(buffer, 0, bytesRead);
        clientOut.flush();
      }
      System.out.printf("Done. Active Thread: %d\r", Thread.activeCount());

      serverSocket.close();
      clientSocket.close();
    } catch (SocketException e) {
      System.out.printf("Client closed connection.\n");
    } catch (IOException e) {
      e.printStackTrace();
    } catch (MalformedRequestException e) {
      try {
        clientSocket.getOutputStream().write(e.getMessage().getBytes());
        clientSocket.close();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }
}

@@ -67,16 +67,54 @@
 ception;
+%0Aimport java.net.UnknownHostException;
 %0A%0A/**%0A *
@@ -529,24 +529,38 @@
 %7B%0A    try %7B%0A
+      try %7B%0A  
       HttpRe
@@ -627,32 +627,34 @@
 tream());%0A      
+ 
+ 
 BufferedOutputSt
@@ -743,24 +743,26 @@
 IZE);%0A      
+  
 System.out.p
@@ -857,16 +857,18 @@
 %0A%0A      
+ 
+ 
 Socket s
@@ -919,24 +919,26 @@
 st(), 80);%0A%0A
+  
       Buffer
@@ -1033,24 +1033,26 @@
 IZE);%0A      
+  
 BufferedOutp
@@ -1141,32 +1141,34 @@
 ER_SIZE);%0A      
+  
 serverOut.write(
@@ -1200,24 +1200,26 @@
 r());%0A      
+  
 serverOut.fl
@@ -1232,16 +1232,18 @@
 %0A%0A      
+ 
+ 
 int byte
@@ -1249,16 +1249,18 @@
 esRead;%0A
+  
       by
@@ -1302,16 +1302,18 @@
 ;%0A      
+ 
+ 
 while ((
@@ -1354,32 +1354,34 @@
  %3E 0) %7B%0A        
+  
 clientOut.write(
@@ -1403,32 +1403,34 @@
 sRead);%0A        
+ 
+ 
 clientOut.flush(
@@ -1434,26 +1434,30 @@
 sh();%0A      
-%7D%0A
+  %7D%0A  
       System
@@ -1517,24 +1517,26 @@
 eCount());%0A%0A
+  
       server
@@ -1553,24 +1553,26 @@
 se();%0A      
+  
 clientSocket
@@ -1577,24 +1577,26 @@
 et.close();%0A
+  
     %7D catch 
@@ -1619,24 +1619,26 @@
  e) %7B%0A      
+  
 System.out.p
@@ -1675,16 +1675,182 @@
 n.%5Cn%22);%0A
+      %7D catch (UnknownHostException e) %7B%0A        clientSocket.getOutputStream().write(%22HTTP/1.0 502 Bad Gateway%5Cr%5Cn%5Cr%5Cn%22.getBytes());%0A        clientSocket.close();%0A  
     %7D ca
@@ -1867,24 +1867,26 @@
 eption e) %7B%0A
+  
       e.prin
@@ -1900,24 +1900,26 @@
 race();%0A    
+  
 %7D catch (Mal
@@ -1946,28 +1946,16 @@
 on e) %7B%0A
-      try %7B%0A
         
@@ -2048,32 +2048,38 @@
 close();%0A      %7D
+%0A    %7D
  catch (IOExcept
@@ -2094,18 +2094,16 @@
 %7B%0A      
-  
 ex.print
@@ -2112,32 +2112,24 @@
 ackTrace();%0A
-      %7D%0A
     %7D%0A  %7D%0A%7D%0A

Handle `UnknownHostException`