summaryrefslogtreecommitdiff
path: root/modules/proxy/proxy_http.c
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2002-03-09 07:15:33 +0000
committerGraham Leggett <minfrin@apache.org>2002-03-09 07:15:33 +0000
commit01b5958cf7a7e33b2c584ebf8686c78dc700a1a7 (patch)
tree07a693a65500f2ddfa83ccbfc513036f358dc519 /modules/proxy/proxy_http.c
parentde8942eb9f1c05aabf2a7061659a20edd7e9dba9 (diff)
downloadhttpd-01b5958cf7a7e33b2c584ebf8686c78dc700a1a7.tar.gz
New directive ProxyIOBufferSize. Sets the size of the buffer used
when reading from a remote HTTP server in proxy. Modify receive/send loop in proxy_http and proxy_ftp so that should it be necessary, the remote server socket is closed before transmitting the last buffer (set by ProxyIOBufferSize) to the client. This prevents the backend server from being forced to hang around while the last few bytes are transmitted to a slow client. Fix the case where no error checking was performed on the final brigade in the loop. PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93811 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/proxy/proxy_http.c')
-rw-r--r--modules/proxy/proxy_http.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c
index 214967ebaf..754b809bef 100644
--- a/modules/proxy/proxy_http.c
+++ b/modules/proxy/proxy_http.c
@@ -75,6 +75,10 @@ typedef struct {
int close;
} proxy_http_conn_t;
+static apr_status_t ap_proxy_http_cleanup(request_rec *r,
+ proxy_http_conn_t *p_conn,
+ proxy_conn_rec *backend);
+
/*
* Canonicalise http-like URLs.
* scheme is the scheme for the URL
@@ -813,17 +817,19 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
"proxy: start body send");
/*
- * if we are overriding the errors, we cant put the content of the
- * page into the brigade
+ * if we are overriding the errors, we can't put the content
+ * of the page into the brigade
*/
if ( (conf->error_override ==0) || r->status < 400 ) {
- /* read the body, pass it to the output filters */
+
+ /* read the body, pass it to the output filters */
apr_bucket *e;
+ int finish = FALSE;
while (ap_get_brigade(rp->input_filters,
bb,
AP_MODE_READBYTES,
APR_BLOCK_READ,
- AP_IOBUFSIZE) == APR_SUCCESS) {
+ conf->io_buffer_size) == APR_SUCCESS) {
#if DEBUGGING
{
apr_off_t readbytes;
@@ -833,21 +839,44 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
getpid(), readbytes);
}
#endif
+ /* sanity check */
if (APR_BRIGADE_EMPTY(bb)) {
+ apr_brigade_cleanup(bb);
break;
}
+
+ /* found the last brigade? */
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
- ap_pass_brigade(r->output_filters, bb);
- break;
+ /* if this is the last brigade, cleanup the
+ * backend connection first to prevent the
+ * backend server from hanging around waiting
+ * for a slow client to eat these bytes
+ */
+ ap_proxy_http_cleanup(r, p_conn, backend);
+ /* signal that we must leave */
+ finish = TRUE;
}
- e = apr_bucket_flush_create();
- APR_BRIGADE_INSERT_TAIL(bb, e);
+
+ /* if no EOS yet, then we must flush */
+ if (FALSE == finish) {
+ e = apr_bucket_flush_create();
+ APR_BRIGADE_INSERT_TAIL(bb, e);
+ }
+
+ /* try send what we read */
if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS) {
/* Ack! Phbtt! Die! User aborted! */
p_conn->close = 1; /* this causes socket close below */
- break;
+ finish = TRUE;
}
+
+ /* make sure we always clean up after ourselves */
apr_brigade_cleanup(bb);
+
+ /* if we are done, leave */
+ if (TRUE == finish) {
+ break;
+ }
}
}
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
@@ -886,8 +915,11 @@ apr_status_t ap_proxy_http_cleanup(request_rec *r, proxy_http_conn_t *p_conn,
* we close the socket, otherwise we leave it open for KeepAlive support
*/
if (p_conn->close || (r->proto_num < HTTP_VERSION(1,1))) {
- apr_socket_close(p_conn->sock);
- backend->connection = NULL;
+ if (p_conn->sock) {
+ apr_socket_close(p_conn->sock);
+ p_conn->sock = NULL;
+ backend->connection = NULL;
+ }
}
return OK;
}