Commit 4625172f authored by Mladen Turk's avatar Mladen Turk
Browse files

Always send body (zero size at least) whenever C-L is present in the request

Backport r696614 from truk

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@711779 13f79535-47bb-0310-9956-ffa450edef68
parent 9d116bdb
Loading
Loading
Loading
Loading
+8 −0
Changes for CHANGES: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.2.11

  *) mod_proxy_ajp: Fix wrongly formatted requests where client
     sets Content-Length header, but doesn't provide a body.
     Servlet container always expects that next packet is
     body whenever C-L is present in the headers. This can lead
     to wrong interpretation of the packets. In this case
     send the empty body packet, so container can deal with
     that. [Mladen Turk]

  *) Worker MPM: Crosscheck that idle workers are still available before using
     them and thus preventing an overflow of the worker queue which causes
     a SegFault. PR 45605 [Denis Ustimenko <denusk gmail.com>]
+0 −9
Changes for STATUS: 0 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -129,15 +129,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
        http://people.apache.org/~tdonovan/diffs/windows_odbc_22x_dsw.patch
     +1: tdonovan, wrowe, mturk

   * mod_proxy_ajp: Always send body (zero size at least) whenever C-L is
     present in the request.
     Trunk version of patch:
        http://svn.apache.org/viewvc?rev=696614&view=rev
        http://svn.apache.org/viewvc?rev=707027&view=rev
     Backport version for 2.2.x of patch:
        Trunk version of patch works
     +1: rpluem, jim, mturk

   * mod_proxy_ajp: Don't discard previously set cookies from the output
     headers.
      Trunk version of patch:
+45 −0
Changes for modules/proxy/mod_proxy_ajp.c: 45 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -116,6 +116,27 @@ static int is_idempotent(request_rec *r)
    }
}

static apr_off_t get_content_length(request_rec * r)
{
    apr_off_t len = 0;

    if (r->clength > 0) {
        return r->clength;
    }
    else if (r->main == NULL) {
        const char *clp = apr_table_get(r->headers_in, "Content-Length");

        if (clp) {
            char *errp;
            if (apr_strtoff(&len, clp, &errp, 10) || *errp || len < 0) {
                len = 0; /* parse error */
            }
        }
    }

    return len;
}

/*
 * XXX: AJP Auto Flushing
 *
@@ -166,6 +187,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
    ap_get_module_config(r->server->module_config, &proxy_module);
    apr_size_t maxsize = AJP_MSG_BUFFER_SZ;
    int send_body = 0;
    apr_off_t content_length = 0;

    if (psf->io_buffer_size_set)
       maxsize = psf->io_buffer_size;
@@ -221,6 +243,8 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                     "proxy: request is chunked");
    } else {
        /* Get client provided Content-Length header */
        content_length = get_content_length(r);
        status = ap_get_brigade(r->input_filters, input_brigade,
                                AP_MODE_READBYTES, APR_BLOCK_READ,
                                maxsize - AJP_HEADER_SZ);
@@ -277,6 +301,27 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
            conn->worker->s->transferred += bufsiz;
            send_body = 1;
        }
        else if (content_length > 0) {
            ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                         "proxy: read zero bytes, expecting"
                         " %" APR_OFF_T_FMT " bytes",
                         content_length);
            status = ajp_send_data_msg(conn->sock, msg, 0);
            if (status != APR_SUCCESS) {
                /* We had a failure: Close connection to backend */
                conn->close++;
                ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                            "proxy: send failed to %pI (%s)",
                            conn->worker->cp->addr,
                            conn->worker->hostname);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            else {
                /* Client send zero bytes with C-L > 0
                 */
                return HTTP_BAD_REQUEST;
            }
        }
    }

    /* read the response */