wb->outcnt = 0;
MP_INLINE apr_status_t modperl_wbucket_pass(modperl_wbucket_t *wb,                                            const char *buf, apr_size_t len,                                            int add_flush_bucket){    apr_bucket_alloc_t *ba = (*wb->filters)->c->bucket_alloc;    apr_bucket_brigade *bb;    apr_bucket *bucket;    const char *work_buf = buf;    if (wb->header_parse) {        request_rec *r = wb->r;        const char *bodytext = NULL;        int status;        /*         * since wb->outbuf is persistent between requests, if the         * current response is shorter than the size of wb->outbuf         * it may include data from the previous request at the         * end. When this function receives a pointer to         * wb->outbuf as 'buf', modperl_cgi_header_parse may         * return that irrelevant data as part of 'bodytext'. So         * to avoid this risk, we create a new buffer of size 'len'         * XXX: if buf wasn't 'const char *buf' we could simply do         * buf[len] = '\0'         */        /* MP_IOBUFSIZE is the size of wb->outbuf */        if (buf == wb->outbuf && len < MP_IOBUFSIZE) {            work_buf = (char *)apr_pcalloc(wb->pool, sizeof(char*)*len);            memcpy((void*)work_buf, buf, len);        }        MP_TRACE_f(MP_FUNC, "\n\n\tparsing headers: %d bytes [%s]\n", len,                   apr_pstrmemdup(wb->pool, work_buf, len));                status = modperl_cgi_header_parse(r, (char *)work_buf, &bodytext);        wb->header_parse = 0; /* only once per-request */        if (status == HTTP_MOVED_TEMPORARILY) {            return APR_SUCCESS; /* XXX: HTTP_MOVED_TEMPORARILY ? */        }        else if (status != OK) {            ap_log_error(APLOG_MARK, APLOG_WARNING,                         0, r->server, "%s did not send an HTTP header",                         r->uri);            r->status = status;            /* XXX: bodytext == NULL here */            return APR_SUCCESS;        }        else if (!bodytext) {            return APR_SUCCESS;        }        len -= (bodytext - work_buf);        work_buf = bodytext;    }    bb = apr_brigade_create(wb->pool, ba);    bucket = apr_bucket_transient_create(work_buf, len, ba);    APR_BRIGADE_INSERT_TAIL(bb, bucket);    if (add_flush_bucket) {        /* append the flush bucket rather then calling ap_rflush, to         * prevent a creation of yet another bb, which will cause an         * extra call for each filter in the chain */        apr_bucket *bucket = apr_bucket_flush_create(ba);        APR_BRIGADE_INSERT_TAIL(bb, bucket);    }    MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %d bytes\n"               "\t\tfrom %s\n\t\tto %s filter handler\n",               len,                ((wb->r && wb->filters == &wb->r->output_filters)                   ? "response handler" : "current filter handler"),               MP_FILTER_NAME(*(wb->filters)));    return ap_pass_brigade(*(wb->filters), bb);}