Re: mod_perl and Transfer-Encoding: chunked
Jim Schueler <[email protected]>
| Newsgroups | gmane.comp.apache.mod-perl |
|---|---|
| Message-ID | <[email protected]> |
In light of Joe Schaefer's response, I appear to be outgunned. So, if nothing else, can someone please clarify whether "de-chunked" means re-assembled? -Jim On Wed, 3 Jul 2013, Jim Schueler wrote: > Thanks for the prompt response, but this is your question, not mine. I > hardly need an RTFM for my trouble. > > I drew my conclusions using a packet sniffer. And as far-fetched as my > answer may seem, it's more plausible than your theory that Apache or modperl > is decoding a raw socket stream. > > The crux of your question seems to be how the request content gets > magically re-assembled. I don't think it was ever disassembled in the first > place. But if you don't like my answer, and you don't want to ignore it > either, then please restate the question. I can't find any definition for > unchunked, and Wiktionary's definition of de-chunk says to "break apart a > chunk", that is (counter-intuitively) chunk a chunk. > > >> 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.  But, is >> that guaranteed to always be the case, even for, >> say, pipelined requests?  >> My guess is yes because whatever is de-chunking the > > read() is blocking. So it never returns 0, even in a pipeline request (if no > data is available, it simply waits). I don't wish to discuss the merits > here, but there is no technical imperative for a content-length request in > the request header. > > -Jim > > > > > > > On Wed, 3 Jul 2013, Bill Moseley wrote: > >> Hi Jim, >> This is the Transfer-Encoding: chunked I was writing about: >> >> http://tools.ietf.org/html/rfc2616#section-3.6.1 >> >> >> >> On Wed, Jul 3, 2013 at 11:34 AM, Jim Schueler <[email protected]> >> wrote: >> I played around with chunking recently in the context of media >> streaming: The client is only requesting a "chunk" of data. >>  "Chunking" is how media players perform a "seek".  It was >> originally implemented for FTP transfers:  E.g, to transfer a >> large file in (say 10K) chunks.  In the case that you describe >> below, if no Content-Length is specified, that indicates "send >> the remainder". >> >> >From what I know, a "chunk" request header is used this way to >> specify the server response.  It does not reflect anything about >> the data included in the body of the request.  So first, I would >> ask if you're confused about this request information. >> >> Hypothetically, some browsers might try to upload large files in >> small chunks and the "chunk" header might reflect a push >> transfer.  I don't know if "chunk" is ever used for this >> purpose.  But it would require the following characteristics: >> >>  1.  The browser would need to originally inquire if the server >> is >>    capable of this type of request. >>  2.  Each chunk of data will arrive in a separate and >> independent HTTP >>    request.  Not necessarily in the order they were sent. >>  3.  Two or more requests may be handled by separate processes >>    simultaneously that can't be written into a single >> destination. >>  4.  Somehow the server needs to request a resend if a chunk is >> missing. >>    Solving this problem requires an imaginitive use of HTTP. >> >> Sounds messy.  But might be appropriate for 100M+ sized uploads. >>  This *may* reflect your situation.  Can you please confirm? >> >> For a single process, the incoming content-length is >> unnecessary. Buffered I/O automatically knows when transmission >> is complete.  The read() argument is the buffer size, not the >> content length.  Whether you spool the buffer to disk or simply >> enlarge the buffer should be determined by your hardware >> capabilities.  This is standard IO behavior that has nothing to >> do with HTTP chunk.  Without a "Content-Length" header, after >> looping your read() operation, determine the length of the >> aggregate data and pass that to Catalyst. >> >> But if you're confident that the complete request spans several >> smaller (chunked) HTTP requests, you'll need to address all the >> problems I've described above, plus the problem of re-assembling >> the whole thing for Catalyst.  I don't know anything about >> Plack, maybe it can perform all this required magic. >> >> Otherwise, if the whole purpose of the Plack temporary file is >> to pass a file handle, you can pass a buffer as a file handle. >>  Used to be IO::String, but now that functionality is built into >> the core. >> >> By your last paragraph, I'm really lost.  Since you're already >> passing the request as a file handle, I'm guessing that Catalyst >> creates the tempororary file for the *response* body.  Can you >> please clarify?  Also, what do you mean by "de-chunking"?  Is > > that the same think as re-assembling? >> >> Wish I could give a better answer.  Let me know if this helps. >> >> -Jim >> >> >> On Tue, 2 Jul 2013, 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? >> >> 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.  But, is >> that guaranteed to always be the case, even for, >> say, pipelined requests?  >> 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? >> >> >> Perhaps I'm approaching this incorrectly, but this >> is all a bit untidy. >> >> I'm using Catalyst and Catalyst needs a >> Content-Length.  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. >> >> 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. >> >> >> -- >> Bill Moseley >> [email protected] >> >> >> >> >> -- >> Bill Moseley >> [email protected] >> >