From: Joe Orton Date: Fri, 23 Jan 2004 16:50:24 +0000 (+0000) Subject: * modules/ssl/ssl_engine_io.c (ssl_io_filter_output): Use non-blocking X-Git-Tag: pre_ajp_proxy~776 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=812f43e5695068cc7f015c60b323ec594176f9ca;p=apache * modules/ssl/ssl_engine_io.c (ssl_io_filter_output): Use non-blocking bucket reads whilst data remains available; flush when a read returns EAGAIN. Fixes streaming nph- CGI scripts over SSL. PR: 21944 Inspired by: Jeff Trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102397 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index c5111b82ca..914ca88620 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.1.0-dev [Remove entries to the current 2.0 section below, when backported] + *) mod_ssl: Fix streaming output from an nph- CGI script. PR 21944 + [Joe Orton] + *) mod_log_config: Fix corruption of buffered logs with threaded MPMs. PR 25520. [Jeff Trawick] diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 0574f574e5..78cdb234c5 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -1370,6 +1370,8 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, apr_status_t status = APR_SUCCESS; ssl_filter_ctx_t *filter_ctx = f->ctx; bio_filter_in_ctx_t *inctx; + bio_filter_out_ctx_t *outctx; + apr_read_type_e rblock = APR_NONBLOCK_READ; if (f->c->aborted) { apr_brigade_cleanup(bb); @@ -1382,6 +1384,8 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, } inctx = (bio_filter_in_ctx_t *)filter_ctx->pbioRead->ptr; + outctx = (bio_filter_out_ctx_t *)filter_ctx->pbioWrite->ptr; + /* When we are the writer, we must initialize the inctx * mode so that we block for any required ssl input, because * output filtering is always nonblocking. @@ -1401,8 +1405,6 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, */ if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) { if (bio_filter_out_flush(filter_ctx->pbioWrite) < 0) { - bio_filter_out_ctx_t *outctx = - (bio_filter_out_ctx_t *)(filter_ctx->pbioWrite->ptr); status = outctx->rc; break; } @@ -1432,7 +1434,19 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, const char *data; apr_size_t len; - status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + status = apr_bucket_read(bucket, &data, &len, rblock); + + if (APR_STATUS_IS_EAGAIN(status)) { + /* No data available: flush... */ + if (bio_filter_out_flush(filter_ctx->pbioWrite) < 0) { + status = outctx->rc; + break; + } + rblock = APR_BLOCK_READ; + continue; /* and try again with a blocking read. */ + } + + rblock = APR_NONBLOCK_READ; if (!APR_STATUS_IS_EOF(status) && (status != APR_SUCCESS)) { break;