Simple Java Proxy Server
import java.io.*;
import java.net.*;
import java.util.*;
public class Proxy
{
public static final String NEW_LINE = System.getProperty("line.separator");
public static final int BUFFER_SIZE = 1024 * 10;
public static final int PORT = 8888;
public static void main(String[] arg)
{
try
{
runServer();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void runServer() throws Exception
{
System.out.println("Proxy Server is Running...");
ServerSocket ss = new ServerSocket(PORT);
while (true)
{
Socket client = null;
BufferedOutputStream streamToClient = null;
BufferedReader readerFromClient = null;
Socket server = null;
BufferedInputStream streamFromServer = null;
PrintWriter writerToServer = null;
try
{
//Connect to Client
client = ss.accept();
streamToClient = new BufferedOutputStream(client.getOutputStream());
readerFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
//Read Request Action
String requestAction = readRequestAction(readerFromClient);
//Read Request Headers
LinkedHashMap<String, ArrayList<String>> requestMap = readRequestHeaders(readerFromClient);
//Read Request Body
String requestBody = readRequestBody(readerFromClient);
//Connect to Server
server = new Socket(getRequestHost(requestMap), getRequestPort(requestMap));
streamFromServer = new BufferedInputStream(server.getInputStream());
writerToServer = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
//Write Request Action
writeRequestAction(writerToServer, requestAction);
//Write Request Headers
writeRequestHeaders(writerToServer, requestMap);
//Write Request Body
writeRequestBody(writerToServer, requestBody);
//Finally, Proxy Response from Server to Client
byte[] buffer = new byte[BUFFER_SIZE];
int length;
while ((length = streamFromServer.read(buffer)) != -1)
{
streamToClient.write(buffer, 0, length);
streamToClient.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
//Close Connections/Sockets
if (writerToServer != null)
writerToServer.close();
if (streamToClient != null)
streamToClient.close();
if (server != null)
server.close();
if (client != null)
client.close();
}
}
}
//Request Stream Methods
public static String readRequestAction(BufferedReader reader) throws Exception
{
return reader.readLine();
}
public static LinkedHashMap<String, ArrayList<String>> readRequestHeaders(BufferedReader reader) throws Exception
{
LinkedHashMap<String, ArrayList<String>> requestMap = new LinkedHashMap<String, ArrayList<String>>();
String line;
while (reader.ready() && (line = reader.readLine()).length() > 0)
{
String[] pair = line.split(":", 2);
String key = pair[0].trim();
String value = pair[1].trim();
addRequestHeader(requestMap, key, value);
}
//Filter/Modify the Request Headers for optimal use with Proxy
removeRequestHeader(requestMap, "keep-alive");
removeRequestHeader(requestMap, "connection");
removeRequestHeader(requestMap, "proxy-connection");
addRequestHeader(requestMap, "connection", "close");
return requestMap;
}
public static String readRequestBody(BufferedReader reader) throws Exception
{
StringBuffer requestBody = new StringBuffer();
char[] buffer = new char[BUFFER_SIZE];
int length;
while (reader.ready() && (length = reader.read(buffer)) != -1)
{
requestBody.append(new String(buffer, 0, length));
}
return requestBody.toString();
}
public static void writeRequestAction(PrintWriter writer, String requestAction)
{
writer.println(requestAction);
writer.flush();
}
public static void writeRequestHeaders(PrintWriter writer, LinkedHashMap<String, ArrayList<String>> requestMap)
{
writer.println(requestHeadersToString(requestMap));
writer.flush();
}
public static void writeRequestBody(PrintWriter writer, String requestBody)
{
if (requestBody != null && requestBody.length() > 0)
{
writer.print(requestBody);
writer.flush();
}
}
//Request Helper Methods
public static String getRequestMethod(String requestAction)
{
return requestAction.split(" ", 3)[0];
}
public static String getRequestURL(String requestAction)
{
return requestAction.split(" ", 3)[1];
}
public static String getRequestProtocol(String requestAction)
{
return requestAction.split(" ", 3)[2];
}
public static String getRequestHost(LinkedHashMap<String, ArrayList<String>> requestMap)
{
String host = getRequestHeader(requestMap, "host");
if (host.contains(":"))
{
host = host.split(":", 2)[0];
}
return host;
}
public static int getRequestPort(LinkedHashMap<String, ArrayList<String>> requestMap)
{
int port = 80;
String host = getRequestHeader(requestMap, "host");
if (host.contains(":"))
{
port = Integer.parseInt(host.split(":", 2)[1]);
}
return port;
}
public static void addRequestHeader(LinkedHashMap<String, ArrayList<String>> requestMap, String key, String value)
{
key = key.toLowerCase();
if (requestMap.containsKey(key))
{
ArrayList<String> list = requestMap.get(key);
list.add(value);
}
else
{
ArrayList<String> list = new ArrayList<String>();
list.add(value);
requestMap.put(key, list);
}
}
public static void removeRequestHeader(LinkedHashMap<String, ArrayList<String>> requestMap, String key)
{
requestMap.remove(key);
}
public static String getRequestHeader(LinkedHashMap<String, ArrayList<String>> requestMap, String key)
{
key = key.toLowerCase();
if (requestMap.containsKey(key))
{
return requestMap.get(key).get(0);
}
return null;
}
public static void setRequestHeaders(LinkedHashMap<String, ArrayList<String>> requestMap, String key, ArrayList<String> value)
{
key = key.toLowerCase();
requestMap.put(key, value);
}
public static ArrayList<String> getRequestHeaders(LinkedHashMap<String, ArrayList<String>> requestMap, String key)
{
key = key.toLowerCase();
return requestMap.get(key);
}
public static String requestHeadersToString(LinkedHashMap<String, ArrayList<String>> requestMap)
{
StringBuilder requestString = new StringBuilder();
Iterator<Map.Entry<String, ArrayList<String>>> i = requestMap.entrySet().iterator();
while (i.hasNext())
{
Map.Entry<String, ArrayList<String>> pair = i.next();
String key = pair.getKey();
ArrayList<String> value = pair.getValue();
for (String s : value)
{
requestString.append(key);
requestString.append(": ");
requestString.append(s);
requestString.append(NEW_LINE);
}
}
return requestString.toString();
}
}