/*
 * 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 "ap_config.h"
#include "ap_mmn.h"
#include "httpd.h"
#include "http_core.h"
#include "http_request.h"
#include "http_protocol.h"
#include "apr_buckets.h"
#include "apr_thread_proc.h"
#include "mod_cgi.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"

module AP_MODULE_DECLARE_DATA fcgid_module;
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;

/* Stolen from mod_cgi.c */
/* KLUDGE --- for back-combatibility, 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;
}

/* End of stolen */

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)
				apr_table_setn(r->subprocess_env, *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_pool_t *p;
	apr_status_t rv;
	int http_retcode;
	fcgid_wrapper_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->finfo.filetype == 0)
		return HTTP_NOT_FOUND;

	if (r->finfo.filetype == APR_DIR)
		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;
	p = r->main ? r->main->pool : r->pool;

	/* Build the command line */
	if ((wrapper_conf = get_wrapper_info(r->filename, r))) {
		if ((rv =
			 default_build_command(&command, &argv, r, p,
								   &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, p,
								  &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 (!wrapper_conf && r->finfo.inode == 0 && r->finfo.device == 0) {
		if ((rv =
			 apr_stat(&r->finfo, command, APR_FINFO_IDENT,
					  r->pool)) != APR_SUCCESS) {
			ap_log_error(APLOG_MARK, APLOG_WARNING, rv, r->server,
						 "mod_fcgid: can't get %s file info", command);
			return HTTP_NOT_FOUND;
		}
	}

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

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

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

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;
	const char *location = NULL;
	apr_table_t *saved_subprocess_env = NULL;
	fcgid_wrapper_conf *wrapper_conf;
	auth_conf *authenticator_info;
	int authoritative;

	authenticator_info = get_authenticator_info(r, &authoritative);

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

	/* Check wrapper */
	wrapper_conf = get_wrapper_info(authenticator_info->path, r);

	/* 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");

	/* Remove some environment variables */
	/* The Web server does not send CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, and SCRIPT_NAME headers */
	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");

	/* Handle the request */
	res =
		bridge_request(r, FCGI_AUTHORIZER, authenticator_info->path,
					   wrapper_conf);

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

	if (res == OK && r->status == 200
		&& (location = 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;
	const char *location = NULL;
	apr_table_t *saved_subprocess_env = NULL;
	fcgid_wrapper_conf *wrapper_conf;
	auth_conf *authorizer_info;
	int authoritative;

	authorizer_info = get_authorizer_info(r, &authoritative);

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

	/* Check wrapper */
	wrapper_conf = get_wrapper_info(authorizer_info->path, r);

	/* 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");

	/* Remove some environment variables */
	/* The Web server does not send CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, and SCRIPT_NAME headers */
	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");

	/* Handle the request */
	res =
		bridge_request(r, FCGI_AUTHORIZER, authorizer_info->path,
					   wrapper_conf);

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

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

		/* 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 {
			ap_note_basic_auth_failure(r);
			return (res == OK) ? HTTP_UNAUTHORIZED : res;
		}
	}
}

static int mod_fcgid_check_access(request_rec * r)
{
	int res = 0;
	const char *location = NULL;
	apr_table_t *saved_subprocess_env = NULL;
	fcgid_wrapper_conf *wrapper_conf;
	auth_conf *access_info;
	int authoritative;

	access_info = get_access_info(r, &authoritative);

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

	/* Check wrapper */
	wrapper_conf = get_wrapper_info(access_info->path, r);

	/* 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");

	/* Remove some environment variables */
	/* The Web server does not send CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED, and SCRIPT_NAME headers */
	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");

	/* Handle the request */
	res =
		bridge_request(r, FCGI_AUTHORIZER, access_info->path,
					   wrapper_conf);

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

	if (res == OK && r->status == 200
		&& (location = 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 {
			ap_note_basic_auth_failure(r);
			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 share 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)
{
	apr_proc_t *procnew;
	const char *userdata_key = "fcgid_init";
	apr_status_t rv;
	void *dummy = NULL;

	g_php_fix_pathinfo_enable = get_php_fix_pathinfo_enable(main_server);

	/* Initialize process manager only once */
	apr_pool_userdata_get(&dummy, userdata_key,
						  main_server->process->pool);
	if (!dummy) {
		procnew =
			apr_pcalloc(main_server->process->pool, sizeof(*procnew));
		procnew->pid = -1;
		procnew->err = procnew->in = procnew->out = NULL;
		apr_pool_userdata_set((const void *) procnew, userdata_key,
							  apr_pool_cleanup_null,
							  main_server->process->pool);
		return OK;
	} else {
		procnew = dummy;
	}

	/* 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 share 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("IdleTimeout", set_idle_timeout, NULL, RSRC_CONF,
				  "an idle fastcgi application will be killed after IdleTimeout"),
	AP_INIT_TAKE1("IdleScanInterval", set_idle_scan_interval, NULL,
				  RSRC_CONF,
				  "scan interval for idle timeout process"),
	AP_INIT_TAKE1("BusyTimeout", set_busy_timeout, NULL, RSRC_CONF,
				  "a fastcgi application will be killed after handling a request for BusyTimeout"),
	AP_INIT_TAKE1("BusyScanInterval", set_busy_scan_interval, NULL,
				  RSRC_CONF,
				  "scan interval for busy timeout process"),
	AP_INIT_TAKE1("ErrorScanInterval", set_error_scan_interval, NULL,
				  RSRC_CONF,
				  "scan interval for exited process"),
	AP_INIT_TAKE1("ZombieScanInterval", set_zombie_scan_interval, NULL,
				  RSRC_CONF,
				  "scan interval for zombiz process"),
	AP_INIT_TAKE1("ProcessLifeTime", set_proc_lifetime, NULL, RSRC_CONF,
				  "fastcgi application lifetime"),
	AP_INIT_TAKE1("SocketPath", set_socketpath, NULL, RSRC_CONF,
				  "fastcgi socket file path"),
	AP_INIT_TAKE1("SharememPath", set_shmpath, NULL, RSRC_CONF,
				  "fastcgi share memory file path"),
	AP_INIT_TAKE1("SpawnScoreUpLimit", set_spawnscore_uplimit, NULL,
				  RSRC_CONF,
				  "Spawn score up limit"),
	AP_INIT_TAKE1("SpawnScore", set_spawn_score, NULL, RSRC_CONF,
				  "Score of spawn"),
	AP_INIT_TAKE1("TimeScore", set_time_score, NULL,
				  RSRC_CONF,
				  "Score of passage of time (in seconds)"),
	AP_INIT_TAKE1("TerminationScore", set_termination_score, NULL,
				  RSRC_CONF,
				  "Score of termination"),
	AP_INIT_TAKE1("MaxProcessCount", set_max_process, NULL, RSRC_CONF,
				  "Max total process count"),
	AP_INIT_TAKE1("DefaultMaxClassProcessCount",
				  set_max_class_process,
				  NULL, RSRC_CONF,
				  "Max process count of one class of fastcgi application"),
	AP_INIT_TAKE1("DefaultMinClassProcessCount",
				  set_min_class_process,
				  NULL, RSRC_CONF,
				  "Min process count of one class of fastcgi application"),
	AP_INIT_TAKE1("OutputBufferSize", set_output_buffersize, NULL,
				  RSRC_CONF,
				  "CGI output buffer size"),
	AP_INIT_TAKE1("IPCConnectTimeout", set_ipc_connect_timeout, NULL,
				  RSRC_CONF,
				  "Connect timeout to fastcgi server"),
	AP_INIT_TAKE1("IPCCommTimeout", set_ipc_comm_timeout, NULL, RSRC_CONF,
				  "Communication timeout to fastcgi server"),
	AP_INIT_TAKE1("MaxRequestLen", set_max_request_len, NULL, RSRC_CONF,
				  "Max HTTP request length in byte"),
	AP_INIT_TAKE1("MaxRequestInMem", set_max_mem_request_len, NULL,
				  RSRC_CONF,
				  "The part of HTTP request which greater than this limit will swap to disk"),
	AP_INIT_TAKE12("DefaultInitEnv", add_default_env_vars, NULL, RSRC_CONF,
				   "an environment variable name and optional value to pass to FastCGI."),
	AP_INIT_TAKE1("PassHeader", add_pass_headers, NULL, RSRC_CONF,
				  "Header name which will be passed to FastCGI as environment variable."),
	AP_INIT_TAKE12("FCGIWrapper", set_wrapper_config, NULL,
				   RSRC_CONF | ACCESS_CONF | OR_FILEINFO,
				   "The CGI wrapper setting"),
	AP_INIT_TAKE1("PHP_Fix_Pathinfo_Enable",
				  set_php_fix_pathinfo_enable,
				  NULL, RSRC_CONF,
				  "Set 1, if cgi.fix_pathinfo=1 in php.ini"),
	AP_INIT_TAKE1("MaxRequestsPerProcess", set_max_requests_per_process,
				  NULL, RSRC_CONF,
				  "Max requests handled by each fastcgi application"),
	AP_INIT_TAKE1("FastCgiAuthenticator", set_authenticator_info, NULL,
				  ACCESS_CONF | OR_FILEINFO,
				  "a absolute authenticator file path"),
	AP_INIT_FLAG("FastCgiAuthenticatorAuthoritative",
				 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("FastCgiAuthorizer", set_authorizer_info, NULL,
				  ACCESS_CONF | OR_FILEINFO,
				  "a absolute authorizer file path"),
	AP_INIT_FLAG("FastCgiAuthorizerAuthoritative",
				 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("FastCgiAccessChecker", set_access_info, NULL,
				  ACCESS_CONF | OR_FILEINFO,
				  "a absolute access checker file path"),
	AP_INIT_FLAG("FastCgiAccessCheckerAuthoritative",
				 set_access_authoritative, NULL, ACCESS_CONF | OR_FILEINFO,
				 "Set to 'off' to allow access control to be passed along to lower modules upon failure"),
	{NULL}
};

static void register_hooks(apr_pool_t * p)
{
	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 */
	NULL,						/* 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 */
};
