]> granicus.if.org Git - apache/commitdiff
Fix ap_rvprintf to support more than 4K of data.
authorRyan Bloom <rbb@apache.org>
Thu, 16 Aug 2001 05:04:39 +0000 (05:04 +0000)
committerRyan Bloom <rbb@apache.org>
Thu, 16 Aug 2001 05:04:39 +0000 (05:04 +0000)
Submitted by: Cody Sherr <csherr@covalent.net>

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90189 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
server/protocol.c

diff --git a/CHANGES b/CHANGES
index 11065afbb504e024bfcf0d0f56531722dbe8fefb..cfa4b26b02bdb6a5bd2c52a0075625f8ba01672c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 Changes with Apache 2.0.24-dev
 
+  *) Fix ap_rvprintf to support more than 4K of data at one time.
+     [Cody Sherr <csherr@covalent.net>]
+
   *) We have always used the obsolete/deprecated Netscape syntax
      for our tracking cookies; now the CookieStyle directive
      allows the Webmaster to choose the Netscape, RFC2109, or
diff --git a/STATUS b/STATUS
index ffe27dbcbde4643f26825a57076c5f76b36ec3cf..d40809544caed2e910aac5ad7932b7c69d68cdb1 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
 APACHE 2.0 STATUS:                                             -*-text-*-
-Last modified at [$Date: 2001/08/16 05:01:43 $]
+Last modified at [$Date: 2001/08/16 05:04:38 $]
 
 Release:
 
@@ -58,9 +58,6 @@ RELEASE SHOWSTOPPERS:
            installed and a "make clean" in aprutil would make Apache
            fail to load.
 
-    * ap_vrprintf() needs to handle more than 4K
-        Status: Greg volunteers
-
     * mod_dir should normally redirect ALL directory requests which do
       not include a trailing slash on the URI. However, if a "notes"
       flag is set (say, via BrowserMatch), this behavior will be
index edb9a9786f0f6642c7a3f702cbb71ab3ca83acbd..7d320efe84d85e20e12e6c167c806555eaed4dca 100644 (file)
@@ -1133,19 +1133,63 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
     return nbyte;
 }
 
+struct ap_vrprintf_data {
+    apr_vformatter_buff_t vbuff;
+    request_rec *r;
+    char *buff;
+};
+
+static apr_status_t r_flush(apr_vformatter_buff_t *buff)
+{
+    /* callback function passed to ap_vformatter to be called when
+     * vformatter needs to write into buff and buff.curpos > buff.endpos */
+
+    /* ap_vrprintf_data passed as a apr_vformatter_buff_t, which is then
+     * "downcast" to an ap_vrprintf_data */
+    struct ap_vrprintf_data *vd = (struct ap_vrprintf_data*)buff;
+
+    if (vd->r->connection->aborted)
+        return -1;
+
+    /* r_flush is called when vbuff is completely full */
+    if (buffer_output(vd->r, vd->buff, AP_IOBUFSIZE)) {
+       return -1;
+    }
+
+    /* reset the buffer position */
+    vd->vbuff.curpos = vd->buff;
+    vd->vbuff.endpos = vd->buff + AP_IOBUFSIZE;
+
+    return APR_SUCCESS;
+}
+
 AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
 {
-    char buf[4096];
     apr_size_t written;
+    struct ap_vrprintf_data vd;
+    static char vrprintf_buf[AP_IOBUFSIZE];
+
+    vd.vbuff.curpos = vrprintf_buf;
+    vd.vbuff.endpos = vrprintf_buf + AP_IOBUFSIZE;
+    vd.r = r;
+    vd.buff = vrprintf_buf;
 
     if (r->connection->aborted)
         return -1;
 
-    /* ### fix this mechanism to allow more than 4K of output */
-    written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
+    written = apr_vformatter(r_flush, &vd.vbuff, fmt, va);
+    /* tack on null terminator on remaining string */
+    *(vd.vbuff.curpos) = '\0';
 
-    if (buffer_output(r, buf, written) != APR_SUCCESS)
-        return -1;
+    if (written != -1) {
+       int n = vd.vbuff.curpos - vrprintf_buf;
+
+       /* last call to buffer_output, to finish clearing the buffer */
+       if (buffer_output(r, vrprintf_buf,n) != APR_SUCCESS)
+           return -1;
+
+       written += n;
+    }
 
     return written;
 }