Loading modules/proxy/proxy_http.c +61 −23 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, int def_p return OK; } static const char *proxy_location_reverse_map(request_rec *r, const char *url) static const char *ap_proxy_location_reverse_map(request_rec *r, const char *url) { void *sconf; proxy_server_conf *conf; Loading @@ -127,6 +127,9 @@ static const char *proxy_location_reverse_map(request_rec *r, const char *url) int i, l1, l2; char *u; /* XXX FIXME: Make sure this handled the ambiguous case of the :80 * after the hostname */ sconf = r->server->module_config; conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); l1 = strlen(url); Loading @@ -142,7 +145,7 @@ static const char *proxy_location_reverse_map(request_rec *r, const char *url) } /* Clear all connection-based headers from the incoming headers table */ static void clear_connection(apr_pool_t *p, apr_table_t *headers) static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers) { const char *name; char *next = apr_pstrdup(p, apr_table_get(headers, "Connection")); Loading Loading @@ -185,6 +188,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, apr_array_header_t *reqhdrs_arr; apr_table_t *resp_hdrs = NULL; apr_table_entry_t *reqhdrs; const char *table_buf; struct sockaddr_in server; struct in_addr destaddr; char buffer[HUGE_STRING_LEN]; Loading Loading @@ -285,14 +289,19 @@ int ap_proxy_http_handler(request_rec *r, char *url, /* the peer reset the connection already; ap_new_connection() * closed the socket */ /* XXX somebody that knows what they're doing add an error path */ /* XXX how's this? */ return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(r->pool, "Connection reset by peer: ", desthost, NULL)); } ap_add_output_filter("CORE", NULL, NULL, origin); clear_connection(r->pool, r->headers_in); /* Strip connection-based headers */ /* strip connection listed hop-by-hop headers from the request */ ap_proxy_clear_connection(r->pool, r->headers_in); buf = apr_pstrcat(r->pool, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF, NULL); " HTTP/1.1" CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) { Loading @@ -306,6 +315,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, APR_BRIGADE_INSERT_TAIL(bb, e); } /* handle Via */ if (conf->viaopt == via_block) { /* Block all outgoing Via: headers */ apr_table_unset(r->headers_in, "Via"); Loading @@ -318,7 +328,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, apr_snprintf(portstr, sizeof portstr, ":%d", i); } /* Generate outgoing Via: header with/without server comment: */ ap_table_mergen(r->headers_in, "Via", apr_table_mergen(r->headers_in, "Via", (conf->viaopt == via_full) ? apr_psprintf(p, "%d.%d %s%s (%s)", HTTP_VERSION_MAJOR(r->proto_num), Loading @@ -332,32 +342,55 @@ int ap_proxy_http_handler(request_rec *r, char *url, ); } /* send request headers */ reqhdrs_arr = apr_table_elts(r->headers_in); reqhdrs = (apr_table_entry_t *) reqhdrs_arr->elts; for (i = 0; i < reqhdrs_arr->nelts; i++) { if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL /* Clear out headers not to send */ /* Clear out hop-by-hop request headers not to send * RFC2616 13.5.1 says we should strip these headers */ || !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */ || !strcasecmp(reqhdrs[i].key, "Keep-Alive") || !strcasecmp(reqhdrs[i].key, "TE") || !strcasecmp(reqhdrs[i].key, "Trailer") || !strcasecmp(reqhdrs[i].key, "Transfer-Encoding") || !strcasecmp(reqhdrs[i].key, "Upgrade") /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be * suppressed if THIS server requested the authentication, * not when a frontend proxy requested it! * * The solution to this problem is probably to strip out * the Proxy-Authorisation header in the authorisation * code itself, not here. This saves us having to signal * somehow whether this request was authenticated or not. */ || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization")) || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization") || !strcasecmp(reqhdrs[i].key, "Proxy-Authenticate")) continue; buf = apr_pstrcat(r->pool, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); } /* we don't yet support keepalives - but we will soon, I promise! */ buf = apr_pstrcat(r->pool, "Connection: close", CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); /* add empty line at the end of the headers */ e = apr_bucket_pool_create(CRLF, strlen(CRLF), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); e = apr_bucket_flush_create(); APR_BRIGADE_INSERT_TAIL(bb, e); ap_pass_brigade(origin->output_filters, bb); /* send the request data, if any. */ /* send the request data, if any. */ if (ap_should_client_block(r)) { while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) { e = apr_bucket_pool_create(buffer, i, r->pool); Loading Loading @@ -401,7 +434,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, int major, minor; if (2 != sscanf(buffer2, "HTTP/%u.%u", &major, &minor)) { major = 1; minor = 0; minor = 1; } /* If not an HTTP/1 message or if the status line was > 8192 bytes */ Loading Loading @@ -431,12 +464,14 @@ int ap_proxy_http_handler(request_rec *r, char *url, } else { clear_connection(p, resp_hdrs); /* Strip Connection hdrs */ /* strip connection listed hop-by-hop headers from response */ ap_proxy_clear_connection(p, resp_hdrs); if (apr_table_get(resp_hdrs, "Content-type")) { r->content_type = apr_pstrdup(r->pool, apr_table_get(resp_hdrs, "Content-type")); } } /* handle Via header in response */ if (conf->viaopt != via_off && conf->viaopt != via_block) { /* Create a "Via:" response header entry and merge it */ i = ap_get_server_port(r); Loading @@ -454,10 +489,13 @@ int ap_proxy_http_handler(request_rec *r, char *url, r->status_line = "200 OK"; } /* * HTTP/1.0 requires us to accept 3 types of dates, but only generate * one type */ /* munge the Location and URI response headers according to ProxyPassReverse */ if ((table_buf = apr_table_get(resp_hdrs, "Location")) != NULL) apr_table_set(resp_hdrs, "Location", ap_proxy_location_reverse_map(r, buf)); if ((table_buf = apr_table_get(resp_hdrs, "Content-Location")) != NULL) apr_table_set(resp_hdrs, "Content-Location", ap_proxy_location_reverse_map(r, buf)); if ((table_buf = apr_table_get(resp_hdrs, "URI")) != NULL) apr_table_set(resp_hdrs, "URI", ap_proxy_location_reverse_map(r, buf)); /* if (!r->assbackwards) Loading modules/proxy/proxy_util.c +4 −4 Original line number Diff line number Diff line Loading @@ -450,7 +450,7 @@ apr_table_t *ap_proxy_read_headers(request_rec *r, char *buffer, int size, conn_ for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) *end = '\0'; ap_table_add(resp_hdrs, buffer, value); apr_table_add(resp_hdrs, buffer, value); /* the header was too long; at the least we should skip extra data */ if (len >= size - 1) { Loading Loading @@ -482,7 +482,7 @@ void ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *t) apr_size_t len = strlen(temp); apr_send(fp, temp, &len); for (i = 0; i < ap_table_elts(t)->nelts; ++i) { for (i = 0; i < apr_table_elts(t)->nelts; ++i) { if (elts[i].key != NULL) { temp = apr_pstrcat(r->pool, elts[i].key, ": ", elts[i].val, CRLF, NULL); apr_send(fp, temp, &len); Loading Loading @@ -1046,7 +1046,7 @@ apr_status_t ap_proxy_doconnect(apr_socket_t *sock, char *host, apr_uint32_t por return rv; } /* This function is called by ap_table_do() for all header lines */ /* This function is called by apr_table_do() for all header lines */ /* (from proxy_http.c and proxy_ftp.c) */ /* It is passed a table_do_args struct pointer and a MIME field and value pair */ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) Loading @@ -1056,7 +1056,7 @@ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) return 1; if (!r->assbackwards) ap_rvputs(r, key, ": ", value, CRLF, NULL); return 1; /* tell ap_table_do() to continue calling us for more headers */ return 1; /* tell apr_table_do() to continue calling us for more headers */ } #if defined WIN32 Loading Loading
modules/proxy/proxy_http.c +61 −23 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, int def_p return OK; } static const char *proxy_location_reverse_map(request_rec *r, const char *url) static const char *ap_proxy_location_reverse_map(request_rec *r, const char *url) { void *sconf; proxy_server_conf *conf; Loading @@ -127,6 +127,9 @@ static const char *proxy_location_reverse_map(request_rec *r, const char *url) int i, l1, l2; char *u; /* XXX FIXME: Make sure this handled the ambiguous case of the :80 * after the hostname */ sconf = r->server->module_config; conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); l1 = strlen(url); Loading @@ -142,7 +145,7 @@ static const char *proxy_location_reverse_map(request_rec *r, const char *url) } /* Clear all connection-based headers from the incoming headers table */ static void clear_connection(apr_pool_t *p, apr_table_t *headers) static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers) { const char *name; char *next = apr_pstrdup(p, apr_table_get(headers, "Connection")); Loading Loading @@ -185,6 +188,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, apr_array_header_t *reqhdrs_arr; apr_table_t *resp_hdrs = NULL; apr_table_entry_t *reqhdrs; const char *table_buf; struct sockaddr_in server; struct in_addr destaddr; char buffer[HUGE_STRING_LEN]; Loading Loading @@ -285,14 +289,19 @@ int ap_proxy_http_handler(request_rec *r, char *url, /* the peer reset the connection already; ap_new_connection() * closed the socket */ /* XXX somebody that knows what they're doing add an error path */ /* XXX how's this? */ return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(r->pool, "Connection reset by peer: ", desthost, NULL)); } ap_add_output_filter("CORE", NULL, NULL, origin); clear_connection(r->pool, r->headers_in); /* Strip connection-based headers */ /* strip connection listed hop-by-hop headers from the request */ ap_proxy_clear_connection(r->pool, r->headers_in); buf = apr_pstrcat(r->pool, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF, NULL); " HTTP/1.1" CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) { Loading @@ -306,6 +315,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, APR_BRIGADE_INSERT_TAIL(bb, e); } /* handle Via */ if (conf->viaopt == via_block) { /* Block all outgoing Via: headers */ apr_table_unset(r->headers_in, "Via"); Loading @@ -318,7 +328,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, apr_snprintf(portstr, sizeof portstr, ":%d", i); } /* Generate outgoing Via: header with/without server comment: */ ap_table_mergen(r->headers_in, "Via", apr_table_mergen(r->headers_in, "Via", (conf->viaopt == via_full) ? apr_psprintf(p, "%d.%d %s%s (%s)", HTTP_VERSION_MAJOR(r->proto_num), Loading @@ -332,32 +342,55 @@ int ap_proxy_http_handler(request_rec *r, char *url, ); } /* send request headers */ reqhdrs_arr = apr_table_elts(r->headers_in); reqhdrs = (apr_table_entry_t *) reqhdrs_arr->elts; for (i = 0; i < reqhdrs_arr->nelts; i++) { if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL /* Clear out headers not to send */ /* Clear out hop-by-hop request headers not to send * RFC2616 13.5.1 says we should strip these headers */ || !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */ || !strcasecmp(reqhdrs[i].key, "Keep-Alive") || !strcasecmp(reqhdrs[i].key, "TE") || !strcasecmp(reqhdrs[i].key, "Trailer") || !strcasecmp(reqhdrs[i].key, "Transfer-Encoding") || !strcasecmp(reqhdrs[i].key, "Upgrade") /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be * suppressed if THIS server requested the authentication, * not when a frontend proxy requested it! * * The solution to this problem is probably to strip out * the Proxy-Authorisation header in the authorisation * code itself, not here. This saves us having to signal * somehow whether this request was authenticated or not. */ || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization")) || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization") || !strcasecmp(reqhdrs[i].key, "Proxy-Authenticate")) continue; buf = apr_pstrcat(r->pool, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); } /* we don't yet support keepalives - but we will soon, I promise! */ buf = apr_pstrcat(r->pool, "Connection: close", CRLF, NULL); e = apr_bucket_pool_create(buf, strlen(buf), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); /* add empty line at the end of the headers */ e = apr_bucket_pool_create(CRLF, strlen(CRLF), r->pool); APR_BRIGADE_INSERT_TAIL(bb, e); e = apr_bucket_flush_create(); APR_BRIGADE_INSERT_TAIL(bb, e); ap_pass_brigade(origin->output_filters, bb); /* send the request data, if any. */ /* send the request data, if any. */ if (ap_should_client_block(r)) { while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) { e = apr_bucket_pool_create(buffer, i, r->pool); Loading Loading @@ -401,7 +434,7 @@ int ap_proxy_http_handler(request_rec *r, char *url, int major, minor; if (2 != sscanf(buffer2, "HTTP/%u.%u", &major, &minor)) { major = 1; minor = 0; minor = 1; } /* If not an HTTP/1 message or if the status line was > 8192 bytes */ Loading Loading @@ -431,12 +464,14 @@ int ap_proxy_http_handler(request_rec *r, char *url, } else { clear_connection(p, resp_hdrs); /* Strip Connection hdrs */ /* strip connection listed hop-by-hop headers from response */ ap_proxy_clear_connection(p, resp_hdrs); if (apr_table_get(resp_hdrs, "Content-type")) { r->content_type = apr_pstrdup(r->pool, apr_table_get(resp_hdrs, "Content-type")); } } /* handle Via header in response */ if (conf->viaopt != via_off && conf->viaopt != via_block) { /* Create a "Via:" response header entry and merge it */ i = ap_get_server_port(r); Loading @@ -454,10 +489,13 @@ int ap_proxy_http_handler(request_rec *r, char *url, r->status_line = "200 OK"; } /* * HTTP/1.0 requires us to accept 3 types of dates, but only generate * one type */ /* munge the Location and URI response headers according to ProxyPassReverse */ if ((table_buf = apr_table_get(resp_hdrs, "Location")) != NULL) apr_table_set(resp_hdrs, "Location", ap_proxy_location_reverse_map(r, buf)); if ((table_buf = apr_table_get(resp_hdrs, "Content-Location")) != NULL) apr_table_set(resp_hdrs, "Content-Location", ap_proxy_location_reverse_map(r, buf)); if ((table_buf = apr_table_get(resp_hdrs, "URI")) != NULL) apr_table_set(resp_hdrs, "URI", ap_proxy_location_reverse_map(r, buf)); /* if (!r->assbackwards) Loading
modules/proxy/proxy_util.c +4 −4 Original line number Diff line number Diff line Loading @@ -450,7 +450,7 @@ apr_table_t *ap_proxy_read_headers(request_rec *r, char *buffer, int size, conn_ for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) *end = '\0'; ap_table_add(resp_hdrs, buffer, value); apr_table_add(resp_hdrs, buffer, value); /* the header was too long; at the least we should skip extra data */ if (len >= size - 1) { Loading Loading @@ -482,7 +482,7 @@ void ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *t) apr_size_t len = strlen(temp); apr_send(fp, temp, &len); for (i = 0; i < ap_table_elts(t)->nelts; ++i) { for (i = 0; i < apr_table_elts(t)->nelts; ++i) { if (elts[i].key != NULL) { temp = apr_pstrcat(r->pool, elts[i].key, ": ", elts[i].val, CRLF, NULL); apr_send(fp, temp, &len); Loading Loading @@ -1046,7 +1046,7 @@ apr_status_t ap_proxy_doconnect(apr_socket_t *sock, char *host, apr_uint32_t por return rv; } /* This function is called by ap_table_do() for all header lines */ /* This function is called by apr_table_do() for all header lines */ /* (from proxy_http.c and proxy_ftp.c) */ /* It is passed a table_do_args struct pointer and a MIME field and value pair */ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) Loading @@ -1056,7 +1056,7 @@ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) return 1; if (!r->assbackwards) ap_rvputs(r, key, ": ", value, CRLF, NULL); return 1; /* tell ap_table_do() to continue calling us for more headers */ return 1; /* tell apr_table_do() to continue calling us for more headers */ } #if defined WIN32 Loading