/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "httpd.h"
#include "http_request.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_pools.h"
#include "apr_file_io.h"
#include "util_script.h"
#include "fcgid_bridge.h"
#include "fcgid_pm.h"
#include "fcgid_proctbl.h"
#include "fcgid_proc.h"
#include "fcgid_conf.h"
#include "fcgid_spawn_ctl.h"
#include "fcgid_protocol.h"
#include "fcgid_bucket.h"
#define FCGID_APPLY_TRY_COUNT 2
#define FCGID_REQUEST_COUNT 32
#define FCGID_BRIGADE_CLEAN_STEP 32

static fcgid_procnode *apply_free_procnode(request_rec *r,
                                           fcgid_command * command)
{
    /* Scan idle list, find a node match inode, deviceid and groupid
       If there is no one there, return NULL */
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *busy_list_header, *proc_table;
    apr_ino_t inode = command->inode;
    apr_dev_t deviceid = command->deviceid;
    uid_t uid = command->uid;
    gid_t gid = command->gid;
    const char *cmdline = command->cmdline;

    proc_table = proctable_get_table_array();
    previous_node = proctable_get_idle_list();
    busy_list_header = proctable_get_busy_list();

    proctable_lock(r);
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];

        if (current_node->inode == inode
            && current_node->deviceid == deviceid
            && !strcmp(current_node->cmdline, cmdline)
            && current_node->vhost_id == command->vhost_id
            && current_node->uid == uid && current_node->gid == gid) {
            /* Unlink from idle list */
            previous_node->next_index = current_node->next_index;

            /* Link to busy list */
            current_node->next_index = busy_list_header->next_index;
            busy_list_header->next_index = current_node - proc_table;

            proctable_unlock(r);
            return current_node;
        }
        else
            previous_node = current_node;

        current_node = next_node;
    }
    proctable_unlock(r);

    /* Found nothing */
    return NULL;
}

static void
return_procnode(request_rec *r,
                fcgid_procnode *procnode, int communicate_error)
{
    fcgid_procnode *previous_node, *current_node, *next_node;
    fcgid_procnode *proc_table = proctable_get_table_array();
    fcgid_procnode *error_list_header = proctable_get_error_list();
    fcgid_procnode *idle_list_header = proctable_get_idle_list();
    fcgid_procnode *busy_list_header = proctable_get_busy_list();

    proctable_lock(r);

    /* Unlink the node from busy list first */
    previous_node = busy_list_header;
    current_node = &proc_table[previous_node->next_index];
    while (current_node != proc_table) {
        next_node = &proc_table[current_node->next_index];
        if (current_node == procnode) {
            /* Unlink from busy list */
            previous_node->next_index = current_node->next_index;
            break;
        }
        else
            previous_node = current_node;
        current_node = next_node;
    }

    /* Return to error list or idle list */
    if (communicate_error) {
        /* Link to error list */
        procnode->next_index = error_list_header->next_index;
        error_list_header->next_index = procnode - proc_table;
    }
    else {
        /* Link to idle list */
        procnode->next_index = idle_list_header->next_index;
        idle_list_header->next_index = procnode - proc_table;
    }

    proctable_unlock(r);
}

apr_status_t bucket_ctx_cleanup(void *thectx)
{
    /* Cleanup jobs:
       1. Free bucket buffer
       2. Return procnode
       NOTE: ipc will be clean when request pool cleanup, so I don't need to close it here
     */
    fcgid_bucket_ctx *ctx = (fcgid_bucket_ctx *) thectx;
    request_rec *r = ctx->ipc.request;

    /* Free bucket buffer */
    if (ctx->buffer) {
        apr_bucket_destroy(ctx->buffer);
        ctx->buffer = NULL;
    }

    /* proc_close_ipc() and ipc_handle_cleanup() do their own sanity
     * checks, but we'll do our own anyway
     */
    if (ctx->ipc.ipc_handle_info) {
        proc_close_ipc(&ctx->ipc);
        ctx->ipc.ipc_handle_info = NULL;
    }

    if (ctx->procnode) {
        ++ctx->procnode->requests_handled;

        /* Return procnode
           I will return this slot to idle(or error) list
         */
        if (ctx->procnode->diewhy == FCGID_DIE_BUSY_TIMEOUT) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                          "mod_fcgid: %s took longer than busy timeout "
                          "(%d secs)",
                          r->uri,
                          ctx->procnode->cmdopts.busy_timeout);
            return_procnode(r, ctx->procnode, 1 /* busy timeout */ );
        }
        else if (ctx->has_error) {
            ctx->procnode->diewhy = FCGID_DIE_COMM_ERROR;
            return_procnode(r, ctx->procnode, 1 /* communication error */ );
        }
        else if (ctx->procnode->cmdopts.max_requests_per_process
                 && ctx->procnode->requests_handled >=
                 ctx->procnode->cmdopts.max_requests_per_process) {
            ctx->procnode->diewhy = FCGID_DIE_LIFETIME_EXPIRED;
            return_procnode(r, ctx->procnode, 1 /* handled all requests */ );
        }
        else
            return_procnode(r, ctx->procnode, 0 /* communication ok */ );

        ctx->procnode = NULL;
    }

    return APR_SUCCESS;
}

static int getsfunc_fcgid_BRIGADE(char *buf, int len, void *arg)
{
    apr_bucket_brigade *bb = (apr_bucket_brigade *) arg;
    const char *dst_end = buf + len - 1;        /* leave room for terminating null */
    char *dst = buf;
    apr_bucket *e = APR_BRIGADE_FIRST(bb);
    apr_status_t rv;
    int done = 0;
    int getLF = 0;
    int getColon = 0;

    while ((dst < dst_end) && !done && e != APR_BRIGADE_SENTINEL(bb)) {
        const char *bucket_data;
        apr_size_t bucket_data_len;
        const char *src;
        const char *src_end;
        apr_bucket *next;

        rv = apr_bucket_read(e, &bucket_data, &bucket_data_len,
                             APR_BLOCK_READ);
        if (rv != APR_SUCCESS) {
            return 0;
        }

        /* 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) {
            next = APR_BUCKET_NEXT(e);
            apr_bucket_delete(e);
            e = next;
            if (getLF) {
                done = 1;
            }
            continue;
        }

        if (bucket_data_len == 0)
            return 0;

        /* Base on RFC2616 section 4.2 */
        src = bucket_data;
        src_end = bucket_data + bucket_data_len;
        while ((src < src_end) && (dst < dst_end) && !done) {
            if (*src == ':')
                getColon = 1;

            if (getLF && ((*src != ' ' && *src != '\t') || !getColon)) {
                done = 1;
                getColon = 0;
                break;
            }
            else if (getLF && (*src == ' ' || *src == '\t')) {
                *dst++ = '\r';
                *dst++ = '\n';
                getLF = 0;
            }

            if (*src == '\n') {
                getLF = 1;
            }
            else if (*src != '\r') {
                *dst++ = *src;
            }
            src++;
        }

        if (src < src_end) {
            apr_bucket_split(e, src - bucket_data);
        }
        next = APR_BUCKET_NEXT(e);
        apr_bucket_delete(e);
        e = next;
    }
    *dst = 0;
    return done;
}

static int
handle_request_ipc(request_rec *r, int role,
                   apr_bucket_brigade *output_brigade,
                   fcgid_bucket_ctx *bucket_ctx, const char **location_ptr)
{
    int cond_status;
    apr_status_t rv;
    apr_bucket_brigade *brigade_stdout;
    char sbuf[MAX_STRING_LEN];
    const char *location;

    /* Write output_brigade to fastcgi server */
    if ((rv = proc_write_ipc(&bucket_ctx->ipc,
                             output_brigade)) != APR_SUCCESS) {
        bucket_ctx->has_error = 1;
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Create brigade */
    brigade_stdout =
        apr_brigade_create(r->pool, r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(brigade_stdout,
                            ap_bucket_fcgid_header_create(r->connection->
                                                          bucket_alloc,
                                                          bucket_ctx));

    /* Check the script header first; return immediately on error. */
    if ((cond_status =
         ap_scan_script_header_err_core(r, sbuf, getsfunc_fcgid_BRIGADE,
                                        brigade_stdout))) {
        /*
         * cond_status could be HTTP_NOT_MODIFIED in the case that the FCGI
         * script does not set an explicit status and ap_meets_conditions,
         * which is called by ap_scan_script_header_err_brigade, detects that
         * the conditions of the requests are met and the response is
         * not modified.
         * In this case set r->status and return OK in order to prevent
         * running through the error processing stack as this would
         * break with mod_cache, if the conditions had been set by
         * mod_cache itself to validate a stale entity.
         * BTW: We circumvent the error processing stack anyway if the
         * FCGI script set an explicit status code (whatever it is) and
         * the only possible values for cond_status here are:
         *
         * HTTP_NOT_MODIFIED          (set by ap_meets_conditions)
         * HTTP_PRECONDITION_FAILED   (set by ap_meets_conditions)
         * HTTP_GATEWAY_TIME_OUT      (script timed out, returned no headers)
         * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
         * processing of the response of the FCGI script, e.g broken headers
         * or a crashed FCGI process).
         */
        if (cond_status == HTTP_NOT_MODIFIED) {
            /* We need to remove our fcgid_filter before returning this
             * status and code; otherwise, when ap_process_async_request()
             * invokes ap_finalize_request_protocol() and that calls
             * ap_pass_brigade(), fcgid_filter notices it has an empty
             * brigade and returns without calling ap_pass_brigade() itself,
             * which incorrectly circumvents the standard output filters.
             */
            ap_remove_output_filter(r->output_filters);

            r->status = cond_status;
            return OK;
        }

        return cond_status;
    }

    if (role == FCGI_AUTHORIZER) {
        return cond_status;
    }

    /* Check redirect */
    location = apr_table_get(r->headers_out, "Location");

    if (location && location[0] == '/' && r->status == 200) {
        /* This redirect needs to be a GET no matter what the original
         * method was.
         */
        r->method = apr_pstrdup(r->pool, "GET");
        r->method_number = M_GET;

        /* We already read the message body (if any), so don't allow
         * the redirected request to think it has one.  We can ignore
         * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
         */
        apr_table_unset(r->headers_in, "Content-Length");

        /* Setting this Location header value causes handle_request() to
         * invoke ap_internal_redirect_handler(); that calls
         * internal_internal_redirect() which sets the new sub-request's
         * r->output_filters back to r->proto_output_filters before
         * running the sub-request's handler.  Because we return here
         * without invoking ap_pass_brigade(), our fcgid_filter is ignored.
         */
        *location_ptr = location;
        return OK;
    }
    else if (location && r->status == 200) {
        /* XX Note that if a script wants to produce its own Redirect
         * body, it now has to explicitly *say* "Status: 302"
         */

        /* This return code causes ap_process_async_request() to invoke
         * ap_die(); that calls ap_send_error_response(), which resets
         * r->output_filters back to r->proto_output_filters, thus removing
         * our fcgid_filter from the output chain before making a final call
         * to ap_finalize_request_protocol(), which passes the brigade to
         * the standard output filters.
         */
        return HTTP_MOVED_TEMPORARILY;
    }

    /* Now pass any remaining response body data to output filters */
    if ((rv = ap_pass_brigade(r->output_filters,
                              brigade_stdout)) != APR_SUCCESS) {
        if (!APR_STATUS_IS_ECONNABORTED(rv)) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                          "mod_fcgid: ap_pass_brigade failed in "
                          "handle_request_ipc function");
        }

        return HTTP_INTERNAL_SERVER_ERROR;
    }

    return cond_status;
}

static int
handle_request(request_rec * r, int role, fcgid_cmd_conf *cmd_conf,
               apr_bucket_brigade * output_brigade)
{
    fcgid_command fcgi_request;
    fcgid_bucket_ctx *bucket_ctx;
    int i, j, cond_status;
    const char *location = NULL;

    bucket_ctx = apr_pcalloc(r->pool, sizeof(*bucket_ctx));

    bucket_ctx->ipc.request = r;
    apr_pool_cleanup_register(r->pool, bucket_ctx,
                              bucket_ctx_cleanup, apr_pool_cleanup_null);
    procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf);

    /* Try to get a connected ipc handle */
    for (i = 0; i < FCGID_REQUEST_COUNT; i++) {
        /* Apply a free process slot, send a spawn request if I can't get one */
        for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) {
            bucket_ctx->ipc.connect_timeout =
                fcgi_request.cmdopts.ipc_connect_timeout;
            bucket_ctx->ipc.communation_timeout =
                fcgi_request.cmdopts.ipc_comm_timeout;

            /* Apply a process slot */
            bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request);
            if (bucket_ctx->procnode)
                break;

            /* Send a spawn request if I can't get a process slot */
            /* procmgr_send_spawn_cmd() return APR_SUCCESS if a process is created */
            if( procmgr_send_spawn_cmd(&fcgi_request, r)==APR_SUCCESS ) {
                bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request);
                if (bucket_ctx->procnode)
                    break;
            }
            else {
                apr_sleep(apr_time_from_sec(1));
                bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request);
                if (bucket_ctx->procnode)
                    break;
            }
        }

        /* Connect to the fastcgi server */
        if (bucket_ctx->procnode) {
            if (proc_connect_ipc(bucket_ctx->procnode,
                                 &bucket_ctx->ipc) != APR_SUCCESS) {
                proc_close_ipc(&bucket_ctx->ipc);
                bucket_ctx->procnode->diewhy = FCGID_DIE_CONNECT_ERROR;
                return_procnode(r, bucket_ctx->procnode, 1 /* has error */ );
                bucket_ctx->procnode = NULL;
            }
            else
                break;
        }
    }

    /* Now I get a connected ipc handle */
    if (!bucket_ctx->procnode) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: can't apply process slot for %s",
                      cmd_conf->cmdline);
        return HTTP_SERVICE_UNAVAILABLE;
    }
    bucket_ctx->active_time = bucket_ctx->procnode->last_active_time =
        apr_time_now();
    bucket_ctx->procnode->diewhy = FCGID_DIE_KILLSELF;

    cond_status = handle_request_ipc(r, role, output_brigade,
                                     bucket_ctx, &location);

    /* Release the process ASAP.  This may already have been done in
     * ap_pass_brigade() by fcgid_header_bucket_read(), but not in the
     * case where handle_request_ipc() returned early without reading
     * the body of the HTTP response.  This could be because of an error,
     * or because of a role or a status code which permits us to ignore
     * the message body.
     *
     * As an example, when handling a request in the FCGI_AUTHORIZER role,
     * we don't read through to the end of the response from the process,
     * we just read the HTTP headers.  That means each phase of the
     * request handling sequence (e.g., authentication, authorization, etc.)
     * will require its own process unless we make sure to always release
     * any process we acquired regardless of whether we're reading the
     * response body.
     *
     * As another example, if we perform or cause an internal redirection
     * (for instance, by returning an error code that invokes a script
     * handler in ap_die() because of an ErrorDocument configuration), then
     * we must also release the process we acquired here so that it is
     * potentially available during the next handling phase.
     */

    apr_pool_cleanup_run(r->pool, bucket_ctx, bucket_ctx_cleanup);

    /* Perform internal redirection if necessary */
    if (location) {
        ap_internal_redirect_handler(location, r);
    }

    /* Return condition status */
    return cond_status;
}

static int add_request_body(request_rec *r, apr_pool_t *request_pool,
                            apr_bucket_brigade *output_brigade)
{
    apr_bucket *bucket_input, *bucket_header;
    apr_file_t *fd = NULL;
    apr_off_t cur_pos = 0, request_size = 0;
    apr_status_t rv;
    FCGI_Header *stdin_request_header;
    fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config,
                                                    &fcgid_module);
    int seen_eos = 0;

    /* Stdin header and body */
    /* I have to read all the request into memory before sending it
       to fastcgi application server, this prevents slow clients from
       keeping the server in processing too long.
       But sometimes it's not acceptable (think about uploading a large attachment)
       Request will be stored in tmp file if the size larger than max_mem_request_len
     */

    apr_bucket_brigade *input_brigade = apr_brigade_create(request_pool,
                                                           r->connection->
                                                           bucket_alloc);
    apr_bucket_brigade *tmp_brigade = apr_brigade_create(request_pool,
                                                           r->connection->
                                                           bucket_alloc);

    do {
        int loop_counter = 0;

        if ((rv = ap_get_brigade(r->input_filters, input_brigade,
                                 AP_MODE_READBYTES,
                                 APR_BLOCK_READ,
                                 HUGE_STRING_LEN)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                          "mod_fcgid: can't get data from http client");
            apr_brigade_destroy(output_brigade);
            apr_brigade_destroy(tmp_brigade);
            apr_brigade_destroy(input_brigade);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

	

        while ((bucket_input = APR_BRIGADE_FIRST(input_brigade)) != APR_BRIGADE_SENTINEL(input_brigade)) {
            const char *data;
            apr_size_t len;
            apr_bucket *bucket_stdin;

            ++loop_counter;
            if ((loop_counter % FCGID_BRIGADE_CLEAN_STEP) == 0) {
                apr_brigade_cleanup(tmp_brigade);
            }
            APR_BUCKET_REMOVE(bucket_input);
            APR_BRIGADE_INSERT_TAIL(tmp_brigade, bucket_input);

            if (APR_BUCKET_IS_EOS(bucket_input)) {
                seen_eos = 1;
                break;
            }

            if (APR_BUCKET_IS_METADATA(bucket_input))
                continue;

            if ((rv = apr_bucket_read(bucket_input, &data, &len,
                                      APR_BLOCK_READ)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                              "mod_fcgid: can't read request from HTTP client");
                apr_brigade_destroy(input_brigade);
                apr_brigade_destroy(tmp_brigade);
                apr_brigade_destroy(output_brigade);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            /* Append a header, and the the bucket */
            stdin_request_header = apr_bucket_alloc(sizeof(FCGI_Header),
                                                    r->connection->
                                                    bucket_alloc);
            bucket_header =
                apr_bucket_heap_create((const char *) stdin_request_header,
                                       sizeof(*stdin_request_header),
                                       apr_bucket_free,
                                       r->connection->bucket_alloc);

            request_size += len;
            if (request_size > sconf->max_request_len) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              "mod_fcgid: HTTP request length %" APR_OFF_T_FMT
                              " (so far) exceeds MaxRequestLen (%"
                              APR_OFF_T_FMT ")", request_size,
                              sconf->max_request_len);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            if (request_size > sconf->max_mem_request_len) {
                apr_size_t wrote_len;
                static const char *fd_key = "fcgid_fd";

                if (fd == NULL) {
                    void *tmp;
                    apr_pool_userdata_get(&tmp, fd_key, r->connection->pool);
                    fd = tmp;

                    if (fd != NULL) {
                        if ((rv = apr_file_trunc(fd, 0)) != APR_SUCCESS) {
                            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                          "mod_fcgid: can't truncate existing "
                                          "temporary file");
                            return HTTP_INTERNAL_SERVER_ERROR;
                        }
                    }
                }

                if (fd == NULL) {
                    const char *tempdir = NULL;
                    char *template;

                    rv = apr_temp_dir_get(&tempdir, r->pool);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                      "mod_fcgid: can't get tmp dir");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }

                    apr_filepath_merge(&template, tempdir,
                                       "fcgid.tmp.XXXXXX",
                                       APR_FILEPATH_NATIVE, r->pool);
                    rv = apr_file_mktemp(&fd, template, 0,
                                         r->connection->pool);
                    if (rv != APR_SUCCESS) {
                        ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                                      "mod_fcgid: can't open tmp file fot stdin request");
                        return HTTP_INTERNAL_SERVER_ERROR;
                    }
                    apr_pool_userdata_set((const void *) fd, fd_key,
                                          apr_pool_cleanup_null,
                                          r->connection->pool);
                }

                /* Write request to tmp file */
                if ((rv =
                     apr_file_write_full(fd, (const void *) data, len,
                                         &wrote_len)) != APR_SUCCESS
                    || len != wrote_len) {
                    ap_log_rerror(APLOG_MARK, APLOG_WARNING,
                                  rv, r,
                                  "mod_fcgid: can't write tmp file for stdin request");
                    return HTTP_INTERNAL_SERVER_ERROR;
                }
                /* Create file bucket */
                bucket_stdin =
                    apr_bucket_file_create(fd, cur_pos, len, r->pool,
                                           r->connection->bucket_alloc);
                cur_pos += len;
            }
            else {
                if (APR_BUCKET_IS_HEAP(bucket_input))
                    apr_bucket_copy(bucket_input, &bucket_stdin);
                else {
                    /* mod_ssl have a bug? */
                    char *pcopydata =
                        apr_bucket_alloc(len, r->connection->bucket_alloc);
                    memcpy(pcopydata, data, len);
                    bucket_stdin =
                        apr_bucket_heap_create(pcopydata, len,
                                               apr_bucket_free,
                                               r->connection->bucket_alloc);
                }
            }

            if (!init_header(FCGI_STDIN, 1, len, 0, stdin_request_header)) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                              "mod_fcgid: header overflow");
                apr_brigade_destroy(input_brigade);
                apr_brigade_destroy(tmp_brigade);
                apr_brigade_destroy(output_brigade);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_header);
            APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_stdin);
        }

        apr_brigade_cleanup(input_brigade);
        apr_brigade_cleanup(tmp_brigade);
    }
    while (!seen_eos);

    apr_brigade_destroy(input_brigade);
    apr_brigade_destroy(tmp_brigade);

    /* Append an empty body stdin header */
    stdin_request_header = apr_bucket_alloc(sizeof(FCGI_Header),
                                            r->connection->bucket_alloc);
    bucket_header =
        apr_bucket_heap_create((const char *) stdin_request_header,
                               sizeof(*stdin_request_header),
                               apr_bucket_free, r->connection->bucket_alloc);
    if (!init_header(FCGI_STDIN, 1, 0, 0, stdin_request_header)) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: header overflow");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_header);

    return 0;
}

int bridge_request(request_rec * r, int role, fcgid_cmd_conf *cmd_conf)
{
    apr_bucket_brigade *output_brigade;
    apr_bucket *bucket_eos;
    char **envp = ap_create_environment(r->pool,
                                        r->subprocess_env);
    int rc;

    /* Create brigade for the request to fastcgi server */
    output_brigade =
        apr_brigade_create(r->pool, r->connection->bucket_alloc);

    /* Build the begin request and environ request, append them to output_brigade */
    if (!build_begin_block
        (role, r, r->connection->bucket_alloc, output_brigade)
        || !build_env_block(r, envp, r->connection->bucket_alloc,
                            output_brigade)) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
                      "mod_fcgid: can't build begin or env request");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    if (role == FCGI_RESPONDER) {
        rc = add_request_body(r, r->pool, output_brigade);
        if (rc) {
            return rc;
        }
    }

    /* The eos bucket now */
    bucket_eos = apr_bucket_eos_create(r->connection->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_eos);

    /* Bridge the request */
    return handle_request(r, role, cmd_conf, output_brigade);
}
