blob: 7648fee9ba09290dd89632f6932baf2372178f73 [file] [log] [blame]
/*
* 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 "apr_strings.h"
#include "apr_hash.h"
#include "apr_tables.h"
#include "http_main.h"
#include "httpd.h"
#include "http_config.h"
#include "fcgid_global.h"
#include "fcgid_conf.h"
extern module AP_MODULE_DECLARE_DATA fcgid_module;
#define DEFAULT_IDLE_TIMEOUT 300
#define DEFAULT_IDLE_SCAN_INTERVAL 120
#define DEFAULT_BUSY_TIMEOUT 300
#define DEFAULT_BUSY_SCAN_INTERVAL 120
#define DEFAULT_ERROR_SCAN_INTERVAL 3
#define DEFAULT_ZOMBIE_SCAN_INTERVAL 3
#define DEFAULT_PROC_LIFETIME (60*60)
#define DEFAULT_SOCKET_PREFIX "logs/fcgidsock"
#define DEFAULT_SHM_PATH "logs/fcgid_shm"
#define DEFAULT_SPAWNSOCRE_UPLIMIT 10
#define DEFAULT_SPAWN_SCORE 1
#define DEFAULT_TERMINATION_SCORE 2
#define DEFAULT_TIME_SCORE 1
#define DEFAULT_MAX_PROCESS_COUNT 1000
#define DEFAULT_MAX_CLASS_PROCESS_COUNT 100
#define DEFAULT_MIN_CLASS_PROCESS_COUNT 3
#define DEFAULT_IPC_CONNECT_TIMEOUT 3
#define DEFAULT_IPC_COMM_TIMEOUT 40
#define DEFAULT_OUTPUT_BUFFERSIZE 65536
#define DEFAULT_MAX_REQUESTS_PER_PROCESS -1
#define DEFAULT_MAX_REQUEST_LEN (1024*1024*1024) /* 1G */
#define DEFAULT_MAX_MEM_REQUEST_LEN (1024*64) /* 64k */
static void init_server_config(apr_pool_t * p, fcgid_server_conf * config)
{
config->default_init_env = NULL;
config->pass_headers = NULL;
config->sockname_prefix =
ap_server_root_relative(p, DEFAULT_SOCKET_PREFIX);
config->shmname_path = ap_server_root_relative(p, DEFAULT_SHM_PATH);
config->idle_timeout = DEFAULT_IDLE_TIMEOUT;
config->idle_scan_interval = DEFAULT_IDLE_SCAN_INTERVAL;
config->busy_scan_interval = DEFAULT_BUSY_SCAN_INTERVAL;
config->proc_lifetime = DEFAULT_PROC_LIFETIME;
config->error_scan_interval = DEFAULT_ERROR_SCAN_INTERVAL;
config->zombie_scan_interval = DEFAULT_ZOMBIE_SCAN_INTERVAL;
config->spawn_score = DEFAULT_SPAWN_SCORE;
config->spawnscore_uplimit = DEFAULT_SPAWNSOCRE_UPLIMIT;
config->termination_score = DEFAULT_TERMINATION_SCORE;
config->time_score = DEFAULT_TIME_SCORE;
config->max_class_process_count = DEFAULT_MAX_CLASS_PROCESS_COUNT;
config->min_class_process_count = DEFAULT_MIN_CLASS_PROCESS_COUNT;
config->max_process_count = DEFAULT_MAX_PROCESS_COUNT;
config->output_buffersize = DEFAULT_OUTPUT_BUFFERSIZE;
config->ipc_comm_timeout = DEFAULT_IPC_COMM_TIMEOUT;
config->ipc_connect_timeout = DEFAULT_IPC_CONNECT_TIMEOUT;
config->busy_timeout = DEFAULT_BUSY_TIMEOUT;
config->php_fix_pathinfo_enable = 0;
config->max_requests_per_process = DEFAULT_MAX_REQUESTS_PER_PROCESS;
config->max_request_len = DEFAULT_MAX_REQUEST_LEN;
config->max_mem_request_len = DEFAULT_MAX_MEM_REQUEST_LEN;
}
void *create_fcgid_server_config(apr_pool_t * p, server_rec * s)
{
fcgid_server_conf *config = apr_pcalloc(p, sizeof(*config));
init_server_config(p, config);
return config;
}
void *merge_fcgid_server_config(apr_pool_t * p, void *basev, void *locv)
{
int i;
fcgid_server_conf *merged_config =
(fcgid_server_conf *) apr_pcalloc(p, sizeof(fcgid_server_conf));
fcgid_server_conf *base = (fcgid_server_conf *) basev;
fcgid_server_conf *local = (fcgid_server_conf *) locv;
const apr_array_header_t *baseenv_array, *locenv_array;
init_server_config(p, merged_config);
/* Merge environment variables */
baseenv_array = apr_table_elts(base->default_init_env);
locenv_array = apr_table_elts(local->default_init_env);
if (baseenv_array != NULL || locenv_array != NULL) {
merged_config->default_init_env = apr_table_make(p, 20);
if (locenv_array != NULL) {
const apr_table_entry_t *locenv_entry =
(apr_table_entry_t *) locenv_array->elts;
for (i = 0; i < locenv_array->nelts; ++i) {
apr_table_set(merged_config->default_init_env,
locenv_entry[i].key, locenv_entry[i].val);
}
}
if (baseenv_array != NULL) {
const apr_table_entry_t *baseenv_entry =
(apr_table_entry_t *) baseenv_array->elts;
for (i = 0; i < baseenv_array->nelts; ++i) {
if (apr_table_get
(merged_config->default_init_env,
baseenv_entry[i].key))
continue;
apr_table_set(merged_config->default_init_env,
baseenv_entry[i].key, baseenv_entry[i].val);
}
}
}
/* Merge pass headers */
if (local->pass_headers != NULL || base->pass_headers != NULL) {
merged_config->pass_headers =
apr_array_make(p, 10, sizeof(const char *));
if (base->pass_headers != NULL)
apr_array_cat(merged_config->pass_headers, base->pass_headers);
if (local->pass_headers != NULL)
apr_array_cat(merged_config->pass_headers,
local->pass_headers);
}
// Merge the other configurations
merged_config->ipc_comm_timeout = base->ipc_comm_timeout;
merged_config->ipc_comm_timeout = local->ipc_comm_timeout;
merged_config->ipc_connect_timeout = base->ipc_connect_timeout;
merged_config->ipc_connect_timeout = local->ipc_connect_timeout;
merged_config->busy_timeout = base->busy_timeout;
merged_config->busy_timeout = local->busy_timeout;
return merged_config;
}
void *create_fcgid_dir_config(apr_pool_t * p, char *dummy)
{
fcgid_dir_conf *config = apr_pcalloc(p, sizeof(fcgid_dir_conf));
config->wrapper_info_hash = apr_hash_make(p);
config->authenticator_info = NULL;
config->authenticator_authoritative = 1;
config->authorizer_info = NULL;
config->authorizer_authoritative = 1;
config->access_info = NULL;
config->access_authoritative = 1;
return (void *) config;
}
const char *set_idle_timeout(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->idle_timeout = atol(arg);
return NULL;
}
int get_idle_timeout(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->idle_timeout : DEFAULT_IDLE_TIMEOUT;
}
const char *set_idle_scan_interval(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->idle_scan_interval = atol(arg);
return NULL;
}
int get_idle_scan_interval(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->idle_scan_interval : DEFAULT_IDLE_TIMEOUT;
}
const char *set_busy_timeout(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->busy_timeout = atol(arg);
return NULL;
}
int get_busy_timeout(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->busy_timeout : DEFAULT_BUSY_TIMEOUT;
}
const char *set_busy_scan_interval(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->busy_scan_interval = atol(arg);
return NULL;
}
int get_busy_scan_interval(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
busy_scan_interval : DEFAULT_BUSY_SCAN_INTERVAL;
}
const char *set_proc_lifetime(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->proc_lifetime = atol(arg);
return NULL;
}
int get_proc_lifetime(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->proc_lifetime : DEFAULT_PROC_LIFETIME;
}
const char *set_error_scan_interval(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->error_scan_interval = atol(arg);
return NULL;
}
int get_error_scan_interval(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
error_scan_interval : DEFAULT_ERROR_SCAN_INTERVAL;
}
const char *set_zombie_scan_interval(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->zombie_scan_interval = atol(arg);
return NULL;
}
int get_zombie_scan_interval(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
zombie_scan_interval : DEFAULT_ZOMBIE_SCAN_INTERVAL;
}
const char *set_socketpath(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->sockname_prefix = ap_server_root_relative(cmd->pool, arg);
if (!config->sockname_prefix)
return "Invalid socket path";
return NULL;
}
const char *get_socketpath(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config->sockname_prefix;
}
const char *set_shmpath(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->shmname_path = ap_server_root_relative(cmd->pool, arg);
if (!config->shmname_path)
return "Invalid shmname path";
return NULL;
}
const char *get_shmpath(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config->shmname_path;
}
const char *set_spawnscore_uplimit(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->spawnscore_uplimit = atol(arg);
return NULL;
}
int get_spawnscore_uplimit(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
spawnscore_uplimit : DEFAULT_SPAWNSOCRE_UPLIMIT;
}
const char *set_max_request_len(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->max_request_len = atol(arg);
return NULL;
}
int get_max_request_len(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->max_request_len : DEFAULT_MAX_REQUEST_LEN;
}
const char *set_max_mem_request_len(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->max_mem_request_len = atol(arg);
return NULL;
}
int get_max_mem_request_len(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
max_mem_request_len : DEFAULT_MAX_MEM_REQUEST_LEN;
}
const char *set_spawn_score(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->spawn_score = atol(arg);
return NULL;
}
int get_spawn_score(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->spawn_score : DEFAULT_SPAWN_SCORE;
}
const char *set_time_score(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->time_score = atol(arg);
return NULL;
}
int get_time_score(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->time_score : DEFAULT_TIME_SCORE;
}
const char *set_termination_score(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->termination_score = atol(arg);
return NULL;
}
int get_termination_score(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->termination_score : DEFAULT_TERMINATION_SCORE;
}
const char *set_max_process(cmd_parms * cmd, void *dummy, const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->max_process_count = atol(arg);
return NULL;
}
int get_max_process(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->max_process_count : DEFAULT_MAX_PROCESS_COUNT;
}
const char *set_output_buffersize(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->output_buffersize = atol(arg);
return NULL;
}
int get_output_buffersize(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->output_buffersize : DEFAULT_OUTPUT_BUFFERSIZE;
}
const char *set_max_class_process(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->max_class_process_count = atol(arg);
return NULL;
}
int get_max_class_process(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
max_class_process_count : DEFAULT_MAX_CLASS_PROCESS_COUNT;
}
const char *set_min_class_process(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->min_class_process_count = atol(arg);
return NULL;
}
int get_min_class_process(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
min_class_process_count : DEFAULT_MIN_CLASS_PROCESS_COUNT;
}
const char *set_php_fix_pathinfo_enable(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->php_fix_pathinfo_enable = atol(arg);
return NULL;
}
const char *set_max_requests_per_process(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->max_requests_per_process = atol(arg);
return NULL;
}
int get_max_requests_per_process(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
max_requests_per_process : DEFAULT_MAX_REQUESTS_PER_PROCESS;
}
int get_php_fix_pathinfo_enable(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->php_fix_pathinfo_enable : 0;
}
const char *set_ipc_connect_timeout(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->ipc_connect_timeout = atol(arg);
return NULL;
}
int get_ipc_connect_timeout(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->
ipc_connect_timeout : DEFAULT_IPC_CONNECT_TIMEOUT;
}
const char *set_ipc_comm_timeout(cmd_parms * cmd, void *dummy,
const char *arg)
{
server_rec *s = cmd->server;
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
config->ipc_comm_timeout = atol(arg);
return NULL;
}
int get_ipc_comm_timeout(server_rec * s)
{
fcgid_server_conf *config =
ap_get_module_config(s->module_config, &fcgid_module);
return config ? config->ipc_comm_timeout : DEFAULT_IPC_COMM_TIMEOUT;
}
const char *add_default_env_vars(cmd_parms * cmd, void *dummy,
const char *name, const char *value)
{
fcgid_server_conf *config =
ap_get_module_config(cmd->server->module_config, &fcgid_module);;
if (config->default_init_env == NULL)
config->default_init_env = apr_table_make(cmd->pool, 20);
apr_table_set(config->default_init_env, name, value ? value : "");
return NULL;
}
apr_table_t *get_default_env_vars(request_rec * r)
{
fcgid_server_conf *config =
ap_get_module_config(r->server->module_config, &fcgid_module);
return config->default_init_env;
}
const char *add_pass_headers(cmd_parms * cmd, void *dummy,
const char *names)
{
const char **header;
fcgid_server_conf *config =
ap_get_module_config(cmd->server->module_config, &fcgid_module);
if (config->pass_headers == NULL)
config->pass_headers =
apr_array_make(cmd->pool, 10, sizeof(const char *));
header = (const char **) apr_array_push(config->pass_headers);
*header = ap_getword_conf(cmd->pool, &names);
return header ? NULL : "Invalid PassHeaders";
}
apr_array_header_t *get_pass_headers(request_rec * r)
{
fcgid_server_conf *config =
ap_get_module_config(r->server->module_config, &fcgid_module);
return config->pass_headers;
}
const char *set_authenticator_info(cmd_parms * cmd, void *config,
const char *authenticator)
{
apr_status_t rv;
apr_finfo_t finfo;
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
/* Is the wrapper exist? */
if ((rv = apr_stat(&finfo, authenticator, APR_FINFO_NORM,
cmd->temp_pool)) != APR_SUCCESS) {
return apr_psprintf(cmd->pool,
"can't get authenticator file info: %s, errno: %d",
authenticator, apr_get_os_error());
}
/* Create the wrapper node */
dirconfig->authenticator_info =
apr_pcalloc(cmd->server->process->pconf,
sizeof(*dirconfig->authenticator_info));
if (!dirconfig->authenticator_info)
return "Can't alloc memory for authenticator_info";
strncpy(dirconfig->authenticator_info->path, authenticator,
_POSIX_PATH_MAX - 1);
dirconfig->authenticator_info->path[_POSIX_PATH_MAX - 1] = '\0';
dirconfig->authenticator_info->inode = finfo.inode;
dirconfig->authenticator_info->deviceid = finfo.device;
dirconfig->authenticator_info->share_group_id = (apr_size_t) - 1;
return NULL;
}
const char *set_authenticator_authoritative(cmd_parms * cmd,
void *config, int arg)
{
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
dirconfig->authenticator_authoritative = arg;
return NULL;
}
auth_conf *get_authenticator_info(request_rec * r, int *authoritative)
{
fcgid_dir_conf *config =
ap_get_module_config(r->per_dir_config, &fcgid_module);
if (config != NULL && config->authenticator_info != NULL) {
*authoritative = config->authenticator_authoritative;
return config->authenticator_info;
}
return NULL;
}
const char *set_authorizer_info(cmd_parms * cmd, void *config,
const char *authorizer)
{
apr_status_t rv;
apr_finfo_t finfo;
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
/* Is the wrapper exist? */
if ((rv = apr_stat(&finfo, authorizer, APR_FINFO_NORM,
cmd->temp_pool)) != APR_SUCCESS) {
return apr_psprintf(cmd->pool,
"can't get authorizer file info: %s, errno: %d",
authorizer, apr_get_os_error());
}
/* Create the wrapper node */
dirconfig->authorizer_info =
apr_pcalloc(cmd->server->process->pconf,
sizeof(*dirconfig->authorizer_info));
if (!dirconfig->authorizer_info)
return "Can't alloc memory for authorizer";
strncpy(dirconfig->authorizer_info->path, authorizer,
_POSIX_PATH_MAX - 1);
dirconfig->authorizer_info->path[_POSIX_PATH_MAX - 1] = '\0';
dirconfig->authorizer_info->inode = finfo.inode;
dirconfig->authorizer_info->deviceid = finfo.device;
dirconfig->authorizer_info->share_group_id = (apr_size_t) - 1;
return NULL;
}
const char *set_authorizer_authoritative(cmd_parms * cmd,
void *config, int arg)
{
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
dirconfig->authorizer_authoritative = arg;
return NULL;
}
auth_conf *get_authorizer_info(request_rec * r, int *authoritative)
{
fcgid_dir_conf *config =
ap_get_module_config(r->per_dir_config, &fcgid_module);
if (config != NULL && config->authorizer_info != NULL) {
*authoritative = config->authorizer_authoritative;
return config->authorizer_info;
}
return NULL;
}
const char *set_access_info(cmd_parms * cmd, void *config,
const char *access)
{
apr_status_t rv;
apr_finfo_t finfo;
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
/* Is the wrapper exist? */
if ((rv = apr_stat(&finfo, access, APR_FINFO_NORM,
cmd->temp_pool)) != APR_SUCCESS) {
return apr_psprintf(cmd->pool,
"can't get authorizer file info: %s, errno: %d",
access, apr_get_os_error());
}
/* Create the wrapper node */
dirconfig->access_info =
apr_pcalloc(cmd->server->process->pconf,
sizeof(*dirconfig->access_info));
if (!dirconfig->access_info)
return "Can't alloc memory for access";
strncpy(dirconfig->access_info->path, access, _POSIX_PATH_MAX - 1);
dirconfig->access_info->path[_POSIX_PATH_MAX - 1] = '\0';
dirconfig->access_info->inode = finfo.inode;
dirconfig->access_info->deviceid = finfo.device;
dirconfig->access_info->share_group_id = (apr_size_t) - 1;
return NULL;
}
const char *set_access_authoritative(cmd_parms * cmd,
void *config, int arg)
{
fcgid_dir_conf *dirconfig = (fcgid_dir_conf *) config;
dirconfig->access_authoritative = arg;
return NULL;
}
auth_conf *get_access_info(request_rec * r, int *authoritative)
{
fcgid_dir_conf *config =
ap_get_module_config(r->per_dir_config, &fcgid_module);
if (config != NULL && config->access_info != NULL) {
*authoritative = config->access_authoritative;
return config->access_info;
}
return NULL;
}
typedef struct {
apr_hash_t *wrapper_id_hash;
apr_size_t cur_id;
} wrapper_id_info;
const char *set_wrapper_config(cmd_parms * cmd, void *dirconfig,
const char *wrapperpath,
const char *extension)
{
const char *path, *tmp;
apr_status_t rv;
apr_finfo_t finfo;
const char *userdata_key = "fcgid_wrapper_id";
wrapper_id_info *id_info;
apr_size_t *wrapper_id;
fcgid_wrapper_conf *wrapper = NULL;
fcgid_dir_conf *config = (fcgid_dir_conf *) dirconfig;
/* Sanity check */
if (wrapperpath == NULL || extension == NULL
|| *extension != '.' || *(extension + 1) == '\0'
|| strchr(extension, '/') || strchr(extension, '\\'))
return "Invalid wrapper file extension";
/* Get wrapper_id base on wrapperpath */
apr_pool_userdata_get((void *) &id_info, userdata_key,
cmd->server->process->pool);
if (!id_info) {
id_info =
apr_pcalloc(cmd->server->process->pool, sizeof(*id_info));
id_info->wrapper_id_hash =
apr_hash_make(cmd->server->process->pool);
apr_pool_userdata_set((const void *) id_info, userdata_key,
apr_pool_cleanup_null,
cmd->server->process->pool);
}
if ((wrapper_id =
apr_hash_get(id_info->wrapper_id_hash, wrapperpath,
strlen(wrapperpath))) == NULL) {
wrapper_id =
apr_pcalloc(cmd->server->process->pool, sizeof(*wrapper_id));
*wrapper_id = id_info->cur_id++;
apr_hash_set(id_info->wrapper_id_hash, wrapperpath,
strlen(wrapperpath), wrapper_id);
}
wrapper = apr_pcalloc(cmd->server->process->pconf, sizeof(*wrapper));
if (!wrapper)
return "Can't alloc memory for wrapper";
/* Get wrapper path */
tmp = wrapperpath;
path = ap_getword_white(cmd->temp_pool, &tmp);
if (path == NULL || *path == '\0')
return "Invalid wrapper config";
/* Is the wrapper exist? */
if ((rv = apr_stat(&finfo, path, APR_FINFO_NORM,
cmd->temp_pool)) != APR_SUCCESS) {
return apr_psprintf(cmd->pool,
"can't get fastcgi file info: %s(%s), errno: %d",
wrapperpath, path, apr_get_os_error());
}
strncpy(wrapper->args, wrapperpath, _POSIX_PATH_MAX - 1);
wrapper->args[_POSIX_PATH_MAX - 1] = '\0';
wrapper->inode = finfo.inode;
wrapper->deviceid = finfo.device;
wrapper->share_group_id = *wrapper_id;
*wrapper_id++;
/* Add the node now */
apr_hash_set(config->wrapper_info_hash, extension, strlen(extension),
wrapper);
return NULL;
}
fcgid_wrapper_conf *get_wrapper_info(const char *cgipath, request_rec * r)
{
char *extension;
fcgid_wrapper_conf *wrapper;
fcgid_dir_conf *config =
ap_get_module_config(r->per_dir_config, &fcgid_module);
/* Get file name extension */
extension = ap_strrchr_c(cgipath, '.');
if (extension == NULL)
return NULL;
/* Search file name extension in per_dir_config */
if (config
&& (wrapper =
apr_hash_get(config->wrapper_info_hash, extension,
strlen(extension))))
return wrapper;
return NULL;
}