mod_proxy_http.c revision 26b3536faba2adf259e19db7af8d9b63adaa5503
97a9a944b5887e91042b019776c41d5dd74557aferikabele/* Licensed to the Apache Software Foundation (ASF) under one or more
97a9a944b5887e91042b019776c41d5dd74557aferikabele * contributor license agreements. See the NOTICE file distributed with
97a9a944b5887e91042b019776c41d5dd74557aferikabele * this work for additional information regarding copyright ownership.
8c81ebbdeed67059e7a1106d7c617543e901c3abyoshiki * The ASF licenses this file to You under the Apache License, Version 2.0
8c81ebbdeed67059e7a1106d7c617543e901c3abyoshiki * (the "License"); you may not use this file except in compliance with
8c81ebbdeed67059e7a1106d7c617543e901c3abyoshiki * the License. You may obtain a copy of the License at
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * Unless required by applicable law or agreed to in writing, software
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * distributed under the License is distributed on an "AS IS" BASIS,
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * See the License for the specific language governing permissions and
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * limitations under the License.
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd/* HTTP routines for Apache proxy */
3b3b7fc78d1f5bfc2769903375050048ff41ff26ndstatic apr_status_t ap_proxy_http_cleanup(const char *scheme,
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * Canonicalise http-like URLs.
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * scheme is the scheme for the URL
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * url is the URL starting with the first '/'
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * def_port is the default port for this scheme.
8c81ebbdeed67059e7a1106d7c617543e901c3abyoshiki const char *err;
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd const char *scheme;
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd /* ap_port_of_scheme() */
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd /* do syntatic check.
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd * We break the URL into host, port, path, search
06ba4a61654b3763ad65f52283832ebf058fdf1cslive err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "error parsing URL %s: %s",
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* now parse path/search args, according to rfc1738 */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* N.B. if this isn't a true proxy request, then the URL _path_
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * has already been decoded. True proxy requests have r->uri
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * == r->unparsed_uri, and no others have that property.
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* process path */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0, r->proxyreq);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport,
e1e8390280254f7f0580d701e583f670643d4f3fnilgun "/", path, (search) ? "?" : "", (search) ? search : "", NULL);
e1e8390280254f7f0580d701e583f670643d4f3fnilgun/* Clear all connection-based headers from the incoming headers table */
e1e8390280254f7f0580d701e583f670643d4f3fnilguntypedef struct foo {
e1e8390280254f7f0580d701e583f670643d4f3fnilgunstatic int clean_warning_headers(void *data, const char *key, const char *val)
e1e8390280254f7f0580d701e583f670643d4f3fnilgun ((foo*)data)->table = headers = apr_table_make(pool, 2);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * Parse this, suckers!
3a6531f1fd50efd78381e5800802a1449096781eslive * Warning = "Warning" ":" 1#warning-value
97a9a944b5887e91042b019776c41d5dd74557aferikabele * warning-value = warn-code SP warn-agent SP warn-text
3a6531f1fd50efd78381e5800802a1449096781eslive * [SP warn-date]
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * warn-code = 3DIGIT
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * warn-agent = ( host [ ":" port ] ) | pseudonym
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * ; the name or pseudonym of the server adding
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * ; the Warning header, for use in debugging
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * warn-text = quoted-string
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * warn-date = <"> HTTP-date <">
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * Buggrit, use a bloomin' regexp!
e1e8390280254f7f0580d701e583f670643d4f3fnilgun * (\d{3}\s+\S+\s+\".*?\"(\s+\"(.*?)\")?) --> whole in $1, date in $3
06ba4a61654b3763ad65f52283832ebf058fdf1cslive while (!ap_regexec(warn_rx, val, nmatch, pmatch, 0)) {
e1e8390280254f7f0580d701e583f670643d4f3fnilgun /* OK, we have a date here */
e1e8390280254f7f0580d701e583f670643d4f3fnilgunstatic apr_table_t *ap_proxy_clean_warnings(apr_pool_t *p, apr_table_t *headers)
2f46ce2a814d7f2b126dfb9f1b25fd64e2fbdc11rbowen x.time = apr_date_parse_http(apr_table_get(headers, "Date"));
e1e8390280254f7f0580d701e583f670643d4f3fnilgun apr_table_do(clean_warning_headers, &x, headers, "Warning", NULL);
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsfstatic int clear_conn_headers(void *data, const char *key, const char *val)
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd const char *name;
e1e8390280254f7f0580d701e583f670643d4f3fnilgun while (*next && !apr_isspace(*next) && (*next != ',')) {
0c4abc32c00611fe1d52c9661f5cc79a3f74c6d4nd while (*next && (apr_isspace(*next) || (*next == ','))) {
9c1260efa52c82c2a58e5b5f20cd6902563d95f5rbowenstatic void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers)
x.pool = p;
apr_bucket *e;
char *buf;
const char *cl_val)
apr_bucket *e;
char *buf;
CRLF,
NULL);
apr_bucket *e;
int flush)
if (flush) {
return status;
return APR_SUCCESS;
request_rec *r,
int seen_eos = 0;
apr_bucket *e;
if (header_brigade) {
return status;
return status;
if (seen_eos) {
return status;
if (header_brigade) {
return status;
request_rec *r,
const char *old_cl_val)
int seen_eos = 0;
apr_bucket *e;
if (old_cl_val) {
return status;
if (header_brigade) {
return status;
return status;
if (seen_eos) {
return status;
return APR_EOF;
if (header_brigade) {
return status;
request_rec *r,
int force_cl)
int seen_eos = 0;
apr_bucket *e;
const char *temp_dir;
char *template;
return status;
"modproxy.tmp.XXXXXX",
APR_FILEPATH_NATIVE, p);
temp_dir);
return status;
e = APR_BUCKET_NEXT(e)) {
const char *data;
const char *tmpfile_name;
return status;
return status;
if (seen_eos) {
return status;
if (tmpfile) {
return status;
apr_bucket *e;
char *buf;
int counter;
int force10;
force10 = 0;
if (!hostname) {
r->uri );
const char *buf;
c->remote_ip);
proxy_run_fixups(r);
if (r->main) {
NULL);
if (r->main) {
if (old_cl_val) {
if (old_te_val) {
goto skip_body;
return APR_EINVAL;
* This helps us avoid any election of C-L v.s. T-E
return status;
return status;
else if (old_te_val) {
if (force10
else if (old_cl_val) {
else if (!force10
if (!force10) {
switch(rb_method) {
case RB_STREAM_CHUNKED:
case RB_STREAM_CL:
case RB_SPOOL_CL:
|| (bytes_read > 0));
c->remote_ip,
return status;
return APR_SUCCESS;
static const char *date_hdrs[]
const char *name;
} transform_hdrs[] = {
for (i = 0; date_hdrs[i]; ++i) {
int len;
int saw_headers = 0;
*pread_len = 0;
if (saw_headers) {
++value;
end)
char *tmp_s = s;
*writen = n;
return rv;
char *server_portstr) {
const char *buf;
char keepchar;
apr_bucket *e;
int pread_len = 0;
int backend_broke = 0;
static const char *hop_by_hop_hdrs[] =
if (len == 0) {
if (len <= 0) {
backasswards = 0;
&pread_len);
r->method);
return r->status;
r->headers_out,
for (i=0; hop_by_hop_hdrs[i]; ++i) {
if (interim_response) {
r->status);
* ProxyPassReverse/etc from here to ap_proxy_read_headers
const char *buf;
if (backasswards) {
|| c->aborted) {
#if DEBUGGING
|| c->aborted) {
} while (!finish);
else if (!interim_response) {
|| c->aborted) {
} while (interim_response);
return DONE;
return OK;
return status;
return OK;
return OK;
int status;
char *scheme;
const char *proxy_function;
int is_ssl = 0;
return DECLINED;
return HTTP_BAD_REQUEST;
return DECLINED;
goto cleanup;
if (is_ssl)
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
if (backend) {
return status;
return APR_SUCCESS;