Simple Proxy Server in Java

In this post, I am going to show how a simple Proxy server can be designed in Java which will provide the core functionalities of a proxy. From Wikipedia, “a proxy server is a server (a computer system or an application program) that acts as an intermediary for requests from clients seeking resources from other servers.“The proxy server generally has some resources, or has access to some resources and when it receives request from a client, it access the appropriate resource and sends back the response.

So it serves two purposes, giving access to a resource which the client do not have access and it hides the real client who needs the resource. The second part is used for the anonymous browsing in Internet using anonymous proxy servers. Although this may not be as “anonymous” as it sounds because the proxy server which you connect to can maintain logs about the clients who are connecting to the server, and also the bigger risk being the data theft. Since the “anonymous” proxy server has access to all the request you send, there is risk of that data being exposed unless there is some kind of encryption in place between the client and the proxy server.

If you are in a network, and the machine which you are using don’t have access to Internet but another machine in the same subnet has access to Internet, then you can run this proxy application in the machine which has Internet access and in your local machine, you can configure your web browser to use the IP and Port number of the machine where the proxy is running in the LAN/Network settings. Once done, you should be able to access the Internet. This is one of the practical use for proxy servers.

The proxy server which we will be designing will be a simple HTTP proxy which gets web requests based on HTTP protocol and sends back response in the same protocol. We will start by declaring some constants.

int proxyServerPortNumber = 7879;
int webServerPortNumber = 80;
String webServerIpAddress = "192.168.1.1";
final int PROXY_SERVER_TIME_OUT = 5000;
final int SOCKET_TIME_OUT = 2000;

proxyServerPortNumber defines the port where the proxy server will be listening. You can use any port number which is not used by other process / standard port.

webServerIpAddress and webServerPortNumber defines the IP/port where the server can access the resources. Since we are designing this to access websites over http, the port is defined as 80 and the IP should be a machine which has Internet access (can be localhost too)

PROXY_SERVER_TIME_OUT and SOCKET_TIME_OUT are standard parameters defined for Server and network socket timeout. You can adjust this based on your needs.

Now we need to start the Java class to bind to the port number defined and to run in a infinite loop or as a daemon thread, so that it keeps on listening for requests. In this example, we will be using the infinite loop.

try {
    serverSocket = new ServerSocket(proxyServerPortNumber);
} catch(Exception exc) {
        System.exit(0);
}

Now the process will be listening in the port 7879 for requests from clients. Now, let’s open an infinte loop and make a connection to the resource, in our case the web server.

socketProxy = new Socket(InetAddress.getByName(webServerIpAddress),webServerPortNumber);
socketProxy.setSoTimeout(PROXY_SERVER_TIME_OUT);
socket = serverSocket.accept();
socket.setSoTimeout(SOCKET_TIME_OUT);
inputStream = socket.getInputStream();

The request from the client will be received by Input Stream, so once we are connected, we will be sending this Input Stream which is nothing but a normal HTTP REQ object to the server which has the resource or as in our case the machine connected to Internet. The server will respond with the response which will be a HTTP RES over the Java Output Stream. We will be forwarding this output stream to the client which will be rendered in the application which the client requested in. That is if the request was sent through command line, the entire HTML will be printed, if its a browser the page will be rendered.

try {
    while( (intCounter = in.read()) != -1) {
        if(intCounter == -1) break;
        if(!bREQ)
            bREQ = true;
        pOutputStream.write(intCounter);
        if(byteCheckFl > 0) {
            break;
        }
        if(intCounter == 13 && intPrevCounter == 10)
            byteCheckFl++;
        intPrevCounter = intCounter;
    }
} catch(Exception e) {
    if(!bREQ) {
        continue;
    }
}

pOutputStream.flush();
pIutputStream = socketProxy.getInputStream();
outputStream = socket.getOutputStream();
try {
    while( (intCounter = pIutputStream.read()) != -1) {
        outputStream.write(intCounter);
    }
} catch(Exception e) {
}
outputStream.flush();

Make sure to close all the opened sockets and connections once the response is sent. Since this whole code is running in an infinite loop, the server will keep on waiting for the requests and sending the responses back. This is a crude implementation of the concept and there is room for a lot more improvements (like supporting SSL), but this should serve as a foundation to make the proxy a robust one.

We can easily make this Java class as a Win32 service, so that it will always run in background and starts along with the OS. That will need some work with JNI. I will explain that in a later post.