I am trying to make a proxy server in java and I was able to make a working proxy which handles http requests properly. After searching a lot I was also able to extend my program for https requests by following this answer to a similar question: https://stackoverflow.com/a/9389125/5309299
Here's my code after a TCP connection is established between client and proxy:
String request = "";
byte[] requestByteArr;
//read the complete request
while(true){
String requestLine = bufferedReaderFromClient.readLine() + "\r\n";
if (requestLine.trim().length()==0 && !request.equals("")){
request+=requestLine;
requestByteArr = request.getBytes();
System.out.println(request);
break;
} else {
request+=requestLine;
}
}
String hostname = getHostFromRequest(request);
int remoteport = getRemotePortFromRequest(request);
if (request.startsWith("CONNECT")){
//establish connection between host and proxy
final Socket hostSocket = new Socket(hostname, remoteport);
//tell client that connection was successful
String statusLine = "HTTP/1.1 200 Connection established \n" + "Proxy-agent: ProxyServer/1.0\n" + "\r\n";
outToClient.write(statusLine.getBytes());
outToClient.flush();
//new thread to handle incoming responses from host
new Thread(){
public void run(){
try{
InputStream inFromHost = hostSocket.getInputStream();
while(true){
byte[] bufread = new byte[128];
int bytes_received;
while ((bytes_received = inFromHost.read(bufread)) > 0){
outToClient.write(bufread, 0, bytes_received);
outToClient.flush();
}
}
} catch (IOException e){
e.printStackTrace();
}
}
}.start();
//main thread handles incoming requests from client
OutputStream outToHost = hostSocket.getOutputStream();
while (true){
byte[] bufread = new byte[128];
int bytes_received;
while ((bytes_received = inFromClient.read(bufread)) > 0){
outToHost.write(bufread, 0, bytes_received);
outToHost.flush();
}
}
}
Obviously, this only works for one host, i.e. when a client (e.g. chrome browser) sends a CONNECT request for one host (e.g. "www.google.com:443"). I want my client to be able to connect with multiple hosts. The problem is that since all the requests that come after CONNECT request are encrypted, my proxy server will not be able to determine which request is meant for which host, so it cannot forward the requests.