summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Jagielski <jim@apache.org>2009-08-31 11:41:33 +0000
committerJim Jagielski <jim@apache.org>2009-08-31 11:41:33 +0000
commit1a216eca678b06d10cae0ce673fd0a7af6481efc (patch)
tree5116fe26d5bd2475861411baaac1f9e288e4764f
parentfdbbba3802914af0a111b740fc793bb3a3582a32 (diff)
downloadhttpd-2.2-proxy.tar.gz
More trunk backportinghttpd-2.2-proxy
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/httpd-2.2-proxy@809545 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--modules/proxy/mod_proxy_balancer.c13
-rw-r--r--modules/proxy/mod_proxy_connect.c21
-rw-r--r--modules/proxy/mod_proxy_http.c39
-rw-r--r--modules/proxy/proxy_util.c58
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);
}