diff options
Diffstat (limited to 'modules/proxy')
| -rw-r--r-- | modules/proxy/NWGNUproxy | 1 | ||||
| -rw-r--r-- | modules/proxy/NWGNUproxylbm_busy | 1 | ||||
| -rw-r--r-- | modules/proxy/NWGNUproxylbm_hb | 1 | ||||
| -rw-r--r-- | modules/proxy/NWGNUproxylbm_req | 1 | ||||
| -rw-r--r-- | modules/proxy/NWGNUproxylbm_traf | 1 | ||||
| -rw-r--r-- | modules/proxy/ajp_header.c | 2 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy.c | 1 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy.h | 12 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_ajp.c | 48 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_balancer.c | 20 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_connect.c | 58 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_fcgi.c | 2 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_ftp.c | 4 | ||||
| -rw-r--r-- | modules/proxy/mod_proxy_http.c | 44 | ||||
| -rw-r--r-- | modules/proxy/proxy_util.c | 66 |
15 files changed, 146 insertions, 116 deletions
diff --git a/modules/proxy/NWGNUproxy b/modules/proxy/NWGNUproxy index cade4acb..6342e613 100644 --- a/modules/proxy/NWGNUproxy +++ b/modules/proxy/NWGNUproxy @@ -277,6 +277,7 @@ $(OBJDIR)/mod_proxy.imp: @echo $(DL) ap_proxy_canon_netloc,$(DL)>> $@ @echo $(DL) ap_proxy_canonenc,$(DL)>> $@ @echo $(DL) ap_proxy_checkproxyblock,$(DL)>> $@ + @echo $(DL) ap_proxy_checkproxyblock2,$(DL)>> $@ @echo $(DL) ap_proxy_conn_is_https,$(DL)>> $@ @echo $(DL) ap_proxy_connect_backend,$(DL)>> $@ @echo $(DL) ap_proxy_connect_to_backend,$(DL)>> $@ diff --git a/modules/proxy/NWGNUproxylbm_busy b/modules/proxy/NWGNUproxylbm_busy index 394af7a6..c1b91f6b 100644 --- a/modules/proxy/NWGNUproxylbm_busy +++ b/modules/proxy/NWGNUproxylbm_busy @@ -19,6 +19,7 @@ XINCDIRS += \ $(APR)/include \ $(APRUTIL)/include \ $(AP_WORK)/include \ + $(AP_WORK)/modules/proxy \ $(AP_WORK)/modules/http \ $(NWOS) \ $(EOLIST) diff --git a/modules/proxy/NWGNUproxylbm_hb b/modules/proxy/NWGNUproxylbm_hb index 80f2f822..19563da6 100644 --- a/modules/proxy/NWGNUproxylbm_hb +++ b/modules/proxy/NWGNUproxylbm_hb @@ -19,6 +19,7 @@ XINCDIRS += \ $(APR)/include \ $(APRUTIL)/include \ $(AP_WORK)/include \ + $(AP_WORK)/modules/proxy \ $(AP_WORK)/modules/http \ $(NWOS) \ $(EOLIST) diff --git a/modules/proxy/NWGNUproxylbm_req b/modules/proxy/NWGNUproxylbm_req index 0170056c..6a2c4cd0 100644 --- a/modules/proxy/NWGNUproxylbm_req +++ b/modules/proxy/NWGNUproxylbm_req @@ -19,6 +19,7 @@ XINCDIRS += \ $(APR)/include \ $(APRUTIL)/include \ $(AP_WORK)/include \ + $(AP_WORK)/modules/proxy \ $(AP_WORK)/modules/http \ $(NWOS) \ $(EOLIST) diff --git a/modules/proxy/NWGNUproxylbm_traf b/modules/proxy/NWGNUproxylbm_traf index 1960453b..1927d626 100644 --- a/modules/proxy/NWGNUproxylbm_traf +++ b/modules/proxy/NWGNUproxylbm_traf @@ -19,6 +19,7 @@ XINCDIRS += \ $(APR)/include \ $(APRUTIL)/include \ $(AP_WORK)/include \ + $(AP_WORK)/modules/proxy \ $(AP_WORK)/modules/http \ $(NWOS) \ $(EOLIST) diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c index dc86defa..3e906514 100644 --- a/modules/proxy/ajp_header.c +++ b/modules/proxy/ajp_header.c @@ -139,7 +139,7 @@ static const unsigned char sc_for_req_method_table[] = { SC_M_PUT, SC_M_POST, SC_M_DELETE, - 0, /* M_DELETE */ + 0, /* M_CONNECT */ SC_M_OPTIONS, SC_M_TRACE, 0, /* M_PATCH */ diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index f9a80090..431efb87 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -44,7 +44,6 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, * can't trust directory_walk/file_walk since these are * not in our filesystem. Prevents mod_http from serving * the TRACE request we will set aside to handle later. - * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy: * fix_ups: convert the URL stored in the filename to the * canonical form. * handler: handle proxy requests diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 5ad91fb5..0bce5065 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -534,6 +534,18 @@ PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, cha char **passwordp, char **hostp, apr_port_t *port); PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message); PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr); + +/** Test whether the hostname/address of the request are blocked by the ProxyBlock + * configuration. + * @param r request + * @param conf server configuration + * @param hostname hostname from request URI + * @param addr resolved address of hostname, or NULL if not known + * @return OK on success, or else an errro + */ +PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, + const char *hostname, apr_sockaddr_t *addr); + PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r); /* DEPRECATED (will be replaced with ap_proxy_connect_backend */ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, request_rec *); diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index 93cb1530..3736156a 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -207,7 +207,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, /* send request headers */ status = ajp_send_header(conn->sock, r, maxsize, uri); if (status != APR_SUCCESS) { - conn->close++; + conn->close = 1; ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00868) "request failed to %pI (%s)", conn->worker->cp->addr, @@ -234,7 +234,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00869) "ajp_alloc_data_msg failed"); return HTTP_INTERNAL_SERVER_ERROR; @@ -255,7 +255,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00871) "ap_get_brigade failed"); apr_brigade_destroy(input_brigade); @@ -275,7 +275,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, status = apr_brigade_flatten(input_brigade, buff, &bufsiz); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; apr_brigade_destroy(input_brigade); ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00874) "apr_brigade_flatten"); @@ -290,7 +290,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, ajp_msg_log(r, msg, "First ajp_send_data_msg: ajp_ilink_send packet dump"); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; apr_brigade_destroy(input_brigade); ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00876) "send failed to %pI (%s)", @@ -319,7 +319,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, * for later resusage by the next request again. * Close it to clean things up. */ - conn->close++; + conn->close = 1; return HTTP_BAD_REQUEST; } } @@ -330,7 +330,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, (ajp_msg_t **)&(conn->data)); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; apr_brigade_destroy(input_brigade); ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00878) "read response failed from %pI (%s)", @@ -559,7 +559,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, * But: Close this connection to the backend. */ if (r->connection->aborted) { - conn->close++; + conn->close = 1; output_failed = 0; result = CMD_AJP13_END_RESPONSE; request_ended = 1; @@ -597,7 +597,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, "Processing of request failed backend: %i, " "output: %i", backend_failed, output_failed); /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; /* Return DONE to avoid error messages being added to the stream */ if (data_sent) { rv = DONE; @@ -607,7 +607,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00891) "Processing of request didn't terminate cleanly"); /* We had a failure: Close connection to backend */ - conn->close++; + conn->close = 1; backend_failed = 1; /* Return DONE to avoid error messages being added to the stream */ if (data_sent) { @@ -616,7 +616,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, } else if (!conn_reuse) { /* Our backend signalled connection close */ - conn->close++; + conn->close = 1; } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00892) @@ -679,7 +679,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, apr_brigade_destroy(output_brigade); if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) { - conn->close++; + conn->close = 1; } return rv; @@ -701,29 +701,15 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker, int retry; proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module); - - /* - * Note: Memory pool allocation. - * A downstream keepalive connection is always connected to the existence - * (or not) of an upstream keepalive connection. If this is not done then - * load balancing against multiple backend servers breaks (one backend - * server ends up taking 100% of the load), and the risk is run of - * downstream keepalive connections being kept open unnecessarily. This - * keeps webservers busy and ties up resources. - * - * As a result, we allocate all sockets out of the upstream connection - * pool, and when we want to reuse a socket, we check first whether the - * connection ID of the current upstream connection is the same as that - * of the connection when the socket was opened. - */ - apr_pool_t *p = r->connection->pool; - apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri)); - + apr_pool_t *p = r->pool; + apr_uri_t *uri; if (strncasecmp(url, "ajp:", 4) != 0) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00894) "declining URL %s", url); return DECLINED; } + + uri = apr_palloc(p, sizeof(*uri)); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00895) "serving URL %s", url); /* create space for state information */ @@ -772,7 +758,7 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker, * TCP connection gets closed and try it once again. */ if (status != APR_SUCCESS) { - backend->close++; + backend->close = 1; ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00897) "cping/cpong failed to %pI (%s)", worker->cp->addr, worker->s->hostname); diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index 96e0901e..1feb2d7c 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -437,6 +437,17 @@ static void force_recovery(proxy_balancer *balancer, server_rec *s) } } +static apr_status_t decrement_busy_count(void *worker_) +{ + proxy_worker *worker = worker_; + + if (worker->s->busy) { + worker->s->busy--; + } + + return APR_SUCCESS; +} + static int proxy_balancer_pre_request(proxy_worker **worker, proxy_balancer **balancer, request_rec *r, @@ -570,6 +581,8 @@ static int proxy_balancer_pre_request(proxy_worker **worker, } (*worker)->s->busy++; + apr_pool_cleanup_register(r->pool, *worker, decrement_busy_count, + apr_pool_cleanup_null); /* Add balancer/worker info to env. */ apr_table_setn(r->subprocess_env, @@ -623,7 +636,7 @@ static int proxy_balancer_post_request(proxy_worker *worker, for (i = 0; i < balancer->errstatuses->nelts; i++) { int val = ((int *)balancer->errstatuses->elts)[i]; if (r->status == val) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01174) + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01174) "%s: Forcing worker (%s) into error state " "due to status code %d matching 'failonstatus' " "balancer parameter", @@ -642,11 +655,7 @@ static int proxy_balancer_post_request(proxy_worker *worker, ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01176) "proxy_balancer_post_request for (%s)", balancer->s->name); - if (worker && worker->s->busy) - worker->s->busy--; - return OK; - } static void recalc_factors(proxy_balancer *balancer) @@ -744,7 +753,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog, s = s->next; continue; } - if (conf->balancers->nelts) { conf->max_balancers = conf->balancers->nelts + conf->bgrowth; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01178) "Doing balancers create: %d, %d (%d)", diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index 9a14eb71..0cf5693c 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -205,7 +205,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, conn_rec *backconn; apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); - apr_status_t err, rv; + apr_status_t rv; apr_size_t nbytes; char buffer[HUGE_STRING_LEN]; apr_socket_t *client_socket = ap_get_conn_socket(c); @@ -216,7 +216,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, const apr_pollfd_t *signalled; apr_int32_t pollcnt, pi; apr_int16_t pollevent; - apr_sockaddr_t *uri_addr, *connect_addr; + apr_sockaddr_t *nexthop; apr_uri_t uri; const char *connectname; @@ -246,37 +246,32 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01019) "connecting %s to %s:%d", url, uri.hostname, uri.port); - /* do a DNS lookup for the destination host */ - err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, - 0, p); - if (APR_SUCCESS != err) { + /* Determine host/port of next hop; from request URI or of a proxy. */ + connectname = proxyname ? proxyname : uri.hostname; + connectport = proxyname ? proxyport : uri.port; + + /* Do a DNS lookup for the next hop */ + rv = apr_sockaddr_info_get(&nexthop, connectname, APR_UNSPEC, + connectport, 0, p); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO() + "failed to resolve hostname '%s'", connectname); return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, "DNS lookup failure for: ", - uri.hostname, NULL)); + connectname, NULL)); } - /* are we connecting directly, or via a proxy? */ - if (proxyname) { - connectname = proxyname; - connectport = proxyport; - err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, - proxyport, 0, p); - } - else { - connectname = uri.hostname; - connectport = uri.port; - connect_addr = uri_addr; + /* Check ProxyBlock directive on the hostname/address. */ + if (ap_proxy_checkproxyblock2(r, conf, uri.hostname, + proxyname ? NULL : nexthop) != OK) { + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } + ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "connecting to remote proxy %s on port %d", connectname, connectport); - /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) { - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - /* Check if it is an allowed port */ if(!allowed_port(c_conf, uri.port)) { return ap_proxyerror(r, HTTP_FORBIDDEN, @@ -289,15 +284,6 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, * We have determined who to connect to. Now make the connection. */ - /* get all the possible IP addresses for the destname and loop through them - * until we get a successful connection - */ - if (APR_SUCCESS != err) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - apr_pstrcat(p, "DNS lookup failure for: ", - connectname, NULL)); - } - /* * At this point we have a list of one or more IP addresses of * the machine to connect to. If configured, reorder this @@ -308,7 +294,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, * For now we do nothing, ie we get DNS round robin. * XXX FIXME */ - failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr, + failed = ap_proxy_connect_to_backend(&sock, "CONNECT", nexthop, connectname, conf, r); /* handle a permanent error from the above loop */ @@ -355,7 +341,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, /* peer reset */ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01021) "an error occurred creating a new connection " - "to %pI (%s)", connect_addr, connectname); + "to %pI (%s)", nexthop, connectname); apr_socket_close(sock); return HTTP_INTERNAL_SERVER_ERROR; } @@ -370,7 +356,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, "connection complete to %pI (%s)", - connect_addr, connectname); + nexthop, connectname); apr_table_setn(r->notes, "proxy-source-port", apr_psprintf(r->pool, "%hu", backconn->local_addr->port)); diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index d0df5fa1..0f844163 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -748,10 +748,10 @@ recv_again: apr_brigade_cleanup(ob); tmp_b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(ob, tmp_b); + r->status = status; ap_pass_brigade(r->output_filters, ob); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070) "Error parsing script headers"); - r->status = status; rv = APR_EINVAL; break; } diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c index d5aabd69..33237d6f 100644 --- a/modules/proxy/mod_proxy_ftp.c +++ b/modules/proxy/mod_proxy_ftp.c @@ -1143,7 +1143,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, } /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) { + if (OK != ap_proxy_checkproxyblock2(r, conf, connectname, connect_addr)) { return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } @@ -1725,7 +1725,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, if (len != 0) buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL); else if (cwd == NULL || strchr(cwd, '/') != NULL) - buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL); + buf = "LIST -lag" CRLF; else buf = "LIST" CRLF; } diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 64b95a2f..243c9a5e 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -795,14 +795,14 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, } buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL); force10 = 1; - p_conn->close++; + p_conn->close = 1; } else { buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" CRLF, NULL); force10 = 0; } if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) { origin->keepalive = AP_CONN_CLOSE; - p_conn->close++; + p_conn->close = 1; } ap_xlate_proto_to_ascii(buf, strlen(buf)); e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); @@ -1019,7 +1019,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, */ if (!r->kept_body && r->main) { /* XXX: Why DON'T sub-requests use keepalives? */ - p_conn->close++; + p_conn->close = 1; if (old_cl_val) { old_cl_val = NULL; apr_table_unset(r->headers_in, "Content-Length"); @@ -1056,7 +1056,7 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, apr_table_unset(r->headers_in, "Content-Length"); old_cl_val = NULL; origin->keepalive = AP_CONN_CLOSE; - p_conn->close++; + p_conn->close = 1; } /* Prefetch MAX_MEM_SPOOL bytes @@ -1705,7 +1705,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106) "bad HTTP/%d.%d header returned by %s (%s)", major, minor, r->uri, r->method); - backend->close += 1; + backend->close = 1; /* * ap_send_error relies on a headers_out to be present. we * are in a bad position here.. so force everything we send out @@ -1746,7 +1746,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, "server %s:%d returned Transfer-Encoding" " and Content-Length", backend->hostname, backend->port); - backend->close += 1; + backend->close = 1; } /* @@ -1755,8 +1755,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, */ te = apr_table_get(r->headers_out, "Transfer-Encoding"); /* strip connection listed hop-by-hop headers from response */ - backend->close += ap_find_token(p, - apr_table_get(r->headers_out, "Connection"), "close"); + if (ap_find_token(p, apr_table_get(r->headers_out, "Connection"), + "close")) + backend->close = 1; ap_proxy_clear_connection(p, r->headers_out); if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { ap_set_content_type(r, apr_pstrdup(p, buf)); @@ -1801,7 +1802,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, /* cancel keepalive if HTTP/1.0 or less */ if ((major < 1) || (minor < 1)) { - backend->close += 1; + backend->close = 1; origin->keepalive = AP_CONN_CLOSE; } } else { @@ -1809,7 +1810,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, backasswards = 1; r->status = 200; r->status_line = "200 OK"; - backend->close += 1; + backend->close = 1; } if (ap_is_HTTP_INFO(proxy_status)) { @@ -1964,8 +1965,9 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, /* ap_get_brigade will return success with an empty brigade * for a non-blocking read which would block: */ - if (APR_STATUS_IS_EAGAIN(rv) - || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) { + if (mode == APR_NONBLOCK_READ + && (APR_STATUS_IS_EAGAIN(rv) + || (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)))) { /* flush to the client and switch to blocking mode */ e = apr_bucket_flush_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, e); @@ -2236,8 +2238,24 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker, * so. */ if (is_ssl) { + proxy_dir_conf *dconf; + const char *ssl_hostname; + + /* + * In the case of ProxyPreserveHost on use the hostname of + * the request if present otherwise use the one from the + * backend request URI. + */ + dconf = ap_get_module_config(r->per_dir_config, &proxy_module); + if ((dconf->preserve_host != 0) && (r->hostname != NULL)) { + ssl_hostname = r->hostname; + } + else { + ssl_hostname = uri->hostname; + } + apr_table_set(backend->connection->notes, "proxy-request-hostname", - uri->hostname); + ssl_hostname); } } diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index fe2ac43e..4aaaf9bc 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -373,7 +373,7 @@ PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *mes NULL)); /* Allow "error-notes" string to be printed by ap_send_error_response() */ - apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*")); + apr_table_setn(r->notes, "verbose-error-to", "*"); r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00898) "%s returned by %s", message, @@ -759,48 +759,63 @@ static int proxy_match_word(struct dirconn_entry *This, request_rec *r) return host != NULL && ap_strstr_c(host, This->name) != NULL; } -/* checks whether a host in uri_addr matches proxyblock */ +/* Backwards-compatible interface. */ PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr) { + return ap_proxy_checkproxyblock2(r, conf, uri_addr->hostname, uri_addr); +} + +#define MAX_IP_STR_LEN (46) + +PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, + const char *hostname, apr_sockaddr_t *addr) +{ int j; - apr_sockaddr_t * src_uri_addr = uri_addr; + /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */ for (j = 0; j < conf->noproxies->nelts; j++) { struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; - struct apr_sockaddr_t *conf_addr = npent[j].addr; - uri_addr = src_uri_addr; + struct apr_sockaddr_t *conf_addr; + ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "checking remote machine [%s] against [%s]", - uri_addr->hostname, npent[j].name); - if (ap_strstr_c(uri_addr->hostname, npent[j].name) - || npent[j].name[0] == '*') { + hostname, npent[j].name); + if (ap_strstr_c(hostname, npent[j].name) || npent[j].name[0] == '*') { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00916) "connect to remote machine %s blocked: name %s " - "matched", uri_addr->hostname, npent[j].name); + "matched", hostname, npent[j].name); return HTTP_FORBIDDEN; } - while (conf_addr) { - uri_addr = src_uri_addr; - while (uri_addr) { - char *conf_ip; - char *uri_ip; - apr_sockaddr_ip_get(&conf_ip, conf_addr); - apr_sockaddr_ip_get(&uri_ip, uri_addr); + + /* No IP address checks if no IP address was passed in, + * i.e. the forward address proxy case, where this server does + * not resolve the hostname. */ + if (!addr) + continue; + + for (conf_addr = npent[j].addr; conf_addr; conf_addr = conf_addr->next) { + char caddr[MAX_IP_STR_LEN], uaddr[MAX_IP_STR_LEN]; + apr_sockaddr_t *uri_addr; + + if (apr_sockaddr_ip_getbuf(caddr, sizeof caddr, conf_addr)) + continue; + + for (uri_addr = addr; uri_addr; uri_addr = uri_addr->next) { + if (apr_sockaddr_ip_getbuf(uaddr, sizeof uaddr, uri_addr)) + continue; ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, - "ProxyBlock comparing %s and %s", conf_ip, - uri_ip); - if (!apr_strnatcasecmp(conf_ip, uri_ip)) { + "ProxyBlock comparing %s and %s", caddr, uaddr); + if (!strcmp(caddr, uaddr)) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(00917) - "connect to remote machine %s blocked: " - "IP %s matched", uri_addr->hostname, conf_ip); + "connect to remote machine %s blocked: " + "IP %s matched", hostname, caddr); return HTTP_FORBIDDEN; } - uri_addr = uri_addr->next; } - conf_addr = conf_addr->next; } } + return OK; } @@ -852,7 +867,7 @@ PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, (balancer = ap_proxy_get_balancer(r->pool, sconf, real, 1))) { int n, l3 = 0; proxy_worker **worker = (proxy_worker **)balancer->workers->elts; - const char *urlpart = ap_strchr_c(real, '/'); + const char *urlpart = ap_strchr_c(real + sizeof(BALANCER_PREFIX) - 1, '/'); if (urlpart) { if (!urlpart[1]) urlpart = NULL; @@ -2128,7 +2143,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, } } /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, conn->addr)) { + if (OK != ap_proxy_checkproxyblock2(r, conf, uri->hostname, + proxyname ? NULL : conn->addr)) { return ap_proxyerror(r, HTTP_FORBIDDEN, "Connect to remote machine blocked"); } |
