Trying to detect end of headers in http request

I can't seem to find a way to see how the headers end, the only reason I need to do this is so that I can use the content-length to let me know when to stop reader from the socket. If there is another way to do this I would love to hear it, lol.

thanks in advance,

- thom

publicvoid run()

{

ServerSocket serverSocket =null;

int port = 8080;

try

{

serverSocket =new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));

}

catch (IOException e)

{

e.printStackTrace();

System.exit(1);

}

// Loop waiting for a request

while (isActive)

{

Socket socket =null;

BufferedReader input =null;

PrintStream output =null;

try

{

socket = serverSocket.accept();

input =new BufferedReader(new InputStreamReader(socket.getInputStream()));

output =new PrintStream(socket.getOutputStream());

Properties headers =new Properties();

StringBuilder inputTotal =new StringBuilder();

String inputLine =null;

// get our content length

int contentLength = 0;

int contentLengthMax = 0;

while ((inputLine = input.readLine()) !=null)

{

String[] headerVar = inputLine.split(":");

if (headerVar.length > 1)

{

headers.setProperty(headerVar[0].trim(), headerVar[1].trim());

}

System.out.println("My content-length = " + headers.getProperty("Content-Length"));

inputTotal.append(inputLine);

if ( headers.getProperty("Content-Length") !=null )

{

contentLengthMax = Integer.parseInt(headers.getProperty("Content-Length"));

System.out.println(contentLength +"/" + contentLengthMax);

if ( contentLength >= contentLengthMax )

{

System.out.println("End of content, breaking loop!!");

break;

}

}

}

// create Request object and parse

/*inputLine = null;

while( ((inputLine = input.readLine()) != null) )

{

if (inputTotal.length() >= contentLength)

{

System.out.println("breaking!");

break;

}

inputTotal.append(inputLine);

}*/

// create Response object

//output.print( "INPUT = " + inputTotal );

System.out.println("INPUT = " + inputTotal );

// Close the socket

socket.close();

}

catch (Exception e)

{

e.printStackTrace();

continue;

}

}

}

[4424 byte] By [the_thoma] at [2007-11-27 2:30:53]
# 1
The end of headers in HTTP is the first quad of \r\n\r\n . This applies to both the request and response. See - http://www.w3.org/Protocols/rfc1945/rfc1945 .
sabre150a at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...
# 2
so I should be able to do a String.contains("\r\n\r\n") to see where the end is? I haven't had any luck doing a contains("\n") and I figured I couldn't search these characters.
the_thoma at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...
# 3
can't seem to find special characters in a String, is it possible to find them in a byte[] (and how)?
the_thoma at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...
# 4

solution:

to stop the read() from blocking the rest of the loop from functioning just gather a byte array and the max allocated space of the total number of characters..

// Loop waiting for a request

while (isActive)

{

Socket socket = null;

InputStream input = null;

PrintStream output = null;

try

{

String[] inputTotal = null;

// setup socket, input and output channel

socket = serverSocket.accept();

input = socket.getInputStream();

output = new PrintStream(socket.getOutputStream());

// create a byte array to hold input

byte[] data = new byte [ input.available() ];

socket.getInputStream().read( data );

// split the headers from the content (W3 standard)

inputTotal = new String(data).split("\r\n\r\n");

// inputTotal[1] is the content, inputTotal[0] is the header information

output.write( inputTotal[1] );

output.flush();

// Close the socket

socket.close();

}

catch (Exception e)

{

e.printStackTrace();

continue;

}

}

the_thoma at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...
# 5

You can't use available() - it does not indicate anything useful. You can't use split() like this. The best way to tackle this is to read a line at a time and when you get an empty line it means you have reached the end of the headers. How you read the line is up to you. You can cheat and just use a BufferedItreamReader but if body is not text you will have problems.

Several years ago I wrote a very simple HTTP server and wrote an InputStream that had a readLine() method that forced the end-of-line to be \r\n and that assumed that the headers were ASCII. Once I had finished reading the headers I was able to continue reading the InputStream as binary data. This worked well.

sabre150a at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...
# 6

I think at this point it would be much easier to read the whole thing as bytes and browse for the "\r\n\r\n", then convert what comes before to be the header.

An even better method is to read from the socket as much as is available, and to feed it into an HTTP parser that takes an uncapped byte stream, and determines, on it's own, when it reached the end(similar to reading a deflate stream and letting the inflater tell you when the stream should end), while at the same time extracting the desired information. You keep reading until the parser tells you "okay, I have it all", or reports some error.

Parsers like that are quite an exercise in coding, but are not that tough.

SlugFillera at 2007-7-12 2:45:06 > top of Java-index,Core,Core APIs...