From 1a216eca678b06d10cae0ce673fd0a7af6481efc Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Mon, 31 Aug 2009 11:41:33 +0000 Subject: More trunk backporting git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-2.2-proxy@809545 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy_balancer.c | 13 ++++++--- modules/proxy/mod_proxy_connect.c | 21 +++++++++++--- modules/proxy/mod_proxy_http.c | 39 ++++++++++++++++++------- modules/proxy/proxy_util.c | 58 ++++++++++++++++++++------------------ 4 files changed, 85 insertions(+), 46 deletions(-) diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index f53be58887..14b3b906f1 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -534,10 +534,15 @@ static int proxy_balancer_pre_request(proxy_worker **worker, if (!*worker) { runtime = find_best_worker(*balancer, r); if (!runtime) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "proxy: BALANCER: (%s). All workers are in error state", - (*balancer)->name); - + if ((*balancer)->workers->nelts) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "proxy: BALANCER: (%s). All workers are in error state", + (*balancer)->name); + } else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "proxy: BALANCER: (%s). No workers in balancer", + (*balancer)->name); + } return HTTP_SERVICE_UNAVAILABLE; } if ((*balancer)->sticky && runtime) { diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index 8804359c09..5fd4c3b6d2 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -201,7 +201,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, return DECLINED; } else { - return HTTP_BAD_GATEWAY; + return HTTP_SERVICE_UNAVAILABLE; } } @@ -270,7 +270,8 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) { apr_socket_close(sock); ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: CONNECT: error apr_pollset_create()"); + "proxy: CONNECT: error apr_pollset_create();" + " check system or user limits"); return HTTP_INTERNAL_SERVER_ERROR; } @@ -280,11 +281,23 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, pollfd.reqevents = APR_POLLIN; pollfd.desc.s = client_socket; pollfd.client_data = NULL; - apr_pollset_add(pollset, &pollfd); + rv = apr_pollset_add(pollset, &pollfd); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: CONNECT: error apr_pollset_add();" + " check system or user limits"); + return HTTP_INTERNAL_SERVER_ERROR; + } /* Add the server side to the poll */ pollfd.desc.s = sock; - apr_pollset_add(pollset, &pollfd); + rv = apr_pollset_add(pollset, &pollfd); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: CONNECT: error apr_pollset_add();" + " check system or user limits"); + return HTTP_INTERNAL_SERVER_ERROR; + } while (1) { /* Infinite loop until error (one side closes the connection) */ if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) { diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 8773b5d9b6..e1b3d56176 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -427,10 +427,15 @@ static int stream_reqbody_cl(apr_pool_t *p, apr_off_t bytes_streamed = 0; if (old_cl_val) { + char *endstr; add_cl(p, bucket_alloc, header_brigade, old_cl_val); - if (APR_SUCCESS != (status = apr_strtoff(&cl_val, old_cl_val, NULL, - 0))) { - return HTTP_INTERNAL_SERVER_ERROR; + status = apr_strtoff(&cl_val, old_cl_val, &endstr, 10); + + if (status || *endstr || endstr == old_cl_val || cl_val < 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, + "proxy: could not parse request Content-Length (%s)", + old_cl_val); + return HTTP_BAD_REQUEST; } } terminate_headers(bucket_alloc, header_brigade); @@ -463,8 +468,13 @@ static int stream_reqbody_cl(apr_pool_t *p, * * Prevents HTTP Response Splitting. */ - if (bytes_streamed > cl_val) - continue; + if (bytes_streamed > cl_val) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "proxy: read more bytes of request body than expected " + "(got %" APR_OFF_T_FMT ", expected %" APR_OFF_T_FMT ")", + bytes_streamed, cl_val); + return HTTP_INTERNAL_SERVER_ERROR; + } if (header_brigade) { /* we never sent the header brigade, so go ahead and @@ -733,11 +743,20 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(header_brigade, e); if (conf->preserve_host == 0) { - if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { - buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", uri->port_str, - CRLF, NULL); + if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */ + if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { + buf = apr_pstrcat(p, "Host: [", uri->hostname, "]:", + uri->port_str, CRLF, NULL); + } else { + buf = apr_pstrcat(p, "Host: [", uri->hostname, "]", CRLF, NULL); + } } else { - buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL); + if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { + buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", uri->port_str, + CRLF, NULL); + } else { + buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL); + } } } else { @@ -947,7 +966,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, * encoding has been done by the extensions' handler, and * do not modify add_te_chunked's logic */ - if (old_te_val && strcmp(old_te_val, "chunked") != 0) { + if (old_te_val && strcasecmp(old_te_val, "chunked") != 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "proxy: %s Transfer-Encoding is not supported", old_te_val); diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 81eb944ab5..64e0cfd7ea 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1785,38 +1785,40 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, worker->name); return; } - /* Get scoreboard slot */ - if (ap_scoreboard_image) { - score = (proxy_worker_stat *) ap_get_scoreboard_lb(worker->id); + if (!worker->s) { + /* Get scoreboard slot */ + if (ap_scoreboard_image) { + score = (proxy_worker_stat *) ap_get_scoreboard_lb(worker->id); + if (!score) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s", + worker->id, getpid(), worker->name); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: grabbed scoreboard slot %d in child %" APR_PID_T_FMT " for worker %s", + worker->id, getpid(), worker->name); + } + } if (!score) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s", - worker->id, getpid(), worker->name); + score = (proxy_worker_stat *) apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s", + getpid(), worker->name); } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: grabbed scoreboard slot %d in child %" APR_PID_T_FMT " for worker %s", - worker->id, getpid(), worker->name); + worker->s = score; + /* + * recheck to see if we've already been here. Possible + * if proxy is using scoreboard to hold shared stats + */ + if (PROXY_WORKER_IS_INITIALIZED(worker)) { + /* The worker share is already initialized */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: worker %s already initialized", + worker->name); + return; } } - if (!score) { - score = (proxy_worker_stat *) apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s", - getpid(), worker->name); - } - worker->s = score; - /* - * recheck to see if we've already been here. Possible - * if proxy is using scoreboard to hold shared stats - */ - if (PROXY_WORKER_IS_INITIALIZED(worker)) { - /* The worker share is already initialized */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: worker %s already initialized", - worker->name); - return; - } if (worker->route) { strcpy(worker->s->route, worker->route); } -- cgit v1.2.1