views:

287

answers:

5

I am currently working on a simple proxy server, which receives http request from browser, process it, then forward it to the desire web server.

I try to get the request from the input stream of the socket connected by the browser, everything is fine except that the stream get stuck after receiving the last block of data.

My code is in fact very simple, as shown below:

ServerSocket servSocket = new ServerSocket(8282);  
Socket workSocket = servSocket.accept();  
InputStream inStream = workSocket.getInputStream();  
byte[] buffer = new byte[1024];  
int numberRead = 0;  

while ((numberRead = inStream.read(buffer, 0, 1024)) != -1){  
System.out.println(new String(buffer));  
}  

The loop simply cannot exit, even the request reception is finished.

Is there any method to workaround this problem?

Thanks in advance for any advice.

A: 

It will cycle until the connection is closed, and the client is probably waiting for HTTP response from you and doesn't close it.

Dmitry Yudakov
In this case, it sounds like I have no way to handle the request except using threads?
CL
Well, you could use select and non-blocking reading/writing - one thread will do in this case. I'm not a Java expert though and cannot give you more details.
Dmitry Yudakov
+1  A: 

As in InputStream javadoc the method will block until the data is available or the EOF is encountered. So, the other side of Socket needs to close it - then the inStream.read() call will return.

Another method is to send the size of message you want to read first, so you know ahead how many bytes you have to read. Or you can use BufferedReader to read from socket in line-wise way. BufferedReader has a method readLine() which returns every time a line is read, which should work for you as HTTP protocol packages are nice divided into lines.

pajton
However, the client connecting to the socket is a browser, like firefox or IE.I have no means to control the browser, neither closing the socket nor sending the size of message at the beginning.
CL
Ok, so I'd suggest using BufferedReader. Every HTTP packet is line delimited, so you will read a couple of lines and be able to say whether this is all of tha packet (it will always end with newline).
pajton
I tried the BufferedReader approach, but the stream still stucks.
CL
It stucks when there is no more lines to read, however by that time you should have read all the response already. Are you able to read at least one line in your tests?
pajton
In fact I can read all the lines, but I don't know how to quit the loop after that.
CL
Ok, now I understand. If you are working on a proxy, then you probably need to read the packets all the time in one loop and process them in another thread.
pajton
A: 

The browser is waiting for a response before it closes the connection. Your read-method on the other hand will block until the stream/connection is closed or new data is received.

Hardcoded
A: 

Not a direct solution according to your current code.

As HTTP is a line based protocol, you might want to use a Buffered Reader and call readLine() on it.

Atmocreations
I tried the BufferedReader approach, but the stream still stucks.
CL
A: 

The when a http request comes in it will always be concluded with a blank line, for example:

GET /someFile.html HTTP/1.1
Host: www.asdf.com

After sending that request the client connection will then wait for a response from the server before closing the connection. So if you want to parse the request from the user you are probably better off using a BufferedReader and reading full lines until you reach a lines of text that is blank line.

Yanamon