/*
 * 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 "http_protocol.h"
#include "ap_mmn.h"
#include "apr_lib.h"
#include "apr_buckets.h"
#include "apr_strings.h"
#include "apr_thread_proc.h"
#include "mod_cgi.h"
#include "mod_status.h"
#include "util_script.h"
#include "fcgid_global.h"
#include "fcgid_pm.h"
#include "fcgid_proctbl.h"
#include "fcgid_conf.h"
#include "fcgid_spawn_ctl.h"
#include "fcgid_bridge.h"
#include "fcgid_filter.h"
#include "fcgid_protocol.h"
#include "fcgid_proc.h"

static APR_OPTIONAL_FN_TYPE(ap_cgi_build_command) * cgi_build_command;
static ap_filter_rec_t *fcgid_filter_handle;
static int g_php_fix_pathinfo_enable = 0;

enum fcgid_procnode_type {
    FCGID_PROCNODE_TYPE_IDLE,
    FCGID_PROCNODE_TYPE_BUSY,
    FCGID_PROCNODE_TYPE_ERROR,
};

/* Stolen from mod_cgi.c */
/* KLUDGE --- for back-compatibility, we don't have to check ExecCGI
 * in ScriptAliased directories, which means we need to know if this
 * request came through ScriptAlias or not... so the Alias module
 * leaves a note for us.
 */

static int is_scriptaliased(request_rec * r)
{
    const char *t = apr_table_get(r->notes, "alias-forced-type");

    return t && (!strcasecmp(t, "cgi-script"));
}

static apr_status_t
default_build_command(const char **cmd, const char ***argv,
                      request_rec * r, apr_pool_t * p,
                      cgi_exec_info_t * e_info)
{
    int numwords, x, idx;
    char *w;
    const char *args = NULL;

    if (e_info->process_cgi) {
        *cmd = r->filename;
        /* Do not process r->args if they contain an '=' assignment 
         */
        if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) {
            args = r->args;
        }
    }

    if (!args) {
        numwords = 1;
    } else {
        /* count the number of keywords */
        for (x = 0, numwords = 2; args[x]; x++) {
            if (args[x] == '+') {
                ++numwords;
            }
        }
    }
    /* Everything is - 1 to account for the first parameter 
     * which is the program name.
     */
    if (numwords > APACHE_ARG_MAX - 1) {
        numwords = APACHE_ARG_MAX - 1;  /* Truncate args to prevent overrun */
    }
    *argv = apr_palloc(p, (numwords + 2) * sizeof(char *));
    (*argv)[0] = *cmd;
    for (x = 1, idx = 1; x < numwords; x++) {
        w = ap_getword_nulls(p, &args, '+');
        ap_unescape_url(w);
        (*argv)[idx++] = ap_escape_shell_cmd(p, w);
    }
    (*argv)[idx] = NULL;

    return APR_SUCCESS;
}

/* http2env stolen from util_script.c */
static char *http2env(apr_pool_t *a, const char *w)
{
    char *res = (char *)apr_palloc(a, sizeof("HTTP_") + strlen(w));
    char *cp = res;
    char c;

    *cp++ = 'H';
    *cp++ = 'T';
    *cp++ = 'T';
    *cp++ = 'P';
    *cp++ = '_';

    while ((c = *w++) != 0) {
        if (!apr_isalnum(c)) {
            *cp++ = '_';
        }
        else {
            *cp++ = apr_toupper(c);
        }
    }
    *cp = 0;
 
    return res;
}

static void fcgid_add_cgi_vars(request_rec * r)
{
    apr_array_header_t *passheaders = get_pass_headers(r);

    if (passheaders != NULL) {
        const char **hdr = (const char **) passheaders->elts;
        int hdrcnt = passheaders->nelts;
        int i;

        for (i = 0; i < hdrcnt; i++, ++hdr) {
            const char *val = apr_table_get(r->headers_in, *hdr);

            if (val) {
                /* no munging of header name to create envvar name;
                 * consistent with legacy mod_fcgid behavior and mod_fastcgi
                 * prior to 2.4.7
                 */
                apr_table_setn(r->subprocess_env, *hdr, val);
                /* standard munging of header name (upcase, HTTP_, etc.) */
                apr_table_setn(r->subprocess_env, http2env(r->pool, *hdr), val);
            }
        }
    }

    /* Work around cgi.fix_pathinfo = 1 in php.ini */
    if (g_php_fix_pathinfo_enable) {
        char *merge_path;
        apr_table_t *e = r->subprocess_env;

        /* "DOCUMENT_ROOT"/"SCRIPT_NAME" -> "SCRIPT_NAME" */
        const char *doc_root = apr_table_get(e, "DOCUMENT_ROOT");
        const char *script_name = apr_table_get(e, "SCRIPT_NAME");

        if (doc_root && script_name
            && apr_filepath_merge(&merge_path, doc_root, script_name, 0,
                                  r->pool) == APR_SUCCESS) {
            apr_table_setn(e, "SCRIPT_NAME", merge_path);
        }
    }
}

static int fcgid_handler(request_rec * r)
{
    cgi_exec_info_t e_info;
    const char *command;
    const char **argv;
    apr_status_t rv;
    int http_retcode;
    fcgid_cmd_conf *wrapper_conf;

    if (strcmp(r->handler, "fcgid-script"))
        return DECLINED;

    if (!(ap_allow_options(r) & OPT_EXECCGI) && !is_scriptaliased(r))
        return HTTP_FORBIDDEN;

    if ((r->used_path_info == AP_REQ_REJECT_PATH_INFO) &&
        r->path_info && *r->path_info)
        return HTTP_NOT_FOUND;

    e_info.process_cgi = 1;
    e_info.cmd_type = APR_PROGRAM;
    e_info.detached = 0;
    e_info.in_pipe = APR_CHILD_BLOCK;
    e_info.out_pipe = APR_CHILD_BLOCK;
    e_info.err_pipe = APR_CHILD_BLOCK;
    e_info.prog_type = RUN_AS_CGI;
    e_info.bb = NULL;
    e_info.ctx = NULL;
    e_info.next = NULL;

    wrapper_conf = get_wrapper_info(r->filename, r);

    /* Check for existence of requested file, unless we use a virtual wrapper. */
    if (wrapper_conf == NULL || !wrapper_conf->virtual) {
        if (r->finfo.filetype == 0)
            return HTTP_NOT_FOUND;

        if (r->finfo.filetype == APR_DIR)
            return HTTP_FORBIDDEN;
    }

    /* Build the command line */
    if (wrapper_conf) {
        if ((rv =
             default_build_command(&command, &argv, r, r->pool,
                                   &e_info)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          "mod_fcgid: don't know how to spawn wrapper child process: %s",
                          r->filename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    } else {
        if ((rv = cgi_build_command(&command, &argv, r, r->pool,
                                    &e_info)) != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          "mod_fcgid: don't know how to spawn child process: %s",
                          r->filename);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        /* Check request like "http://localhost/cgi-bin/a.exe/defghi" */
        if (r->finfo.inode == 0 && r->finfo.device == 0) {
            if ((rv =
                 apr_stat(&r->finfo, command, APR_FINFO_IDENT,
                          r->pool)) != APR_SUCCESS) {
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
                              "mod_fcgid: can't get %s file info", command);
                return HTTP_NOT_FOUND;
            }
        }

        /* Dummy up a wrapper configuration, using the requested file as 
         * both the executable path and command-line.
         */
        wrapper_conf = apr_pcalloc(r->pool, sizeof(*wrapper_conf));

        if (strlen(command) >= fcgid_min(FCGID_PATH_MAX, FCGID_CMDLINE_MAX)) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "mod_fcgid: Executable path length exceeds compiled-in limit: %s",
                          command);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        wrapper_conf->cgipath = apr_pstrdup(r->pool, command);
        wrapper_conf->cmdline = wrapper_conf->cgipath;
        wrapper_conf->inode = r->finfo.inode;
        wrapper_conf->deviceid = r->finfo.device;
    }

    ap_add_common_vars(r);
    ap_add_cgi_vars(r);
    fcgid_add_cgi_vars(r);

    /* Remove hop-by-hop headers handled by http
     */
    apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
    apr_table_unset(r->subprocess_env, "HTTP_TE");
    apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
    apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
    apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");

    /* Connection hop-by-hop header to prevent the CGI from hanging */
    apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close");

    /* Insert output filter */
    ap_add_output_filter_handle(fcgid_filter_handle, NULL, r,
                                r->connection);

    http_retcode = bridge_request(r, FCGI_RESPONDER, wrapper_conf);
    return (http_retcode == HTTP_OK ? OK : http_retcode);
}

static int fcgidsort(fcgid_procnode **e1, fcgid_procnode **e2)
{
    int cmp = strcmp((*e1)->executable_path, (*e2)->executable_path);

    if (cmp != 0)
        return cmp;
    if ((*e1)->gid != (*e2)->gid)
        return (*e1)->gid > (*e2)->gid ? 1 : -1;
    if ((*e1)->uid != (*e2)->uid)
        return (*e1)->uid > (*e2)->uid ? 1 : -1;
    cmp = strcmp((*e1)->cmdline, (*e2)->cmdline);
    if (cmp != 0)
        return cmp;
    if ((*e1)->vhost_id != (*e2)->vhost_id)
        return (*e1)->vhost_id > (*e2)->vhost_id ? 1 : -1;
    if ((*e1)->diewhy != (*e2)->diewhy)
        return (*e1)->diewhy > (*e2)->diewhy ? 1 : -1;
    if ((*e1)->node_type != (*e2)->node_type)
        return (*e1)->node_type > (*e2)->node_type ? 1 : -1;
    return 0;
}

static char *get_state_desc(fcgid_procnode *node)
{
    if (node->node_type == FCGID_PROCNODE_TYPE_IDLE)
        return "Ready";
    else if (node->node_type == FCGID_PROCNODE_TYPE_BUSY)
        return "Working";
    else {
        switch (node->diewhy) {
        case FCGID_DIE_KILLSELF:
            return "Exiting(normal exit)";
        case FCGID_DIE_IDLE_TIMEOUT:
            return "Exiting(idle timeout)";
        case FCGID_DIE_LIFETIME_EXPIRED:
            return "Exiting(lifetime expired)";
        case FCGID_DIE_BUSY_TIMEOUT:
            return "Exiting(busy timeout)";
        case FCGID_DIE_CONNECT_ERROR:
            return "Exiting(connect error)";
        case FCGID_DIE_COMM_ERROR:
            return "Exiting(communication error)";
        case FCGID_DIE_SHUTDOWN:
            return "Exiting(shutting down)";
        default:
            return "Exiting";
        }
    }
}
    
/* fcgid Extension to mod_status */
static int fcgid_status_hook(request_rec *r, int flags)
{       
    fcgid_procnode **ar = NULL, *current_node;
    int num_ent, index;
    apr_ino_t last_inode = 0;
    apr_dev_t last_deviceid = 0;
    gid_t last_gid = 0;  
    uid_t last_uid = 0;
    const char *last_cmdline = "";
    apr_time_t now;
    int last_vhost_id = -1;
    const char *basename, *tmpbasename;
    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();
        
    if ((flags & AP_STATUS_SHORT) || (proc_table == NULL))
        return OK;
            
    proctable_lock(r);
        
    /* Get element count */
    num_ent = 0;
    current_node = &proc_table[busy_list_header->next_index];
    while (current_node != proc_table) {
        num_ent++;
        current_node = &proc_table[current_node->next_index];
    }
    current_node = &proc_table[idle_list_header->next_index];
    while (current_node != proc_table) {
        num_ent++;
        current_node = &proc_table[current_node->next_index];
    }
    current_node = &proc_table[error_list_header->next_index];
    while (current_node != proc_table) {
        num_ent++;
        current_node = &proc_table[current_node->next_index];
    }

    /* Create an array for qsort() */
    if (num_ent != 0) {
        ar = (fcgid_procnode **)apr_palloc(r->pool, num_ent * sizeof(fcgid_procnode*));
        index = 0;
        current_node = &proc_table[busy_list_header->next_index];
        while (current_node != proc_table) {
            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
            *ar[index] = *current_node;
            ar[index++]->node_type = FCGID_PROCNODE_TYPE_BUSY;
            current_node = &proc_table[current_node->next_index];
        }
        current_node = &proc_table[idle_list_header->next_index];
        while (current_node != proc_table) {
            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
            *ar[index] = *current_node;
            ar[index++]->node_type = FCGID_PROCNODE_TYPE_IDLE;
            current_node = &proc_table[current_node->next_index];
        }    
        current_node = &proc_table[error_list_header->next_index];
        while (current_node != proc_table) {
            ar[index] = apr_palloc(r->pool, sizeof(fcgid_procnode));
            *ar[index] = *current_node;
            ar[index++]->node_type = FCGID_PROCNODE_TYPE_ERROR;
            current_node = &proc_table[current_node->next_index];
        }
    }
    proctable_unlock(r);

    now = apr_time_now();

    /* Sort the array */
    if (num_ent != 0)
        qsort((void *)ar, num_ent, sizeof(fcgid_procnode *),
              (int (*)(const void *, const void *))fcgidsort);
    
    /* Output */
    ap_rputs("<hr />\n<h1>mod_fcgid status:</h1>\n", r);
    ap_rprintf(r, "Total FastCGI processes: %d\n", num_ent);
    for (index = 0; index < num_ent; index++) {
    	current_node = ar[index];
        if (current_node->inode != last_inode || current_node->deviceid != last_deviceid
            || current_node->gid != last_gid || current_node->uid != last_uid
            || strcmp(current_node->cmdline, last_cmdline)
            || current_node->vhost_id != last_vhost_id) {
            if (index != 0)
                 ap_rputs("</table>\n\n", r);
           
            /* Print executable path basename */
	    tmpbasename = ap_strrchr_c(current_node->executable_path, '/');
	    if (tmpbasename != NULL)
                tmpbasename++;
            basename = ap_strrchr_c(tmpbasename, '\\');
            if (basename != NULL)
                basename++;
	    else
                basename = tmpbasename;
            ap_rprintf(r, "<hr />\n<b>Process: %s</b>&nbsp;&nbsp;(%s)<br />\n",
                       basename, current_node->cmdline);

            /* Create a new table for this process info */
            ap_rputs("\n\n<table border=\"0\"><tr>"
                     "<th>Pid</th><th>Active</th><th>Idle</th>"
                     "<th>Accesses</th><th>State</th>"
                     "</tr>\n", r);

            last_inode = current_node->inode;
            last_deviceid = current_node->deviceid;
            last_gid = current_node->gid;
            last_uid = current_node->uid;
            last_cmdline = current_node->cmdline;
            last_vhost_id = current_node->vhost_id;
        }

        ap_rprintf(r, "<tr><td>%" APR_PID_T_FMT "</td><td>%" APR_TIME_T_FMT "</td><td>%" APR_TIME_T_FMT "</td><td>%d</td><td>%s</td></tr>",
                   current_node->proc_id.pid,
                   apr_time_sec(now - current_node->start_time),
                   apr_time_sec(now - current_node->last_active_time),
                   current_node->requests_handled,
                   get_state_desc(current_node));
    }
    if (num_ent != 0) {
        ap_rputs("</table>\n\n", r);
        ap_rputs("<hr>\n"
                 "<b>Active</b> and <b>Idle</b> are time active and time since\n"
                 "last request, in seconds.\n", r);
    }

    return OK;
}

static int mod_fcgid_modify_auth_header(void *subprocess_env,
                                        const char *key, const char *val)
{
    /* When the application gives a 200 response, the server ignores response 
       headers whose names aren't prefixed with Variable- prefix, and ignores 
       any response content */
    if (strncasecmp(key, "Variable-", 9) == 0)
        apr_table_setn(subprocess_env, key + 9, val);
    return 1;
}

static int mod_fcgid_authenticator(request_rec * r)
{
    int res = 0;
    const char *password = NULL;
    apr_table_t *saved_subprocess_env = NULL;
    fcgid_cmd_conf *authenticator_info;
    int authoritative;

    authenticator_info = get_authenticator_info(r, &authoritative);

    /* Is authenticator enable? */
    if (authenticator_info == NULL)
        return DECLINED;

    /* Get the user password */
    if ((res = ap_get_basic_auth_pw(r, &password)) != OK)
        return res;

    /* Save old process environment */
    saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env);

    /* Add some environment variables */
    ap_add_common_vars(r);
    ap_add_cgi_vars(r);
    fcgid_add_cgi_vars(r);
    apr_table_setn(r->subprocess_env, "REMOTE_PASSWD", password);
    apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", "AUTHENTICATOR");

    /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED,
     * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass
     * PROXY_AUTH to allow CGI to perform proxy auth for httpd
     */
    apr_table_unset(r->subprocess_env, "CONTENT_LENGTH");
    apr_table_unset(r->subprocess_env, "PATH_INFO");
    apr_table_unset(r->subprocess_env, "PATH_TRANSLATED");
    apr_table_unset(r->subprocess_env, "SCRIPT_NAME");
    apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
    apr_table_unset(r->subprocess_env, "HTTP_TE");
    apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
    apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
    apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");

    /* Connection hop-by-hop header to prevent the CGI from hanging */
    apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close");

    /* Handle the request */
    res = bridge_request(r, FCGI_AUTHORIZER, authenticator_info);

    /* Restore r->subprocess_env */
    r->subprocess_env = saved_subprocess_env;

    if (res == OK && r->status == 200
        && apr_table_get(r->headers_out, "Location") == NULL)
    {
        /* Pass */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,
                      "mod_fcgid: user %s authentication pass", r->user);

        /* Modify headers: An Authorizer application's 200 response may include headers
           whose names are prefixed with Variable-.  */
        apr_table_do(mod_fcgid_modify_auth_header, r->subprocess_env,
                     r->err_headers_out, NULL);

        return OK;
    } else {
        /* Print error info first */
        if (res != OK)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authentication failed, respond %d, URI %s",
                          r->user, res, r->uri);
        else if (r->status != 200)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authentication failed, status %d, URI %s",
                          r->user, r->status, r->uri);
        else
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authentication failed, redirected is not allowed",
                          r->user);

        /* Handle error */
        if (!authoritative)
            return DECLINED;
        else {
            ap_note_basic_auth_failure(r);
            return (res == OK) ? HTTP_UNAUTHORIZED : res;
        }
    }
}

static int mod_fcgid_authorizer(request_rec * r)
{
    int res = 0;
    apr_table_t *saved_subprocess_env = NULL;
    fcgid_cmd_conf *authorizer_info;
    int authoritative;

    authorizer_info = get_authorizer_info(r, &authoritative);

    /* Is authenticator enable? */
    if (authorizer_info == NULL)
        return DECLINED;

    /* Save old process environment */
    saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env);

    /* Add some environment variables */
    ap_add_common_vars(r);
    ap_add_cgi_vars(r);
    fcgid_add_cgi_vars(r);
    apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", "AUTHORIZER");

    /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED,
     * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass
     * PROXY_AUTH to allow CGI to perform proxy auth for httpd
     */
    apr_table_unset(r->subprocess_env, "CONTENT_LENGTH");
    apr_table_unset(r->subprocess_env, "PATH_INFO");
    apr_table_unset(r->subprocess_env, "PATH_TRANSLATED");
    apr_table_unset(r->subprocess_env, "SCRIPT_NAME");
    apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
    apr_table_unset(r->subprocess_env, "HTTP_TE");
    apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
    apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
    apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");

    /* Connection hop-by-hop header to prevent the CGI from hanging */
    apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close");

    /* Handle the request */
    res = bridge_request(r, FCGI_AUTHORIZER, authorizer_info);

    /* Restore r->subprocess_env */
    r->subprocess_env = saved_subprocess_env;

    if (res == OK && r->status == 200
        && apr_table_get(r->headers_out, "Location") == NULL)
    {
        /* Pass */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,
                      "mod_fcgid: access granted (authorization)");

        /* Modify headers: An Authorizer application's 200 response may include headers
           whose names are prefixed with Variable-.  */
        apr_table_do(mod_fcgid_modify_auth_header, r->subprocess_env,
                     r->err_headers_out, NULL);

        return OK;
    } else {
        /* Print error info first */
        if (res != OK)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authorization failed, respond %d, URI %s",
                          r->user, res, r->uri);
        else if (r->status != 200)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authorization failed, status %d, URI %s",
                          r->user, r->status, r->uri);
        else
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s authorization failed, redirected is not allowed",
                          r->user);

        /* Handle error */
        if (!authoritative)
            return DECLINED;
        else {
            ap_note_basic_auth_failure(r);
            return (res == OK) ? HTTP_UNAUTHORIZED : res;
        }
    }
}

static int mod_fcgid_check_access(request_rec * r)
{
    int res = 0;
    apr_table_t *saved_subprocess_env = NULL;
    fcgid_cmd_conf *access_info;
    int authoritative;

    access_info = get_access_info(r, &authoritative);

    /* Is access check enable? */
    if (access_info == NULL)
        return DECLINED;

    /* Save old process environment */
    saved_subprocess_env = apr_table_copy(r->pool, r->subprocess_env);

    /* Add some environment variables */
    ap_add_common_vars(r);
    ap_add_cgi_vars(r);
    fcgid_add_cgi_vars(r);
    apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE",
                   "ACCESS_CHECKER");

    /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED,
     * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass
     * PROXY_AUTH to allow CGI to perform proxy auth for httpd
     */
    apr_table_unset(r->subprocess_env, "CONTENT_LENGTH");
    apr_table_unset(r->subprocess_env, "PATH_INFO");
    apr_table_unset(r->subprocess_env, "PATH_TRANSLATED");
    apr_table_unset(r->subprocess_env, "SCRIPT_NAME");
    apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
    apr_table_unset(r->subprocess_env, "HTTP_TE");
    apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
    apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
    apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");

    /* Connection hop-by-hop header to prevent the CGI from hanging */
    apr_table_set(r->subprocess_env, "HTTP_CONNECTION", "close");

    /* Handle the request */
    res = bridge_request(r, FCGI_AUTHORIZER, access_info);

    /* Restore r->subprocess_env */
    r->subprocess_env = saved_subprocess_env;

    if (res == OK && r->status == 200
        && apr_table_get(r->headers_out, "Location") == NULL)
    {
        /* Pass */
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,
                      "mod_fcgid: access check pass");

        /* Modify headers: An Authorizer application's 200 response may include headers
           whose names are prefixed with Variable-.  */
        apr_table_do(mod_fcgid_modify_auth_header, r->subprocess_env,
                     r->err_headers_out, NULL);

        return OK;
    } else {
        /* Print error info first */
        if (res != OK)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s access check failed, respond %d, URI %s",
                          r->user, res, r->uri);
        else if (r->status != 200)
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s access check failed, status %d, URI %s",
                          r->user, r->status, r->uri);
        else
            ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, 0, r,
                          "mod_fcgid: user %s access check failed, redirected is not allowed",
                          r->user);

        /* Handle error */
        if (!authoritative)
            return DECLINED;
        else {
            return (res == OK) ? HTTP_UNAUTHORIZED : res;
        }
    }
}

static void initialize_child(apr_pool_t * pchild, server_rec * main_server)
{
    apr_status_t rv;

    if ((rv = proctable_child_init(main_server, pchild)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't initialize shared memory or mutex in child");
        return;
    }

    if ((rv = procmgr_child_init(main_server, pchild)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't initialize process manager");
        return;
    }

    return;
}

static int
fcgid_init(apr_pool_t * config_pool, apr_pool_t * plog, apr_pool_t * ptemp,
           server_rec * main_server)
{
    const char *userdata_key = "fcgid_init";
    apr_status_t rv;
    void *dummy = NULL;
    fcgid_server_conf *sconf = ap_get_module_config(main_server->module_config,
                                                    &fcgid_module);

    ap_add_version_component(config_pool, MODFCGID_PRODUCT);

    g_php_fix_pathinfo_enable = sconf->php_fix_pathinfo_enable;

    /* Initialize process manager only once */
    apr_pool_userdata_get(&dummy, userdata_key,
                          main_server->process->pool);
    if (!dummy) {
        apr_pool_userdata_set((const void *)1, userdata_key,
                              apr_pool_cleanup_null,
                              main_server->process->pool);
        return OK;
    }

    /* Initialize share memory and share lock */
    if ((rv =
         proctable_post_config(main_server, config_pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't initialize shared memory or mutex");
        return rv;
    }

    /* Initialize process manager */
    if ((rv =
         procmgr_post_config(main_server, config_pool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, main_server,
                     "mod_fcgid: Can't initialize process manager");
        return rv;
    }

    /* This is the means by which unusual (non-unix) os's may find alternate
     * means to run a given command (e.g. shebang/registry parsing on Win32)
     */
    cgi_build_command = APR_RETRIEVE_OPTIONAL_FN(ap_cgi_build_command);
    if (!cgi_build_command) {
        cgi_build_command = default_build_command;
    }

    return APR_SUCCESS;
}

static const command_rec fcgid_cmds[] = {
    AP_INIT_TAKE1("FcgidAccessChecker", set_access_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "a absolute access checker file path"),
    AP_INIT_FLAG("FcgidAccessCheckerAuthoritative",
                 set_access_authoritative, NULL, ACCESS_CONF | OR_FILEINFO,
                 "Set to 'off' to allow access control to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidAuthenticator", set_authenticator_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "a absolute authenticator file path"),
    AP_INIT_FLAG("FcgidAuthenticatorAuthoritative",
                 set_authenticator_authoritative, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "Set to 'off' to allow authentication to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidAuthorizer", set_authorizer_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "a absolute authorizer file path"),
    AP_INIT_FLAG("FcgidAuthorizerAuthoritative",
                 set_authorizer_authoritative, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "Set to 'off' to allow authorization to be passed along to lower modules upon failure"),
    AP_INIT_TAKE1("FcgidBusyScanInterval", set_busy_scan_interval, NULL,
                  RSRC_CONF,
                  "scan interval for busy timeout process"),
    AP_INIT_TAKE1("FcgidBusyTimeout", set_busy_timeout, NULL, RSRC_CONF,
                  "a fastcgi application will be killed after handling a request for BusyTimeout"),
    AP_INIT_RAW_ARGS("FcgidCmdOptions", set_cmd_options, NULL, RSRC_CONF,
                     "set processing options for a FastCGI command"),
    AP_INIT_TAKE12("FcgidInitialEnv", add_default_env_vars, NULL, RSRC_CONF,
                   "an environment variable name and optional value to pass to FastCGI."),
    AP_INIT_TAKE1("FcgidMaxProcessesPerClass",
                  set_max_class_process,
                  NULL, RSRC_CONF,
                  "Max process count of one class of fastcgi application"),
    AP_INIT_TAKE1("FcgidMinProcessesPerClass",
                  set_min_class_process,
                  NULL, RSRC_CONF,
                  "Min process count of one class of fastcgi application"),
    AP_INIT_TAKE1("FcgidErrorScanInterval", set_error_scan_interval, NULL,
                  RSRC_CONF,
                  "scan interval for exited process"),
    AP_INIT_TAKE1("FcgidIdleScanInterval", set_idle_scan_interval, NULL,
                  RSRC_CONF,
                  "scan interval for idle timeout process"),
    AP_INIT_TAKE1("FcgidIdleTimeout", set_idle_timeout, NULL, RSRC_CONF,
                  "an idle fastcgi application will be killed after IdleTimeout"),
    AP_INIT_TAKE1("FcgidIOTimeout", set_ipc_comm_timeout, NULL, RSRC_CONF,
                  "Communication timeout to fastcgi server"),
    AP_INIT_TAKE1("FcgidConnectTimeout", set_ipc_connect_timeout, NULL,
                  RSRC_CONF,
                  "Connect timeout to fastcgi server"),
    AP_INIT_TAKE1("FcgidMaxProcesses", set_max_process, NULL, RSRC_CONF,
                  "Max total process count"),
    AP_INIT_TAKE1("FcgidMaxRequestInMem", set_max_mem_request_len, NULL,
                  RSRC_CONF,
                  "The part of HTTP request which greater than this limit will swap to disk"),
    AP_INIT_TAKE1("FcgidMaxRequestLen", set_max_request_len, NULL, RSRC_CONF,
                  "Max HTTP request length in byte"),
    AP_INIT_TAKE1("FcgidMaxRequestsPerProcess", set_max_requests_per_process,
                  NULL, RSRC_CONF,
                  "Max requests handled by each fastcgi application"),
    AP_INIT_TAKE1("FcgidOutputBufferSize", set_output_buffersize, NULL,
                  RSRC_CONF,
                  "CGI output buffer size"),
    AP_INIT_TAKE1("FcgidPassHeader", add_pass_headers, NULL, RSRC_CONF,
                  "Header name which will be passed to FastCGI as environment variable."),
    AP_INIT_TAKE1("FcgidFixPathinfo",
                  set_php_fix_pathinfo_enable,
                  NULL, RSRC_CONF,
                  "Set 1, if cgi.fix_pathinfo=1 in php.ini"),
    AP_INIT_TAKE1("FcgidProcessLifeTime", set_proc_lifetime, NULL, RSRC_CONF,
                  "fastcgi application lifetime"),
    AP_INIT_TAKE1("FcgidProcessTableFile", set_shmpath, NULL, RSRC_CONF,
                  "fastcgi shared memory file path"),
    AP_INIT_TAKE1("FcgidIPCDir", set_socketpath, NULL, RSRC_CONF,
                  "fastcgi socket file path"),
    AP_INIT_TAKE1("FcgidSpawnScore", set_spawn_score, NULL, RSRC_CONF,
                  "Score of spawn"),
    AP_INIT_TAKE1("FcgidSpawnScoreUpLimit", set_spawnscore_uplimit, NULL,
                  RSRC_CONF,
                  "Spawn score up limit"),
    AP_INIT_TAKE1("FcgidTerminationScore", set_termination_score, NULL,
                  RSRC_CONF,
                  "Score of termination"),
    AP_INIT_TAKE1("FcgidTimeScore", set_time_score, NULL,
                  RSRC_CONF,
                  "Score of passage of time (in seconds)"),
    AP_INIT_TAKE123("FcgidWrapper", set_wrapper_config, NULL,
                    RSRC_CONF | ACCESS_CONF | OR_FILEINFO,
                    "The CGI wrapper file an optional URL suffix and an optional flag"),
    AP_INIT_TAKE1("FcgidZombieScanInterval", set_zombie_scan_interval, NULL,
                  RSRC_CONF,
                  "scan interval for zombie process"),

    /* The following directives are all deprecated in favor
     * of a consistent use of the Fcgid prefix.
     * Add all new command above this line.
     */
    AP_INIT_TAKE1("BusyScanInterval", set_busy_scan_interval, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidBusyScanInterval' instead"),
    AP_INIT_TAKE1("BusyTimeout", set_busy_timeout, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidBusyTimeout' instead"),
    AP_INIT_TAKE12("DefaultInitEnv", add_default_env_vars, NULL, RSRC_CONF,
                   "Deprecated - Use 'FcgidInitialEnv' instead"),
    AP_INIT_TAKE1("DefaultMaxClassProcessCount",
                  set_max_class_process,
                  NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidMaxProcessesPerClass' instead"),
    AP_INIT_TAKE1("DefaultMinClassProcessCount",
                  set_min_class_process,
                  NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidMinProcessesPerClass' instead"),
    AP_INIT_TAKE1("ErrorScanInterval", set_error_scan_interval, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidErrorScanInterval' instead"),
    AP_INIT_TAKE1("FastCgiAccessChecker", set_access_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "Deprecated - Use 'FcgidAccessChecker' instead"),
    AP_INIT_FLAG("FastCgiAccessCheckerAuthoritative",
                 set_access_authoritative, NULL, ACCESS_CONF | OR_FILEINFO,
                 "Deprecated - Use 'FcgidAccessCheckerAuthoritative' instead"),
    AP_INIT_TAKE1("FastCgiAuthenticator", set_authenticator_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "Deprecated - Use 'FcgidAuthenticator' instead"),
    AP_INIT_FLAG("FastCgiAuthenticatorAuthoritative",
                 set_authenticator_authoritative, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "Deprecated - Use 'FcgidAuthenticatorAuthoritative' instead"),
    AP_INIT_TAKE1("FastCgiAuthorizer", set_authorizer_info, NULL,
                  ACCESS_CONF | OR_FILEINFO,
                  "Deprecated - Use 'FcgidAuthorizer' instead"),
    AP_INIT_FLAG("FastCgiAuthorizerAuthoritative",
                 set_authorizer_authoritative, NULL,
                 ACCESS_CONF | OR_FILEINFO,
                 "Deprecated - Use 'FcgidAuthorizerAuthoritative' instead"),
    AP_INIT_TAKE123("FCGIWrapper", set_wrapper_config, NULL,
                    RSRC_CONF | ACCESS_CONF | OR_FILEINFO,
                    "Deprecated - Use 'FcgidWrapper' instead"),
    AP_INIT_TAKE1("IdleScanInterval", set_idle_scan_interval, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidIdleScanInterval' instead"),
    AP_INIT_TAKE1("IdleTimeout", set_idle_timeout, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidIdleTimeout' instead"),
    AP_INIT_TAKE1("IPCCommTimeout", set_ipc_comm_timeout, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidIOTimeout' instead"),
    AP_INIT_TAKE1("IPCConnectTimeout", set_ipc_connect_timeout, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidConnectTimeout' instead"),
    AP_INIT_TAKE1("MaxProcessCount", set_max_process, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidMaxProcesses' instead"),
    AP_INIT_TAKE1("MaxRequestInMem", set_max_mem_request_len, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidMaxRequestInMem' instead"),
    AP_INIT_TAKE1("MaxRequestLen", set_max_request_len, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidMaxRequestLen' instead"),
    AP_INIT_TAKE1("MaxRequestsPerProcess", set_max_requests_per_process,
                  NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidMaxRequestsPerProcess' instead"),
    AP_INIT_TAKE1("OutputBufferSize", set_output_buffersize, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidOutputBufferSize' instead"),
    AP_INIT_TAKE1("PassHeader", add_pass_headers, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidPassHeader' instead"),
    AP_INIT_TAKE1("PHP_Fix_Pathinfo_Enable",
                  set_php_fix_pathinfo_enable,
                  NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidFixPathinfo' instead"),
    AP_INIT_TAKE1("ProcessLifeTime", set_proc_lifetime, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidProcessLifeTime' instead"),
    AP_INIT_TAKE1("SharememPath", set_shmpath, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidProcessTableFile' instead"),
    AP_INIT_TAKE1("SocketPath", set_socketpath, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidIPCDir' instead"),
    AP_INIT_TAKE1("SpawnScore", set_spawn_score, NULL, RSRC_CONF,
                  "Deprecated - Use 'FcgidSpawnScore' instead"),
    AP_INIT_TAKE1("SpawnScoreUpLimit", set_spawnscore_uplimit, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidSpawnScoreUpLimit' instead"),
    AP_INIT_TAKE1("TerminationScore", set_termination_score, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidTerminationScore' instead"),
    AP_INIT_TAKE1("TimeScore", set_time_score, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidTimeScore' instead"),
    AP_INIT_TAKE1("ZombieScanInterval", set_zombie_scan_interval, NULL,
                  RSRC_CONF,
                  "Deprecated - Use 'FcgidZombieScanInterval' instead"),
    {NULL}
};

static int fcgid_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                            apr_pool_t *ptemp)
{
    apr_status_t rv;

    APR_OPTIONAL_HOOK(ap, status_hook, fcgid_status_hook, NULL, NULL,
                      APR_HOOK_MIDDLE);

    rv = procmgr_pre_config(pconf, plog, ptemp);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = proctable_pre_config(pconf, plog, ptemp);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    return OK;
} 

static void register_hooks(apr_pool_t * p)
{
    ap_hook_pre_config(fcgid_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(fcgid_init, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_handler(fcgid_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_check_user_id(mod_fcgid_authenticator, NULL, NULL,
                          APR_HOOK_MIDDLE);
    ap_hook_auth_checker(mod_fcgid_authorizer, NULL, NULL,
                         APR_HOOK_MIDDLE);
    ap_hook_access_checker(mod_fcgid_check_access, NULL, NULL,
                           APR_HOOK_MIDDLE);

    /* Insert fcgid output filter */
    fcgid_filter_handle =
        ap_register_output_filter("FCGID_OUT",
                                  fcgid_filter,
                                  NULL, AP_FTYPE_RESOURCE - 10);
}

module AP_MODULE_DECLARE_DATA fcgid_module = {
    STANDARD20_MODULE_STUFF,
    create_fcgid_dir_config,    /* create per-directory config structure */
    merge_fcgid_dir_config,     /* merge per-directory config structures */
    create_fcgid_server_config, /* create per-server config structure */
    merge_fcgid_server_config,  /* merge per-server config structures */
    fcgid_cmds,                 /* command apr_table_t */
    register_hooks              /* register hooks */
};
