Hi,
Am Samstag 31 Juli 2004 10:20 schrieb Stas Bekman:
Geoffrey Young wrote:
Boris Zentner wrote:
Hi,
I have a handler, that serve dynamic pages or static ones. If the handler gets a HEAD request, it answers with
[...]
it is desired - you no longer need to set the Content-Length header for requests in Apache 2.0.
It's somewhat documented: http://perl.apache.org/docs/2.0/user/handlers/http.html#Handling_HEAD_Reque sts
I just read it, thanks for the pointer. I think the text should make clear, that even if it is not needed to return early with 'return OK if $r->header_only;' with apache2, it is recommended, since it is ( or can be ) a big waste of time to construct the body, that is removed in the next pass.
From reading the comments in modules/http/http_protocol.c ( ap_http_header_filter ), I get the impression, that apache2 recommend generating and throwing away the content. Here is the comment in question:
/* This is a hack, but I can't find anyway around it. The idea is that * we don't want to send out 0 Content-Lengths if it is a head request. * This happens when modules try to outsmart the server, and return * if they see a HEAD request. Apache 1.3 handlers were supposed to * just return in that situation, and the core handled the HEAD. In * 2.0, if a handler returns, then the core sends an EOS bucket down * the filter stack, and the content-length filter computes a C-L of * zero and that gets put in the headers, and we end up sending a * zero C-L to the client. We can't just remove the C-L filter, * because well behaved 2.0 handlers will send their data down the stack, * and we will compute a real C-L for the head request. RBB */
That's what I understood as well.
Does anybody have any statistics on the percentage of HEAD requests vs. GET? The purpose of HEAD request is not to save your CPU cycles, but to avoid data transfer which is precisely what Apache 2.0 does, without making you do the extra work to deal with HEAD requests.
also The comment implies, that I get a Content-Length header for a HEAD request, if I waste my time and generate the body of the message. I tried it and got _no_ Content-Length header!
$apr->content_type($media_type) unless $apr->main; if ( $apr->header_only ) { $apr->print( ' ' x $size ); # just to see if I got a content-length header return DONE; }
The only way to get the Content-Length header for a HEAD request is
$apr->headers_out->{'Content-Length'} = $size ; $apr->content_type($media_type) unless $apr->main; if ( $apr->header_only ) { $apr->rflush; return DONE; }
But I fail to see why this works, I thought the data walks the same filter chain only in more buckets.
In dynamic scripts you never get the C-L header unless you set it explicitly and some filter doesn't remove it. It's not possible for Apache to add one, since headers are sent *before* it knows how much data your handler is going to send. So HEAD or GET, you won't get it.
So HEAD on dynamic scripts that doesn't set their own C-L is a wasted operation on behalf of the client. Unless you use some E-Tag (but I haven't checked the RFC).
BTW, what's wrong with $r->set_content_length()? http://perl.apache.org/docs/2.0/api/Apache/Response.html#C_set_content_length_ Neither you need to rflush. Neither you should return DONE, but OK.
-- __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
-- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html