Commit ad81f265 authored by Joe Orton's avatar Joe Orton
Browse files

* 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
parent 27c30bbf
Loading
Loading
Loading
Loading
+17 −3
Original line number Diff line number Diff line
@@ -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;