httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dean gaudet <dgaudet-list-new-ht...@arctic.org>
Subject Re: [PATCH] ap_vrprintf fix to handle > 4K
Date Wed, 08 Aug 2001 22:29:28 GMT
ew yuck.

please consult 1.3's src/main/buff.c ap_vbprintf() and see how you can do
this without exponential memory allocation.  you need to use
ap_vformatter() and a callback... but it's really worth it.

there's probably even a 2.0 way that just uses multiple 4K buffers
allocated one after the other and tacked onto the bucket to avoid the
extra copy... which still has the disadvantage that it could consume lots
of memory (1 byte per byte output) but at least it doesn't consume 2 bytes
per byte output memory.

also -- if you really want to do it the way you've done it below you might
as well use ap_psprintf() ... which does almost what you're doing, but it
can at least optimise its use of the free space in a pool.  but really the
bprintf() stuff from 1.3 is the best for an output buffer, 'cause you can
get rid of each 4K chunk as soon as you've finished writing to it, and
save memory.  psprintf() style stuff is only useful if you absolutely need
the entire output as a single string.

-dean

On Wed, 1 Aug 2001, Cody Sherr wrote:

>
> This allows ap_vrprintf to handle > 4k length writes, as listed in STATUS.
>
> regards,
>
> --
> Cody Sherr
>
> Engineer
> Covalent Technologies
>
> phone: (415)536-5292
> email: csherr@covalent.net
>
> Index: protocol.c
> ===================================================================
> RCS file: /home/cvspublic/httpd-2.0/server/protocol.c,v
> retrieving revision 1.35
> diff -u -r1.35 protocol.c
> --- protocol.c	2001/07/30 04:38:02	1.35
> +++ protocol.c	2001/08/01 21:08:02
> @@ -1135,14 +1135,31 @@
>
>  AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
>  {
> -    char buf[4096];
> +    char *buf;
> +    int   buf_size = 4096; /* start with a 4k buffer */
>      apr_size_t written;
>
>      if (r->connection->aborted)
>          return -1;
>
> -    /* ### fix this mechanism to allow more than 4K of output */
> -    written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
> +    buf = apr_palloc(r->pool, buf_size);
> +    while (1) {
> +	written = apr_vsnprintf(buf, buf_size, fmt, va);
> +
> +	/*
> +	 * Per the apr_vsnprintf comments, in no event does apr_snprintf return a negative
number.
> +	 * Therefore, it's not possible to distinguish between an output which was truncated,
> +	 * and an output which exactly filled the buffer.
> +	 */
> +	if (written == buf_size) {
> +	    buf_size *= 2;
> +	    buf = apr_palloc(r->pool, buf_size); /* want realloc */
> +	}
> +	else {
> +	    break;
> +	}
> +    }
> +
>      if (buffer_output(r, buf, written) != APR_SUCCESS)
>          return -1;
>
>
>



Mime
View raw message