Re: mod_perl and Transfer-Encoding: chunked

André Warnier <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
Not disregarding the other answers to your questions, but I believe that maybe one aspect 
has been neglected here.

Bill Moseley wrote:
> For requests that are chunked (Transfer-Encoding: chunked and no
> Content-Length header) calling $r->read returns *unchunked* data from the
> socket.
> 
> That's indeed handy.  Is that mod_perl doing that un-chunking or is it
> Apache?
> 
> But, it leads to some questions.
> 
> First, if $r->read reads unchunked data then why is there a
> Transfer-Encoding header saying that the content is chunked?   Shouldn't
> that header be removed?   How does one know if the content is chunked or
> not, otherwise?

The real question is : does one need to know ?

The transfer-coding is something that even an intermediate HTTP proxy may
be allowed to change, for reasons to do with transport of the request along a section of 
the network path.
It should be entirely transparent to the application receiving the data.

> 
> Second, if there's no Content-Length header then how does one know how much
> data to read using $r->read?
> 
> One answer is until $r->read returns zero bytes, of course.  

Indeed. That means that the end of *this* request body has been encountered.

But, is
> that guaranteed to always be the case, even for, say, pipelined requests?

It should be, because $r concerns the present request being processed.
If there is another request pipelined onto that same connection, it is a separate request 
and a different $r.

> My guess is yes because whatever is de-chunking the request knows to stop
> after reading the last chunk, trailer and empty line.   Can
> anyone elaborate on how Apache/mod_perl is doing this?
> 

I can't really, but it should be done by something at some fairly low level.  It should be 
the *first* thing which happens to the request body, before any request-level body access 
is allowed.
(Similarly, at the response level, "chunking" a response body should be the last thing 
happening before the request is put on the wire out.)

> 
> Perhaps I'm approaching this incorrectly, but this is all a bit untidy.
> 
> I'm using Catalyst and Catalyst needs a Content-Length.

I would posit then that Catalyst is wrong (or not compatible with HTTP 1.1 in that respect).

   So, I have a Plack
> Middleware component that creates a temporary file writing the buffer from
> $r->read( my $buffer, 64 * 1024 ) until that returns zero bytes.  I pass
> this file handle onto Catalyst.
> 

So what you wrote then is a patch to Catalyst.

> Then, for some content-types, Catalyst (via HTTP::Body) writes the body to *
> another* temp file.    I don't know how Apache/mod_perl does its
> de-chunking, but I can call $r->read with a huge buffer length and Apache
> returns that.  So, maybe Apache is buffering to disk, too.
> 
> In other words, for each tiny chunked JSON POST or PUT I'm creating two (or
> three?) temp files which doesn't seem ideal.
> 
> 

I realise that my comments above don't really help you in your specific predicament, but I 
just felt that it was good to put things back in their place, particularly that at the $r 
(request) level, you should not have to know if the request came in chunked or not.
And that if a client sends a request with a chunked body, you are not necessarily gettting 
it so on the server on the which application runs.  And vice-versa.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.