httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Ames <grega...@apache.org>
Subject [PATCH] PR 18757 Content-Length removed from proxied HEAD responses
Date Tue, 18 Oct 2005 22:58:07 GMT
...a.k.a. Windows Update doesn't work through an httpd-2.* proxy.  it looks like a 
regression from 1.3.

the interesting stuff happens in ap_content_length_filter.  it calculates the new content

length by traversing the output brigade.  but in this case, the brigade consists of only 
an EOS bucket and r->headers_out has a good Content-Length header set by the origin 
server.  the existing code calls ap_set_content_length which replaces the C-L with one 
containing a zero length. that gets stripped off later in ap_http_header_filter, causing 
the browser to complain.

clearly the call to ap_set_content_length must be skipped in this case.  the first patch 
in the PR skipped it for HEAD requests.  but that is bad when the content is a local file

run thru mod_deflate for example.  then Nick Kew committed a patch that skipped the 
ap_set_content_length call if the current brigade has a zero length.  I personally like 
that one but Brad Nicoles reverted it because it broke TLS upgrades so it must have had a

flaw.  so I incorporated both checks in this patch and added another for an existing C-L 
header to try to keep the scope as narrow as possible.

any reason why I shouldn't commit this?  yes, I will add a CHANGES entry.

note 1: you have to enable the CONNECT method to get Windows Update to work completely.
LoadModule proxy_connect_module modules/mod_proxy_connect.so
(thanks to Eric Covener for that)

note 2: there is no T-E header in this case.  if there were both, ap_http_header_filter 
takes care of it later.

Greg

Index: server/protocol.c
===================================================================
--- server/protocol.c   (revision 326257)
+++ server/protocol.c   (working copy)
@@ -1302,7 +1302,13 @@
       * We can only set a C-L in the response header if we haven't already
       * sent any buckets on to the next output filter for this request.
       */
-    if (ctx->data_sent == 0 && eos) {
+    if (ctx->data_sent == 0 && eos &&
+         /* don't whack the C-L if it has already been set for a HEAD
+          * by something like proxy.  the brigade only has an EOS bucket
+          * in this case, making r->bytes_sent zero.
+          */
+        !(r->header_only && r->bytes_sent == 0 &&
+            apr_table_get(r->headers_out, "Content-Length"))) {
          ap_set_content_length(r, r->bytes_sent);
      }

Mime
View raw message