stas        2004/08/08 20:04:23

  Modified:    src/docs/2.0/user/handlers http.pod
  Log:
  document the issues with Content-length and HEAD requests
  
  Revision  Changes    Path
  1.43      +94 -5     modperl-docs/src/docs/2.0/user/handlers/http.pod
  
  Index: http.pod
  ===================================================================
  RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/http.pod,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -u -r1.42 -r1.43
  --- http.pod  16 Jul 2004 01:11:03 -0000      1.42
  +++ http.pod  9 Aug 2004 03:04:23 -0000       1.43
  @@ -1593,25 +1593,114 @@
   
   
   
  -=head1 Handling HEAD Requests
  +
  +
  +
  +
  +=head1 Miscellaneous Issues
  +
  +
  +=head2 Handling HEAD Requests
   
   In order to avoid the overhead of sending the data to the client when
   the request is of type HEAD in mod_perl 1.0 we L<used to return
   early|docs::1.0::guide::porting/Generating_correct_HTTP_Headers> from
   the handler:
   
  -  return OK if $r->header_only;
  +  return Apache::OK if $r->header_only;
  +
  +This logic should not be used in mod_perl 2.0, because Apache 2.0
  +automatically discards the response body for HEAD requests. It expects
  +the full body to generate the correct set of response headers, if you
  +don't send the body you may encounter problems.
   
  -This logic is no longer needed in mod_perl 2.0, because Apache 2.0
  -automatically discards the response body for HEAD requests. (You can
  -also read the comment in for C<ap_http_header_filter()> in
  +(You can also read the comment in for C<ap_http_header_filter()> in
   I<modules/http/http_protocol.c> in the Apache 2.0 source.)
   
  +
  +
  +
  +
  +=head2 C<Content-Length> Response Header
  +
  +You may encounter some issues with the C-L (C<Content-Length>)
  +header. Some of them are discussed here.
  +
  +=over
  +
  +=item * The special case of C<Content-Length: 0>
  +
  +Since Apache proclaims itself governor of the C-L header via the C-L
  +filter (ap_content_length_filter at F<httpd-2.0/server/protocol.c>),
  +for the most part C<GET> and C<HEAD> behave exactly the same.
  +However, when Apache sees a C<HEAD> request with a C-L header of zero
  +it takes special action and removes the C-L header.  This is done to
  +protect against handlers that called C<$r-E<gt>header_only> (L<which
  +was ok in 1.3 but is not in 2.0|/Handling_HEAD_Requests>).  Therefore,
  +C<GET> and C<HEAD> behave indentically, except when the content
  +handler (and/or filters) end up sending no content.  For more details
  +refer to the lengthy comments in C<ap_http_header_filter()> in
  +F<httpd-2.0/modules/http/http_protocol.c>).
  +
  +For more discussion on why it is important to get HEAD requests right,
  +see these threads from the mod_perl list:
  +
  +  http://marc.theaimsgroup.com/?l=apache-modperl&m=108647669726915&w=2
  +  http://marc.theaimsgroup.com/?t=109122984600001&r=1&w=2
  +
  +as well as this bug report from mozilla, which shows how C<HEAD>
  +requests are used in the wild:
  +
  +  http://bugzilla.mozilla.org/show_bug.cgi?id=245447
  +
  +=item * Not getting C<Content-Length> header with C<HEAD> requests
  +
  +Even though the spec says that content handlers should send an
  +identical response for GET and HEAD requests, some folks try to
  +L<avoid the overhead of generating the response
  +body|/Handling_HEAD_Requests>, which Apache is going to discard anyway
  +for HEAD requests. The following discussion assumes that we deal with
  +a HEAD request.
  +
  +When Apache sees EOS and no headers and no response body were sent,
  +C<ap_content_length_filter()> (F<httpd-2.0/server/protocol.c>) sets
  +C-L to 0. Later on C<ap_http_header_filter()>
  +(F<httpd-2.0/modules/http/http_protocol.c>) removes the C-L header for
  +the HEAD requests.
  +
  +The workaround is to force the sending of the response headers, before
  +C<EOS> was sent (which happens when the response handler returns). The
  +simplest solution is to use rflush():
  +
  +  if ($r->header_only) { # HEAD
  +      $body_len = calculate_body_len();
  +      $r->set_content_length($body_len);
  +      $r->rflush;
  +  }
  +  else {                 # GET
  +      # generate and send the body
  +  }
  +
  +now if the handler sets the C-L header it'll be delivered to the
  +client unmodified.
  +
  +=back
  +
  +
  +
  +
  +
  +
  +
   =head1 Extending HTTP Protocol
   
   Extending HTTP under mod_perl is a trivial task.  Look at L<the
   example of adding a new method C<EMAIL>|/PerlHeaderParserHandler> for
   details.
  +
  +
  +
  +
   
   
   =head1 Maintainers
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to