From 5dc8b53fa3c40b7699baa0cb7d51a1378a890c4c Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Tue, 10 Jun 2014 19:18:55 +0000 Subject: [PATCH] merge r1591508 from trunk: mod_proxy_fcgi: Support iobuffersize parameter. Submitted by: trawick Reviewed by: jim, ylavic git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1601749 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 2 + STATUS | 4 -- modules/proxy/mod_proxy_fcgi.c | 75 +++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index f56ef656b6..39f7a342dc 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,8 @@ Changes with Apache 2.4.10 + *) mod_proxy_fcgi: Support iobuffersize parameter. [Jeff Trawick] + *) mod_auth_form: Add a debug message when the fields on a form are not recognised. [Graham Leggett] diff --git a/STATUS b/STATUS index 8e142b0c57..2f342013b6 100644 --- a/STATUS +++ b/STATUS @@ -100,10 +100,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy_fcgi: Support iobuffersize parameter. - trunk patch: http://svn.apache.org/r1591508 - 2.4.x patch: trunk works (modulo CHANGES) - +1: trawick, jim, ylavic PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index f949875f5c..9513e99074 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -395,7 +395,15 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, unsigned char farray[AP_FCGI_HEADER_LEN]; apr_pollfd_t pfd; int header_state = HDR_STATE_READING_HEADERS; - + char stack_iobuf[AP_IOBUFSIZE]; + apr_size_t iobuf_size = AP_IOBUFSIZE; + char *iobuf = stack_iobuf; + + if (conn->worker->s->io_buffer_size_set) { + iobuf_size = conn->worker->s->io_buffer_size; + iobuf = apr_palloc(r->pool, iobuf_size); + } + pfd.desc_type = APR_POLL_SOCKET; pfd.desc.s = conn->sock; pfd.p = r->pool; @@ -422,14 +430,13 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, } if (pfd.rtnevents & APR_POLLOUT) { - char writebuf[AP_IOBUFSIZE]; - apr_size_t writebuflen; + apr_size_t to_send, writebuflen; int last_stdin = 0; - int nvec = 0; + char *iobuf_cursor; rv = ap_get_brigade(r->input_filters, ib, AP_MODE_READBYTES, APR_BLOCK_READ, - sizeof(writebuf)); + iobuf_size); if (rv != APR_SUCCESS) { break; } @@ -438,9 +445,9 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, last_stdin = 1; } - writebuflen = sizeof(writebuf); + writebuflen = iobuf_size; - rv = apr_brigade_flatten(ib, writebuf, &writebuflen); + rv = apr_brigade_flatten(ib, iobuf, &writebuflen); apr_brigade_cleanup(ib); @@ -448,22 +455,35 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, break; } - ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id, - (apr_uint16_t) writebuflen, 0); - ap_fcgi_header_to_array(&header, farray); + to_send = writebuflen; + iobuf_cursor = iobuf; + while (to_send > 0) { + int nvec = 0; + apr_size_t write_this_time; + + write_this_time = + to_send < AP_FCGI_MAX_CONTENT_LEN ? to_send : AP_FCGI_MAX_CONTENT_LEN; - vec[nvec].iov_base = (void *)farray; - vec[nvec].iov_len = sizeof(farray); - ++nvec; - if (writebuflen) { - vec[nvec].iov_base = writebuf; - vec[nvec].iov_len = writebuflen; + ap_fcgi_fill_in_header(&header, AP_FCGI_STDIN, request_id, + (apr_uint16_t)write_this_time, 0); + ap_fcgi_header_to_array(&header, farray); + + vec[nvec].iov_base = (void *)farray; + vec[nvec].iov_len = sizeof(farray); ++nvec; - } + if (writebuflen) { + vec[nvec].iov_base = iobuf_cursor; + vec[nvec].iov_len = write_this_time; + ++nvec; + } - rv = send_data(conn, vec, nvec, &len, 0); - if (rv != APR_SUCCESS) { - break; + rv = send_data(conn, vec, nvec, &len, 0); + if (rv != APR_SUCCESS) { + break; + } + + to_send -= write_this_time; + iobuf_cursor += write_this_time; } if (last_stdin) { @@ -483,7 +503,6 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, } if (pfd.rtnevents & APR_POLLIN) { - char readbuf[AP_IOBUFSIZE]; apr_size_t readbuflen; apr_uint16_t clen, rid; apr_bucket *b; @@ -522,8 +541,8 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf, } recv_again: - if (clen > sizeof(readbuf)) { - readbuflen = sizeof(readbuf); + if (clen > iobuf_size) { + readbuflen = iobuf_size; } else { readbuflen = clen; } @@ -532,7 +551,7 @@ recv_again: * recv call, this will eventually change when we move to real * nonblocking recv calls. */ if (readbuflen != 0) { - rv = get_data(conn, readbuf, &readbuflen); + rv = get_data(conn, iobuf, &readbuflen); if (rv != APR_SUCCESS) { break; } @@ -541,14 +560,14 @@ recv_again: switch (type) { case AP_FCGI_STDOUT: if (clen != 0) { - b = apr_bucket_transient_create(readbuf, + b = apr_bucket_transient_create(iobuf, readbuflen, c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(ob, b); if (! seen_end_of_headers) { - int st = handle_headers(r, &header_state, readbuf); + int st = handle_headers(r, &header_state, iobuf); if (st == 1) { int status; @@ -647,7 +666,7 @@ recv_again: /* TODO: Should probably clean up this logging a bit... */ if (clen) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01071) - "Got error '%s'", readbuf); + "Got error '%s'", iobuf); } if (clen > readbuflen) { @@ -667,7 +686,7 @@ recv_again: } if (plen) { - rv = get_data_full(conn, readbuf, plen); + rv = get_data_full(conn, iobuf, plen); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02537) "Error occurred reading padding"); -- 2.40.0