Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Olaf,
On 12/27/2010 5:24 PM, Olaf Tomczak wrote:
2010/12/27 Christopher Schultz <ch...@christopherschultz.net>
Non-blocking just means that your request processor threads don't block
waiting for data to arrive. The requirements of reading the request --
including all the headers -- do not change with the connector. Tomcat
needs to read the entire set of headers in order to route the request to
the right host and webapp. Also, Tomcat must have all headers in order
to perform some operations -- such as responding to "getHeaders" calls
which sometimes require that multiple separate HTTP header lines be
merged into a single method return value.
I understand that the whole request must be read to start "request
processing" - I was just suggesting that from what I understand the
connector does not wait for the buffer to be completely filled before
starting to parse request line and headers. Isn't that right?
I don't believe the difference you describe would be detectable at any
level. The choice of connector does not change the logic for request
processing: only that of gathering the bytes from the request.
Business is slow these days, so let's muse a bit.
Tomcat is a HTTP server, and processes HTTP requests (a sub-category of HTTP Messages), as
defined in RFC 2616 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html).
Section 4 defines precisely what a message is, so I will not repeat it here.
But the essence is that there is a start-line, followed by a series of optional headers
lines, followed by one empty line (2 CR/LF in a row), sometimes followed by a body
(depends on request type).
There is no mention of a size limit for the headers part, nor any mention of any special
ordering of the individual headers.
In other words, as far as the RFC is concerned, there could be a million header lines, and
the "Host:" header could be the last one of them. (Except for a confusing example in
section 5.1.2, but then, such things happen in RFCs).
In other words also, if Tomcat started to parse the request headers before it is sure to
have all of them, it would have to store the results of such parsing in some temporary
holding area, because at that point it may not have seen the "Host:" header yet, and thus
not know which <Host> is supposed to handle this request (among other things).
And this would offer a major opening for anyone wanting to mount a DOS attack : just send
a few requests with very, very large header sections, to overwhelm this temporary holding
area.
I would thus imagine that the Tomcat developers in their wisdom seeked to prevent this, by
implementing a limit to how large a HTTP headers section would be reasonably expected to
be. And let's say that this is the maxHttpHeaderSize attribute, and that by default it is
set to about 8KB.
So the logic of reading the request reads it, up to either two consecutive CR/LF
indicating the end of the headers, /or/ a limit of maxHttpHeaderSize bytes, and then
declares that it has all the headers and attempts to parse them.
And if it so happens that the request would contain a larger header section,
tough.
That's the price to pay for avoiding the DOS attack.
Now the optional /body/ of the request is something else, because by then Tomcat already
knows which Host and which webapp should handle it, what format it is supposed to be in
etc.., and can feed it to this webapp one chunk at a time, with or without blocking a
Connector for the purpose.
The above is purely speculative, as I have not looked at the actual code to verify that it
is so. But this being rather central to what Tomcat is and does, I could imagine that by
the time one is able to confirm or deny this, he may well have read a good portion of the
Tomcat code.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org