Commit 16d530fa authored by Ryan Bloom's avatar Ryan Bloom
Browse files

Fix ap_rvprintf to support more than 4K of data.

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
parent a598cb93
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
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
+1 −4
Original line number Diff line number Diff line
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
+49 −5
Original line number Diff line number Diff line
@@ -1133,20 +1133,64 @@ 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 (written != -1) {
	int n = vd.vbuff.curpos - vrprintf_buf;

    if (buffer_output(r, buf, written) != APR_SUCCESS)
	/* 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;
}