How to read HTTP chunk-size from servlet?

S

Scott Harper

I have a servlet that accepts POSTs from a J2ME client. I need the length of
the message body.

Ordinarily, I'd just read the Content-Length header (or call the
ServletRequest.getContentLength() method). Unfortunately, that header isn't
present. I'm pretty sure this is because there is a Transfer-Encoding header
present with a value of "chunked". Section 4.4 of the HTTP spec makes it
sound like the Transfer-Encoding and Content-Length headers don't always play
well together.

I'm not sure how the Transfer-Encoding header is getting added (I'm not
explicitly putting it there). I'm guessing that the MIDlet implementation is
putting it in there by default. At any rate, the size of data being passed is
certainly not large enough to warrant chunking.

Anyway, sections 3.6 and 3.6.1 of the HTTP spec seem to describe a way to get
the chunk size from the message body. But it sort of sounds like you need to
parse through the binary http packet to get at that data. There don't appear
to be any ServletRequest methods to get to it...

Does anyone have any pointers or examples on how to get this data?


thanks,
Scott
 
D

Daniel Pitts

Scott said:
I have a servlet that accepts POSTs from a J2ME client. I need the length of
the message body.

Ordinarily, I'd just read the Content-Length header (or call the
ServletRequest.getContentLength() method). Unfortunately, that header isn't
present. I'm pretty sure this is because there is a Transfer-Encoding header
present with a value of "chunked". Section 4.4 of the HTTP spec makes it
sound like the Transfer-Encoding and Content-Length headers don't always play
well together.

I'm not sure how the Transfer-Encoding header is getting added (I'm not
explicitly putting it there). I'm guessing that the MIDlet implementation is
putting it in there by default. At any rate, the size of data being passed is
certainly not large enough to warrant chunking.

Anyway, sections 3.6 and 3.6.1 of the HTTP spec seem to describe a way to get
the chunk size from the message body. But it sort of sounds like you need to
parse through the binary http packet to get at that data. There don't appear
to be any ServletRequest methods to get to it...

Does anyone have any pointers or examples on how to get this data?


thanks,
Scott
My first thought is "why do you need to know the length of the POST
data"? That should all be taken care of for you by the framework.

My second thought is "http metadata is text, there isn't a binary http
packet for the headers"...
My third thought is "why am I iterating my thoughts this way"?

As far as I know, you shouldn't need to concern yourself with the
Content-Length header from a user-agent. If you give me a good reason
why, I'll remember it when I need it :)
 
R

Rogan Dawes

Daniel said:
My first thought is "why do you need to know the length of the POST
data"? That should all be taken care of for you by the framework.

My second thought is "http metadata is text, there isn't a binary http
packet for the headers"...
My third thought is "why am I iterating my thoughts this way"?

As far as I know, you shouldn't need to concern yourself with the
Content-Length header from a user-agent. If you give me a good reason
why, I'll remember it when I need it :)

Use ServletRequest.getInputStream() or .getReader(), and simply read
from them.

If you are trying to limit the size of the body you will accept, simply
keep a tally of how many bytes you have read, and bail if you read too many.

In case you are not familiar with the idiom, something like this will
probably work for you:

InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[2048];
while ((int got=is.read(buff))>0) {
baos.write(buff,0,got);
if (baos.size()>MAX)
throw new Exception("Too big");
}
byte[] requestBody = baos.toByteArray();

Rogan

P.S. Daniel: The InputStream that you get from getInputStream() does the
de-chunking for you automatically, so you don't actually get to see what
size the chunks were. Google for ChunkedInputStream for more info.
 
L

Lew

Rogan said:
If you are trying to limit the size of the body you will accept, simply
keep a tally of how many bytes you have read, and bail if you read too
many.

In case you are not familiar with the idiom, something like this will
probably work for you:

InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[2048];
while ((int got=is.read(buff))>0) {
baos.write(buff,0,got);
if (baos.size()>MAX)
throw new Exception("Too big");
}
byte[] requestBody = baos.toByteArray();

Or, to prevent going over before you get there, put the test before the write().

for ( int got; (got = is.read(buff)) > 0; )
{
if ( (baos.size() + got) > MAX )
throw new Exception("Too big");
baos.write(buff,0,got);
}

Works out about the same if the first version of MAX is buff.length larger
than the second. (My use of the 'for' idiom vs. the 'while' idiom is not
relevant, just my own style. I thought folks might benefit from seeing both
forms.)

- Lew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top