Context
I'm trying to build a simple HTTP web proxy using Java. Right now all I have is something that listens on port 5041 for HTTP requests. Right now I have 2 classes. The Proxy
class opens a ServerSocket
on the port, I call this socket the welcomeSocket
. After this port is opened Proxy
starts a new Connection
thread everytime welcomeSocket
accepts a new socket. The Connection
class has some simple logic to read the HTTP request header information. Later this class will be extended for further functionality. Thanks for any help.
Problems
When I run my proxy and configure my browser to point to the proxy I'm getting SocketException
errors saying that my socket is closed. I'm not sure how these are coming about. Also it appears that Connection
threads are being created but don't necessarily output HTTP header info. This is apparent because output shows repetetive NEW connection thread created
prints but no header info after the print.
Proxy Class
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Proxy {
// Port is 5000 + 41
private final int PORT;
private ServerSocket welcomeSocket = null;
private boolean listening = true;
public Proxy(int port) {
PORT = port;
try {
welcomeSocket = new ServerSocket(PORT);
listenForConnectionRequests();
} catch (IOException e) {
System.err.println("There was a problem while creating the welcome socket");
e.printStackTrace();
System.exit(-1);
}
}
public void listenForConnectionRequests() {
System.out.println("Listening for connection requests at " + PORT + "\n");
while (listening) {
try {
new Connection(welcomeSocket.accept()).start();
} catch (IOException e) {
System.err.println("I/O error occured while waiting for a connection.");
e.printStackTrace();
}
}
}
}
Connection Class
public class Connection extends Thread {
private Socket connectionSocket = null;
private ArrayList<String> requestHeaders = new ArrayList<String>();
private boolean running = true;
private OutputStream os;
private InputStream is;
public Connection(Socket connectionSocket) {
super("Proxy");
System.out.println("NEW connection thread created");
this.connectionSocket = connectionSocket;
}
public void run() {
while (running) {
readHttpHeader();
}
}
private void stopRunning() {
running = false;
System.err.println("Stopping thread.");
closeEverything();
}
private void readHttpHeader() {
try {
os = connectionSocket.getOutputStream();
} catch (IOException e) {
System.err.println("Problem getting output stream from connection socket.");
e.printStackTrace();
stopRunning();
}
try {
is = connectionSocket.getInputStream();
} catch (IOException e) {
System.err.println("Problem getting input stream from connection socket.");
e.printStackTrace();
stopRunning();
}
String input;
BufferedReader in = null;
DataOutputStream out = null;
try {
in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
out = new DataOutputStream(connectionSocket.getOutputStream());
while ((input = in.readLine()) != null) {
requestHeaders.add(input);
System.out.println(input);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void closeEverything() {
try {
connectionSocket.close();
is.close();
os.close();
} catch (IOException e) {
System.err.println("Problem closing connection or streams");
e.printStackTrace();
stopRunning();
}
}
}
Output after testing some webpages
Listening for connection requests at 5041
NEW connection thread created
GET http://127.0.0.1:63342/browserConnection/buildInfo HTTP/1.1
Host: 127.0.0.1:63342
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
NEW connection thread created
NEW connection thread created
GET http://google.com/ HTTP/1.1
Host: google.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
X-Client-Data: CKK2yQEIwbbJAQj9lcoB
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: OGP=-5061574:; SID=DQAAAMoCAACmU0EuiAZrQAuo8mgssp5cukiLvNn13ryGL2GeGswaF8Cmv2NIxyW_nnC7ihLpQRaY0gdlYg4K91TStT2aPHo3PWFhExCr5zD0yywqgMwsXuWgQedtdi8Lc6tsL0Nz2WSt8j1Is6Dw53SYpWw-Ukis9d386YATJRYdsDUhVsb3h-pe-QrKNBL3deaxIlMIb5itaAWVTSVkRUVcocns6S-mAopRFT-k8YMKXKVeouztBQhblI1YQUKAtMCqv55ZllmFyfZSQcqmbcsJx19ofBLnl6u2KByIwBLwMMa1DrK1YketAgvgxUzlrfanvTm94VQ7Lie9rppG-up1cNlDsu4XbXrIOkG2bdbD7J2SdjwmI_Hf9IrLl3IelDvdCfQol3CT8rdAMk1p7zBMQq5L_JfiiCLmjNd9VA0CiadcB-6dIBWnGGThNYEOkrU11i2qeiEPtvJqDx_7kyuphkFuQh8b5GI7f5xg-uVmLfjaO4Q7q5EiV7BTt5jacajRibvPsqK77lEw9_UTnPvXOkW1jmfJOKx85rAztVpV2vymO_dGMiG_ehiD4R6CO6ifCnHjij5TKUeWeSEzQdtdDsKGL3MAMSg1bZVKcmc3Veq77AwWZa996gUkyEdD1dJ5c4eTodTEjTx8KiUDEufPGxQtjyOEuT8rnY_MWvDTFUx0os-aMZfcYsLrTmJ6mWpYzKa5wnCvFHKnjBL24UddbBmhhaklLcOghJEH8kcVEVWvNuKC145OIzxwZA2CmTCfEDzymOd6pTGlwl9P7VInl2ro_SkoNmEn6VqUWLRC0zH1jEWZhpkNf9kbpLmWBS-xLWMBpvgPu7ysVBf7qR8_YlzyVprCdRDAR4mrciRaOaswHvWCWgU8EJk_gF8PgiP_D2WEtw8uJR6b4IL_ggxpmckGdHM7yUvkel9jWeFQxrazmF1f1c6SHBooSO6t-tCW7-Hw44A; HSID=A_KCc1Le4o6JlU760; APISID=hE0OzriLy98RcM4M/ALgi7Gky2rmmyyiDE; NID=77=dmymZT8yk5KfHAaIyzxhzvKfG_fvBjPwDpg-yTfz_5cBDKAsqL9n010br6xg1dSRrSKhS--_RYLoCuDodOzAHiaWS11pBB-4Npc9eQbqwkLnaf-nzeqNC_fwNSDElB7qfUmmvnZSHX1mowllXfpIM8cLm-ewYD0tGdHbpfvbAxkfH_jIwQKj-pS0f6ZkcodJ2CEEeoDhMUbZDAOfBKUUhM5qvLxE3curLhef6pftojQo0QpTumhoky2_pWR1lWP-5W0lPN29lMDSdeYrW5Umz_3jNHPRyMiGFwzNMIV9r9RUoyO50JreK057mDnzNygESvk_fBHlt49b2U6tesQ5NAtaAmL4VaWsAuj3jKEvjWTxSgSVrUeWwPC84hjn3liuGlBulWg; OGPC=5061900-22:5061918-27:5061934-15:5061921-40:5061937-46:5061933-25:5061941-6:5061574-1:5061940-57:5061952-26:5061975-14:5061983-7:
Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:916)
at Connection.readHttpHeader(Connection.java:46)
at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:54)
at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:65)
at Connection.run(Connection.java:34)
Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:916)
at Connection.readHttpHeader(Connection.java:46)
at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:54)
at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:65)
at Connection.run(Connection.java:34)
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
GET http://www.yelp.com/ HTTP/1.1
Host: www.yelp.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: __cfduid=dd3ccfb39916d84ca8053ba95c0ca89fe1457229239; yuv=pOdmTZnrxWdr1NhFcLyF8cCB7Pj5l2tN3CSqNp0fiz0yKun0fbD0MHFrIo4K432S0pKC_-Sl9QijvKAX5u1iUJMmwZ2EnL4p; hl=en_US; fd=0; D_SID=172.250.60.189:SscPaGXtn/I/Skx3ISxQZOtF5qtsm+TmywEwnqXsiuo; qntcst=D%2CT%2C43606%2C43604%2C43602%2C43597%2C43596%2C43595%2C43583%2C43582%2C43581%2C37336%2C34588%2C34585%2C27425%2C27424%2C20052%2C20047%2C20040%2C20021%2C20020%2C20015%2C19991%2C19989%2C19958%2C19948%2C19947%2C19945%2C19944%2C19942%2C19941%2C19939%2C19936%2C19934%2C19932; __qca=P0-1476739725-1457229248633; fbm_97534753161=base_domain=.yelp.com; location=%7B%22city%22%3A+%22Seattle%22%2C+%22zip%22%3A+%22%22%2C+%22country%22%3A+%22US%22%2C+%22address2%22%3A+%22%22%2C+%22address3%22%3A+%22%22%2C+%22state%22%3A+%22WA%22%2C+%22address1%22%3A+%22%22%2C+%22unformatted%22%3A+%22seattle%22%7D; bse=b955bbc7020253479a51b278e343d766; __utma=165223479.439363298.1457229244.1457383227.1457394139.4; __utmc=165223479; __utmz=165223479.1457383227.3.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __utmv=165223479.|4=account%20level=anon=1; _ga=GA1.2.C1BEB9B4D17FEEDD; D_PID=469F0452-18FF-3E05-8072-566D9785BE96; D_IID=EC337894-ADD2-36A6-848D-AA87DA4B1407; D_UID=6E67A9C8-F999-33A6-8838-4EBFBC9B943E; D_HID=qXtXeOzvXZDnGT33GPaUewyWk7KgXdgunNy1mqdkX7g
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.