From: Eric Covener Date: Fri, 11 Jan 2008 20:30:23 +0000 (+0000) Subject: *) mod_proxy_http: Return HTTP status codes instead of apr_status_t X-Git-Tag: 2.3.0~1031 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ea9fdcbc0fe783f11036f111f5ded36d185261e;p=apache *) mod_proxy_http: Return HTTP status codes instead of apr_status_t values for errors encountered while forwarding the request body PR 44165 [Eric Covener] See also PR 31759 / r448711 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@611292 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index f5607f95ac..90ccf0071d 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.3.0 [ When backported to 2.2.x, remove entry from this file ] + *) mod_proxy_http: Return HTTP status codes instead of apr_status_t + values for errors encountered while forwarding the request body + PR 44165 [Eric Covener] + *) mod_logio: Provide optional function to allow modules to adjust the bytes_in count [Eric Covener] diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index b174af2f86..ba35ea5b93 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -259,7 +259,7 @@ static void terminate_headers(apr_bucket_alloc_t *bucket_alloc, APR_BRIGADE_INSERT_TAIL(header_brigade, e); } -static apr_status_t pass_brigade(apr_bucket_alloc_t *bucket_alloc, +static int pass_brigade(apr_bucket_alloc_t *bucket_alloc, request_rec *r, proxy_conn_rec *conn, conn_rec *origin, apr_bucket_brigade *bb, int flush) @@ -279,22 +279,27 @@ static apr_status_t pass_brigade(apr_bucket_alloc_t *bucket_alloc, ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, "proxy: pass request body failed to %pI (%s)", conn->addr, conn->hostname); - return status; + if (origin->aborted) { + return APR_STATUS_IS_TIMEUP(status) ? HTTP_GATEWAY_TIME_OUT : HTTP_BAD_GATEWAY; + } + else { + return HTTP_BAD_REQUEST; + } } apr_brigade_cleanup(bb); - return APR_SUCCESS; + return OK; } #define MAX_MEM_SPOOL 16384 -static apr_status_t stream_reqbody_chunked(apr_pool_t *p, +static int stream_reqbody_chunked(apr_pool_t *p, request_rec *r, proxy_conn_rec *p_conn, conn_rec *origin, apr_bucket_brigade *header_brigade, apr_bucket_brigade *input_brigade) { - int seen_eos = 0; + int seen_eos = 0, rv = OK; apr_size_t hdr_len; apr_off_t bytes; apr_status_t status; @@ -352,7 +357,7 @@ static apr_status_t stream_reqbody_chunked(apr_pool_t *p, */ status = ap_save_brigade(NULL, &bb, &input_brigade, p); if (status != APR_SUCCESS) { - return status; + return HTTP_INTERNAL_SERVER_ERROR; } header_brigade = NULL; @@ -362,9 +367,9 @@ static apr_status_t stream_reqbody_chunked(apr_pool_t *p, } /* The request is flushed below this loop with chunk EOS header */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 0); - if (status != APR_SUCCESS) { - return status; + rv = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 0); + if (rv != OK) { + return rv; } if (seen_eos) { @@ -376,7 +381,7 @@ static apr_status_t stream_reqbody_chunked(apr_pool_t *p, HUGE_STRING_LEN); if (status != APR_SUCCESS) { - return status; + return HTTP_BAD_REQUEST; } } @@ -408,11 +413,11 @@ static apr_status_t stream_reqbody_chunked(apr_pool_t *p, } /* Now we have headers-only, or the chunk EOS mark; flush it */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1); - return status; + rv = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1); + return rv; } -static apr_status_t stream_reqbody_cl(apr_pool_t *p, +static int stream_reqbody_cl(apr_pool_t *p, request_rec *r, proxy_conn_rec *p_conn, conn_rec *origin, @@ -420,7 +425,7 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, apr_bucket_brigade *input_brigade, const char *old_cl_val) { - int seen_eos = 0; + int seen_eos = 0, rv = 0; apr_status_t status = APR_SUCCESS; apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; apr_bucket_brigade *bb; @@ -433,7 +438,7 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, add_cl(p, bucket_alloc, header_brigade, old_cl_val); if (APR_SUCCESS != (status = apr_strtoff(&cl_val, old_cl_val, NULL, 0))) { - return status; + return HTTP_INTERNAL_SERVER_ERROR; } } terminate_headers(bucket_alloc, header_brigade); @@ -486,7 +491,7 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, */ status = ap_save_brigade(NULL, &bb, &input_brigade, p); if (status != APR_SUCCESS) { - return status; + return HTTP_INTERNAL_SERVER_ERROR; } header_brigade = NULL; @@ -496,9 +501,9 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, } /* Once we hit EOS, we are ready to flush. */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, seen_eos); - if (status != APR_SUCCESS) { - return status; + rv = pass_brigade(bucket_alloc, r, p_conn, origin, bb, seen_eos); + if (rv != OK) { + return rv ; } if (seen_eos) { @@ -510,7 +515,7 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, HUGE_STRING_LEN); if (status != APR_SUCCESS) { - return status; + return HTTP_BAD_REQUEST; } } @@ -518,7 +523,7 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "proxy: client %s given Content-Length did not match" " number of body bytes read", r->connection->remote_ip); - return APR_EOF; + return HTTP_BAD_REQUEST; } if (header_brigade) { @@ -526,12 +531,13 @@ static apr_status_t stream_reqbody_cl(apr_pool_t *p, * body; send it now with the flush flag */ bb = header_brigade; - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1); + return(pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1)); } - return status; + + return OK; } -static apr_status_t spool_reqbody_cl(apr_pool_t *p, +static int spool_reqbody_cl(apr_pool_t *p, request_rec *r, proxy_conn_rec *p_conn, conn_rec *origin, @@ -572,7 +578,7 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, "proxy: search for temporary directory failed"); - return status; + return HTTP_INTERNAL_SERVER_ERROR; } apr_filepath_merge(&template, temp_dir, "modproxy.tmp.XXXXXX", @@ -582,7 +588,7 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, "proxy: creation of temporary file in directory %s failed", temp_dir); - return status; + return HTTP_INTERNAL_SERVER_ERROR; } } for (e = APR_BRIGADE_FIRST(input_brigade); @@ -602,7 +608,7 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, "proxy: write to temporary file %s failed", tmpfile_name); - return status; + return HTTP_INTERNAL_SERVER_ERROR; } AP_DEBUG_ASSERT(bytes_read == bytes_written); fsize += bytes_written; @@ -622,7 +628,7 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, */ status = ap_save_brigade(NULL, &body_brigade, &input_brigade, p); if (status != APR_SUCCESS) { - return status; + return HTTP_INTERNAL_SERVER_ERROR; } } @@ -638,7 +644,7 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, HUGE_STRING_LEN); if (status != APR_SUCCESS) { - return status; + return HTTP_BAD_REQUEST; } } @@ -655,12 +661,11 @@ static apr_status_t spool_reqbody_cl(apr_pool_t *p, APR_BRIGADE_INSERT_TAIL(header_brigade, e); } /* This is all a single brigade, pass with flush flagged */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, header_brigade, 1); - return status; + return(pass_brigade(bucket_alloc, r, p_conn, origin, header_brigade, 1)); } static -apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, +int ap_proxy_http_request(apr_pool_t *p, request_rec *r, proxy_conn_rec *p_conn, conn_rec *origin, proxy_server_conf *conf, apr_uri_t *uri, @@ -683,7 +688,7 @@ apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, const char *old_te_val = NULL; apr_off_t bytes_read = 0; apr_off_t bytes; - int force10; + int force10, rv; apr_table_t *headers_in_copy; header_brigade = apr_brigade_create(p, origin->bucket_alloc); @@ -926,7 +931,7 @@ apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "proxy: %s Transfer-Encoding is not supported", old_te_val); - return APR_EINVAL; + return HTTP_INTERNAL_SERVER_ERROR; } if (old_cl_val && old_te_val) { @@ -959,7 +964,7 @@ apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, " from %s (%s)", p_conn->addr, p_conn->hostname ? p_conn->hostname: "", c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; + return HTTP_BAD_REQUEST; } apr_brigade_length(temp_brigade, 1, &bytes); @@ -981,7 +986,7 @@ apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, " to %pI (%s) from %s (%s)", p_conn->addr, p_conn->hostname ? p_conn->hostname: "", c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; + return HTTP_INTERNAL_SERVER_ERROR; } /* Ensure we don't hit a wall where we have a buffer too small @@ -1095,37 +1100,38 @@ skip_body: /* send the request body, if any. */ switch(rb_method) { case RB_STREAM_CHUNKED: - status = stream_reqbody_chunked(p, r, p_conn, origin, header_brigade, + rv = stream_reqbody_chunked(p, r, p_conn, origin, header_brigade, input_brigade); break; case RB_STREAM_CL: - status = stream_reqbody_cl(p, r, p_conn, origin, header_brigade, + rv = stream_reqbody_cl(p, r, p_conn, origin, header_brigade, input_brigade, old_cl_val); break; case RB_SPOOL_CL: - status = spool_reqbody_cl(p, r, p_conn, origin, header_brigade, + rv = spool_reqbody_cl(p, r, p_conn, origin, header_brigade, input_brigade, (old_cl_val != NULL) || (old_te_val != NULL) || (bytes_read > 0)); break; default: /* shouldn't be possible */ - status = APR_EINVAL; + rv = HTTP_INTERNAL_SERVER_ERROR ; break; } - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + if (rv != OK) { + /* apr_errno value has been logged in lower level method */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "proxy: pass request body failed to %pI (%s)" " from %s (%s)", p_conn->addr, p_conn->hostname ? p_conn->hostname: "", c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; + return rv; } - return APR_SUCCESS; + return OK; } static void process_proxy_header(request_rec *r, proxy_dir_conf *c,