views:

335

answers:

7

I am writing somewhat of a proxy program in Java. Here's how it works:

  1. The browser will be connected to the program.
  2. Any requests by the browser will be first be printed out to standard out, then forwarded to the server.
  3. The server then returns a response, which is also printed to standard out, then forwarded back to the browser.

My problem is, step 1 works, step two works, but step 3 fails. The program can get a response, and its printed off to standard out properly, but the browser can't seem to get it. I've modified the program to isolate the problem.

All its doing here, is printing the response directly to the browser:

 ServerSocket client = null;
 try {
      client = new ServerSocket(snoopPort);
 } catch (IOException e) {
      System.out.println("ERROR: Could not listen on port: " + snoopPort);
      System.exit(-1);
 }

 Socket clientSocket = null;
 try {
      clientSocket = client.accept();
 } catch (IOException e) {
      System.out.println("ERROR: Accept failed on port: " + snoopPort);
      System.exit(-1);
 }

 PrintWriter snoopOut = new PrintWriter(clientSocket.getOutputStream(), true);

 snoopOut.print("HTTP/1.1 200 OK\r\n");
 snoopOut.print("Date: Thu, 05 Feb 2009 06:37:28 GMT\r\n");
 snoopOut.print("Server: Apache\r\n");
 snoopOut.print("Set-Cookie: Apache=99.245.58.244.1233815848703045; path=/\r\n");
 snoopOut.print("Accept-Ranges: bytes\r\n");
 snoopOut.print("Transfer-Encoding: chunked\r\n");
 snoopOut.print("Content-Type: text/html\r\n");
 snoopOut.print("\r\n");
 snoopOut.print("<html><head><title>test</head><body>hello world!</body></html>\r\n");

 snoopOut.close();

 clientSocket.close();
 client.close();
A: 

Try a flush after writing to snoopOut.

mP
I've tried that as well, but the browser still doesn't get anything.
Anton
A: 

Try changing:

snoopOut.write(svrRead);

to

snoopOut.println(svrRead);
Marc Novakowski
That doesn't work either. Although, when I use "println", it crashes halfway through due to an IOException.
Anton
A: 

Did you try closing the clientSocket?

jdigital
Each while loop is running in seperate threads (so that they can read/write at the same time). Client, Server, and ClientSocket is being closed in one of the threads (the one where it is working), but only after execution is done.
Anton
A: 

Here's one theory: are you connecting to the server from the proxy when the program begins? Many webservers will drop the connection if it doesn't get any data from the socket for a few seconds (to avoid DOS attacks among other things). If this is the case, then maybe defer connecting to the server until the client has connected and you have read the request from the client.

Marc Novakowski
Good idea! I've tried to eliminate the web server altogether by directly printing the result that the browser's supposed to get, to the browser itself. Unfortunately, the browser still doesn't load the code. I've modified the code above, since it narrows the problem down.
Anton
A: 

Perhaps it's because println() only adds a single linefeed (LF) to the output, whereas the HTTP spec expects each line to end with a CRLF?

Marc Novakowski
Okay I tried that one, but the browser still gives me nothing. I gotta say though, thanks for helping me so far, appreciate it!
Anton
Not sure what else to suggest - perhaps snoop on the actual TCP/IP traffic using a program like wireshark. At least then you'll have a sense for where the data is going (or NOT going as the case may be) and when the connections are closed.
Marc Novakowski
A: 

IN your revised description, I'd guess you have a problem with the http message. Is this correct: "Transfer-Encoding: chunked" ? (doesn't looked chunked to me)

jdigital
A: 

Okay. I've semi-figured out the problem. The code? its perfect. Everything works. It was the environment I was running under.

I was testing it on a vista machine, and despite disabling all anti-virus and firewalls, it wouldn't let me connect to the port. When I took it back to work, it was flawless. Why? I still have to figure it out. But thanks for the help everyone!

Anton