From: Ryan Bloom Date: Thu, 16 Aug 2001 05:04:39 +0000 (+0000) Subject: Fix ap_rvprintf to support more than 4K of data. X-Git-Tag: 2.0.24~81 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=12aad48bed050c538a284bb72124a2c8fa457492;p=apache Fix ap_rvprintf to support more than 4K of data. Submitted by: Cody Sherr git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90189 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 11065afbb5..cfa4b26b02 100644 --- 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 ] + *) 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 ffe27dbcbd..d40809544c 100644 --- 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 diff --git a/server/protocol.c b/server/protocol.c index edb9a9786f..7d320efe84 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -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; }