]> granicus.if.org Git - apache/commitdiff
* modules/ssl/ssl_engine_io.c (ssl_io_filter_output): Use non-blocking
authorJoe Orton <jorton@apache.org>
Fri, 23 Jan 2004 16:50:24 +0000 (16:50 +0000)
committerJoe Orton <jorton@apache.org>
Fri, 23 Jan 2004 16:50:24 +0000 (16:50 +0000)
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

CHANGES
modules/ssl/ssl_engine_io.c

diff --git a/CHANGES b/CHANGES
index c5111b82ca6b3dd2306853b4e96818127fdaef89..914ca8862030c2e58f3dc85bd191f4f1bf376594 100644 (file)
--- 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]
 
index 0574f574e5a5aa37512138574803b74b554aa063..78cdb234c5be830d715c08da4e0a86693fb22752 100644 (file)
@@ -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;