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-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=996c8079087821634e61bf8e4fbb7e927ca86362;p=thirdparty%2Fapache%2Fhttpd.git * 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/modules/ssl@102397 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/ssl_engine_io.c b/ssl_engine_io.c index 0574f574e5a..78cdb234c5b 100644 --- a/ssl_engine_io.c +++ b/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;