You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2002/04/30 21:21:45 UTC

DO NOT REPLY [Bug 8677] New: - mod_proxy ALWAYS nukes Content-Length and Transfer-Encoding if body sent

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8677>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8677

mod_proxy ALWAYS nukes Content-Length and Transfer-Encoding if body sent 

           Summary: mod_proxy ALWAYS nukes Content-Length and Transfer-
                    Encoding if body sent
           Product: Apache httpd-2.0
           Version: 2.0.35
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: mod_proxy
        AssignedTo: bugs@httpd.apache.org
        ReportedBy: tim.mcbride@alcoa.com


apparently, this was done so that ap_set_keepalive will work properly:

(proxy_http.c)
            /* In order for ap_set_keepalive to work properly, we can NOT
             * have any length information stored in the output headers.

            apr_table_unset(r->headers_out,"Transfer-Encoding");
            apr_table_unset(r->headers_out,"Content-Length");

            ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                         "proxy: start body send");
             
However, this is overbroad.  If we have Connection: close, then we're not going 
to have a keepalive connection, so we don't need or want to nuke the c-l and t-
e headers.  Refering to an earlier bug declared invalid (#8673), not every 
vendor comprehends the standards, and so might very well send a set of HTTP 
headers that is inconsistent with the standard.  mod_proxy should not touch any 
headers that it does not absolutely have to.

Here's ap_set_keepalive, just so all of the appropriate code is in one place:

AP_DECLARE(int) ap_set_keepalive(request_rec *r)
{
    int ka_sent = 0;
    int wimpy = ap_find_token(r->pool,
                              apr_table_get(r->headers_out, "Connection"),
                              "close");
    const char *conn = apr_table_get(r->headers_in, "Connection");
 
    /* The following convoluted conditional determines whether or not
     * the current connection should remain persistent after this response
     * (a.k.a. HTTP Keep-Alive) and whether or not the output message
     * body should use the HTTP/1.1 chunked transfer-coding.  In English,
     *
     *   IF  we have not marked this connection as errored;
     *   and the response body has a defined length due to the status code
     *       being 304 or 204, the request method being HEAD, already
     *       having defined Content-Length or Transfer-Encoding: chunked, or
     *       the request version being HTTP/1.1 and thus capable of being set
     *       as chunked [we know the (r->chunked = 1) side-effect is ugly];
     *   and the server configuration enables keep-alive;
     *   and the server configuration has a reasonable inter-request timeout;
     *   and there is no maximum # requests or the max hasn't been reached;
     *   and the response status does not require a close;
     *   and the response generator has not already indicated close;
     *   and the client did not request non-persistence (Connection: close);
     *   and    we haven't been configured to ignore the buggy twit
     *       or they're a buggy twit coming through a HTTP/1.1 proxy
     *   and    the client is requesting an HTTP/1.0-style keep-alive
     *       or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
     *   THEN we can be persistent, which requires more headers be output.
     *
     * Note that the condition evaluation order is extremely important.
     */
...
}
 
the code corresponding to the Content-Length condition is:
 
        && ((r->status == HTTP_NOT_MODIFIED)
            || (r->status == HTTP_NO_CONTENT)
            || r->header_only
            || apr_table_get(r->headers_out, "Content-Length")
            || ap_find_last_token(r->pool,
                                  apr_table_get(r->headers_out,
                                                "Transfer-Encoding"),
                                  "chunked")
            || ((r->proto_num >= HTTP_VERSION(1,1))
                && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */