How do I write a tunneling HTTP proxy in Java?

Martin Erren

[Note: the following is not a full-featured HTTP proxy. Other true HTTP proxies, like Squid, accept the CONNECT request, and can interpret the HTTP headers intelligently. This is a simple tunneling proxy, so it may not work correctly if you set it as your browser's proxy setting. Also, a more full-featured proxy has other features, like caching media. -Alex]

Recently I wrote a little Proxy in java and it works fine tunneling the requests with any ports to tomcat, but I didn't use apache (That's not the reason anyway) and NT instead of WIN98. I think it's either the configuration of the Proxy or the network configuration in your System

try this:


import java.net.*;
import java.io.*;
import java.util.*;

class ProxyConnection extends Thread {

 Socket fromClient;
 String host;
 int port;
 long timeout;


 ProxyConnection(Socket s, String host, int port, long timeout) {
  fromClient=s;
  this.host = host;
  this.port = port;
  this.timeout=timeout;
 }

 public void run() {
  InputStream clientIn = null;
  OutputStream clientOut = null;
  InputStream serverIn = null;
  OutputStream serverOut = null;
  Socket toServer = null;
  int r0=-1,r1=-1,ch=-1,i=-1;
  long time0 = new Date().getTime();
  long time1 = new Date().getTime();
  try {
   toServer = new Socket(host,port);
   Proxy.display("open connection to:"+toServer+"(timeout="+timeout+" ms)");
   clientIn = fromClient.getInputStream();
   clientOut = new BufferedOutputStream(fromClient.getOutputStream());
   serverIn = toServer.getInputStream();
   serverOut = new BufferedOutputStream(toServer.getOutputStream());
   while(r0!=0 || r1!=0 || (time1-time0)<=timeout) {
    while((r0=clientIn.available())>0) {
     Proxy.println(""); Proxy.println("<<<"+r0+" bytes from client");
     Proxy.display(""); Proxy.display("<<<"+r0+" bytes from client");
     for(i=0; i<r0; i++) {
      ch = clientIn.read();
      if(ch!=-1) {
       serverOut.write(ch);
       Proxy.print(ch);
      } else {
       Proxy.display("client stream closed");
      }
     }
     time0=new Date().getTime();
     serverOut.flush();
    }
    while((r1=serverIn.available())>0) {
     Proxy.println(""); Proxy.println(">>>"+r1+" bytes from server");
     Proxy.display(""); Proxy.display(">>>"+r1+" bytes from server");
     for(i=0; i<r1; i++) {
      ch = serverIn.read();
      if(ch!=-1) {
       clientOut.write(ch);
       Proxy.print(ch);
      } else {
       Proxy.display("server stream closed");
      }
     }
     time0=new Date().getTime();
     clientOut.flush();
    }
    if(r0==0 && r1==0) {
     time1 = new Date().getTime();
     Thread.sleep(100);
     //Proxy.display("waiting:"+(time1-time0)+" ms");
    }
   }
  } catch(Throwable t) {
   Proxy.display("i="+i+" ch="+ch);
   t.printStackTrace(System.err);
  } finally {
   try {
    clientIn.close();
    clientOut.close();
    serverIn.close();
    serverOut.close();
    fromClient.close();
    toServer.close();
    Proxy.quit(time1-time0);
   } catch(Exception e) {
    e.printStackTrace(System.err);
   }
  }
 }
}

public class Proxy {

public static final String usageArgs =" <localport> <host> <port> <timeout_ms>";

static int clientCount;

public static synchronized void print(int i) {
 System.out.print((char) i);
}

public static synchronized void println(String s) {
 System.out.println(s);
}

public static synchronized void display(String s) {
 System.err.println(s);
}

public static synchronized void quit(long t) {
 display("...quit after waiting "+t+" ms");
 clientCount--;
}


public void run(int localport, String host, int port,long timeout) {
 try {
  ServerSocket sSocket = new ServerSocket(localport);
  while(true) {
   Socket cSocket=null;
   try {
    display("listening...");
    cSocket = sSocket.accept();
    if(cSocket!=null) {
     clientCount++;
     display("accepted as #"+clientCount+":"+cSocket);
     ProxyConnection c = new ProxyConnection(cSocket,host,port,timeout);
     c.run();
    }
   } catch(Exception e) {
    e.printStackTrace(System.err);
   }  
   try {
    cSocket.close();
   } catch(Exception e) {
    //fall thru
   }
  }
 } catch(Throwable t) {
  t.printStackTrace(System.err);
 }
}

public static void main(String[] argv) {
 Proxy self = new Proxy();
 
 if(argv.length>=3) {
  int localport = Integer.parseInt(argv[0]);
  String url = argv[1];
  int port = Integer.parseInt(argv[2]);
  int timeout = 30000;
  try {
   timeout=Integer.parseInt(argv[3]);
  } catch(Exception e) {}
  self.run(localport,url,port,timeout);
 } else {
  System.err.println("usage: java " + self.getClass().getName() + usageArgs);
 }
}

}//class

0 Comments  (click to add your comment)
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

About | Sitemap | Contact