httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Re: cvs commit: apache-2.0/src/main http_protocol.c
Date Fri, 13 Oct 2000 00:33:18 GMT

> > I'll be working backwards, because I think it will make more sense.  Take
> > the gunzip filter.  The content length tells Apache when to stop reading
> > data from the network.  Greg, in what you said above, we end up losing
> > data.  It is a sneaky loss, but it exists.  Think about it this way.  We
> > start with a content length of 25.  This is 25 bytes of gzip'ed data that
> > actually represents 35 bytes.  We start by calling down through
> > gunzip_filter to the http_filter, saying give back at most 25 bytes.  The
> > http_filter gives 25 bytes to the gunzip filter, which uncompresses to 35
> > bytes.  Now the gunzip filter is only allowed to return 25 bytes, leaving
> > 10 that are saved off to the side.  The problem is that as far as Apache
> > is concerned, we have already read all the data from the network,
> BING! There is your error :-)
> "as far as Apache is concerned" ?? Nope. We have only read all the data from
> the network when the top filter on input_filters() returns APR_EOF. Don't
> look in any magic fields of the request or conn_rec. Wait for APR_EOF.
> [ the underlying filters will manage when to send APR_EOF ]
> ap_get_client_block() shouldn't look at any fields in the request or conn to
> determine when "end" is. The only definition of "end" is APR_EOF.
> Caveat: we may need to distinguish APR_EOF -- between "socket closed" and
> "end of this request" ... I haven't thought about that part yet.

This is incorrect.  There is no such thing as EOF at end of
request.  There is only an EOF when the connection closes.  There is no
way for low level filters to know when they have hit the end of a
request.  If that were possible most of this discussion would be moot.

There is one solution I can think of for how to do this, but it is
completely wrong and ugly and it makes absolutely no sense, so if we ever
tried to implement it I would veto it because it is just wrong.  The idea
is that on the first call down to http_filter we pass the
content-length.  On subsequent calls, we just read until we have read that
much data, ignoring all other values of content-length that are passed
down.  As I said this is just wrong.

As for why lower level filter can't know about the end of a request, it
has to do with the protocol.  There are two basic ways to signal the end
of a request body (I am ignoring multi-part/byteranges for now).  The
first is to have a content-length in the request headers.  The second is
to use chunked encoding.  Both of these things can only be determined by
looking at the request_rec.  However, the http_filter is a connection
based filter, so it doesn't have access to a request_rec, therefore it
doesn't have access to the headers.  This means that the filter needs to
be told how much data there is going to be.

> > What else does this mean?  It means that all of a sudden
> > ap_get_client_block can actually receive more data from the filters than
> > it asked for.
> Nope. This would still be restricted to what ap_get_client_block() asked
> for, from the top input filter. *That* filter may need to do some set-aside,
> but that isn't get_client_block's concern.

See above.  It isn't possible.

> > I dislike this, and there is a big part of me that thinks we are violating
> > the HTTP protocol by allowing filters to expand the body data like
> > this.  The other thing that needs to be noted, is that if we change the
> > content-length, then that information also needs to be changed in the
> > request_rec.
> 1) we aren't violating HTTP. it was designed for this kind of expansion.
> 2) don't put content-length into the request_rec. that is a private matter
>    for the chunk_filter, I believe. (not sure who's responsible if the chunk
>    filter isn't installed; but I know that we should not be changing the
>    value sitting in the request_rec (nobody should examine that value!).

This won't work.  It looks like the chunking code in ap_get_client_block
is currently setting the Content-Length, so the chunk_filter will need to
set that correctly.  But that also tells me that there is a reason we do
that.  If nobody inside Apache cared about the Content-Length, then the
chunk code wouldn't need to set it.  A quick grep shows mod_dav getting
the value, but since you know mod_dav 1000 x better than me, I'll assume
you know why, and you won't care if it is set incorrectly.

If it does need to be set correctly, than ap_get_client_block needs to set
it to the new length after the transformations.


Ryan Bloom               
406 29th St.
San Francisco, CA 94131

View raw message