summaryrefslogtreecommitdiff
path: root/modules/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'modules/proxy')
-rw-r--r--modules/proxy/NWGNUproxy1
-rw-r--r--modules/proxy/NWGNUproxylbm_busy1
-rw-r--r--modules/proxy/NWGNUproxylbm_hb1
-rw-r--r--modules/proxy/NWGNUproxylbm_req1
-rw-r--r--modules/proxy/NWGNUproxylbm_traf1
-rw-r--r--modules/proxy/ajp_header.c2
-rw-r--r--modules/proxy/mod_proxy.c1
-rw-r--r--modules/proxy/mod_proxy.h12
-rw-r--r--modules/proxy/mod_proxy_ajp.c48
-rw-r--r--modules/proxy/mod_proxy_balancer.c20
-rw-r--r--modules/proxy/mod_proxy_connect.c58
-rw-r--r--modules/proxy/mod_proxy_fcgi.c2
-rw-r--r--modules/proxy/mod_proxy_ftp.c4
-rw-r--r--modules/proxy/mod_proxy_http.c44
-rw-r--r--modules/proxy/proxy_util.c66
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");
}