apr_status_t fcgid_filter()

in modules/fcgid/fcgid_filter.c [25:99]


apr_status_t fcgid_filter(ap_filter_t * f, apr_bucket_brigade * bb)
{
    apr_status_t rv;
    apr_bucket_brigade *tmp_brigade;
    apr_size_t save_size = 0;
    conn_rec *c = f->c;
    server_rec *s = f->r->server;
    fcgid_server_conf *sconf = ap_get_module_config(s->module_config,
                                                    &fcgid_module);

    tmp_brigade =
        apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
    while (!APR_BRIGADE_EMPTY(bb)) {
        apr_size_t readlen;
        const char *buffer;

        apr_bucket *e = APR_BRIGADE_FIRST(bb);

        if (APR_BUCKET_IS_EOS(e))
            break;

        if (APR_BUCKET_IS_METADATA(e)) {
            apr_bucket_delete(e);
            continue;
        }

        /* Read the bucket now */
        if ((rv = apr_bucket_read(e, &buffer, &readlen,
                                  APR_BLOCK_READ)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r,
                          "mod_fcgid: can't read data from fcgid handler");
            return rv;
        }

        /* Move on to next bucket if it's fastcgi header bucket */
        if (e->type == &ap_bucket_type_fcgid_header
            || (e->type == &apr_bucket_type_immortal && readlen == 0)) {
            apr_bucket_delete(e);
            continue;
        }
        save_size += readlen;

        /* Cache it to tmp_brigade */
        APR_BUCKET_REMOVE(e);
        APR_BRIGADE_INSERT_TAIL(tmp_brigade, e);

        /* I will pass tmp_brigade to next filter if I have got too much buckets */
        if (save_size > sconf->output_buffersize) {
            APR_BRIGADE_INSERT_TAIL(tmp_brigade,
                                    apr_bucket_flush_create(f->r->
                                                            connection->
                                                            bucket_alloc));

            if ((rv =
                 ap_pass_brigade(f->next, tmp_brigade)) != APR_SUCCESS)
                return rv;

            /* Is the client aborted? */
            if (c && c->aborted)
                return APR_SUCCESS;

            save_size = 0;
        }
    }

    /* Any thing left? */
    if (!APR_BRIGADE_EMPTY(tmp_brigade)) {
        if ((rv = ap_pass_brigade(f->next, tmp_brigade)) != APR_SUCCESS)
            return rv;
    }

    /* This filter is done once it has served up its content */
    ap_remove_output_filter(f);
    return APR_SUCCESS;
}