📄 core.c
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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 "apr.h"#include "apr_strings.h"#include "apr_lib.h"#include "apr_fnmatch.h"#include "apr_hash.h"#include "apr_thread_proc.h" /* for RLIMIT stuff */#include "apr_hooks.h"#define APR_WANT_IOVEC#define APR_WANT_STRFUNC#define APR_WANT_MEMFUNC#include "apr_want.h"#define CORE_PRIVATE#include "ap_config.h"#include "httpd.h"#include "http_config.h"#include "http_core.h"#include "http_protocol.h" /* For index_of_response(). Grump. */#include "http_request.h"#include "http_vhost.h"#include "http_main.h" /* For the default_handler below... */#include "http_log.h"#include "rfc1413.h"#include "util_md5.h"#include "http_connection.h"#include "apr_buckets.h"#include "util_filter.h"#include "util_ebcdic.h"#include "mpm.h"#include "mpm_common.h"#include "scoreboard.h"#include "mod_core.h"#include "mod_proxy.h"#include "ap_listen.h"/* LimitRequestBody handling */#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)/* LimitXMLRequestBody handling */#define AP_LIMIT_UNSET ((long) -1)#define AP_DEFAULT_LIMIT_XML_BODY ((size_t)1000000)#define AP_MIN_SENDFILE_BYTES (256)/* maximum include nesting level */#ifndef AP_MAX_INCLUDE_DEPTH#define AP_MAX_INCLUDE_DEPTH (128)#endifAPR_HOOK_STRUCT( APR_HOOK_LINK(get_mgmt_items))AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, (apr_pool_t *p, const char *val, apr_hash_t *ht), (p, val, ht), OK, DECLINED)/* Server core module... This module provides support for really basic * server operations, including options and commands which control the * operation of other modules. Consider this the bureaucracy module. * * The core module also defines handlers, etc., do handle just enough * to allow a server with the core module ONLY to actually serve documents * (though it slaps DefaultType on all of 'em); this was useful in testing, * but may not be worth preserving. * * This file could almost be mod_core.c, except for the stuff which affects * the http_conf_globals. *//* Handles for core filters */AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle;AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle;AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle;AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;/* magic pointer for ErrorDocument xxx "default" */static char errordocument_default;static void *create_core_dir_config(apr_pool_t *a, char *dir){ core_dir_config *conf; int i; conf = (core_dir_config *)apr_pcalloc(a, sizeof(core_dir_config)); /* conf->r and conf->d[_*] are initialized by dirsection() or left NULL */ conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL; conf->opts_add = conf->opts_remove = OPT_NONE; conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL; conf->content_md5 = 2; conf->accept_path_info = 3; conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */ conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); for (i = 0; i < METHODS; ++i) { conf->satisfy[i] = SATISFY_NOSPEC; }#ifdef RLIMIT_CPU conf->limit_cpu = NULL;#endif#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) conf->limit_mem = NULL;#endif#ifdef RLIMIT_NPROC conf->limit_nproc = NULL;#endif conf->limit_req_body = AP_LIMIT_REQ_BODY_UNSET; conf->limit_xml_body = AP_LIMIT_UNSET; conf->sec_file = apr_array_make(a, 2, sizeof(ap_conf_vector_t *)); conf->server_signature = srv_sig_unset; conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET; conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; /* Overriding all negotiation */ conf->mime_type = NULL; conf->handler = NULL; conf->output_filters = NULL; conf->input_filters = NULL; /* * Flag for use of inodes in ETags. */ conf->etag_bits = ETAG_UNSET; conf->etag_add = ETAG_UNSET; conf->etag_remove = ETAG_UNSET; conf->enable_mmap = ENABLE_MMAP_UNSET; conf->enable_sendfile = ENABLE_SENDFILE_UNSET; conf->allow_encoded_slashes = 0; return (void *)conf;}/* * Overlay one hash table of ct_output_filters onto another */static void *merge_ct_filters(apr_pool_t *p, const void *key, apr_ssize_t klen, const void *overlay_val, const void *base_val, const void *data){ ap_filter_rec_t *cur; const ap_filter_rec_t *overlay_info = (const ap_filter_rec_t *)overlay_val; const ap_filter_rec_t *base_info = (const ap_filter_rec_t *)base_val; cur = NULL; while (overlay_info) { ap_filter_rec_t *new; new = apr_pcalloc(p, sizeof(ap_filter_rec_t)); new->name = apr_pstrdup(p, overlay_info->name); new->next = cur; cur = new; overlay_info = overlay_info->next; } while (base_info) { ap_filter_rec_t *f; int found = 0; /* We can't have dups. */ f = cur; while (f) { if (!strcasecmp(base_info->name, f->name)) { found = 1; break; } f = f->next; } if (!found) { f = apr_pcalloc(p, sizeof(ap_filter_rec_t)); f->name = apr_pstrdup(p, base_info->name); f->next = cur; cur = f; } base_info = base_info->next; } return cur;}static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv){ core_dir_config *base = (core_dir_config *)basev; core_dir_config *new = (core_dir_config *)newv; core_dir_config *conf; int i; /* Create this conf by duplicating the base, replacing elements * (or creating copies for merging) where new-> values exist. */ conf = (core_dir_config *)apr_palloc(a, sizeof(core_dir_config)); memcpy(conf, base, sizeof(core_dir_config)); conf->d = new->d; conf->d_is_fnmatch = new->d_is_fnmatch; conf->d_components = new->d_components; conf->r = new->r; if (new->opts & OPT_UNSET) { /* there was no explicit setting of new->opts, so we merge * preserve the invariant (opts_add & opts_remove) == 0 */ conf->opts_add = (conf->opts_add & ~new->opts_remove) | new->opts_add; conf->opts_remove = (conf->opts_remove & ~new->opts_add) | new->opts_remove; conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add; if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) { conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES; } } else { /* otherwise we just copy, because an explicit opts setting * overrides all earlier +/- modifiers */ conf->opts = new->opts; conf->opts_add = new->opts_add; conf->opts_remove = new->opts_remove; } if (!(new->override & OR_UNSET)) { conf->override = new->override; } if (new->ap_default_type) { conf->ap_default_type = new->ap_default_type; } if (new->ap_auth_type) { conf->ap_auth_type = new->ap_auth_type; } if (new->ap_auth_name) { conf->ap_auth_name = new->ap_auth_name; } if (new->ap_requires) { conf->ap_requires = new->ap_requires; } if (conf->response_code_strings == NULL) { conf->response_code_strings = new->response_code_strings; } else if (new->response_code_strings != NULL) { /* If we merge, the merge-result must have it's own array */ conf->response_code_strings = apr_palloc(a, sizeof(*conf->response_code_strings) * RESPONSE_CODES); memcpy(conf->response_code_strings, base->response_code_strings, sizeof(*conf->response_code_strings) * RESPONSE_CODES); for (i = 0; i < RESPONSE_CODES; ++i) { if (new->response_code_strings[i] != NULL) { conf->response_code_strings[i] = new->response_code_strings[i]; } } } /* Otherwise we simply use the base->response_code_strings array */ if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET) { conf->hostname_lookups = new->hostname_lookups; } if ((new->do_rfc1413 & 2) == 0) { conf->do_rfc1413 = new->do_rfc1413; } if ((new->content_md5 & 2) == 0) { conf->content_md5 = new->content_md5; } if (new->accept_path_info != 3) { conf->accept_path_info = new->accept_path_info; } if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) { conf->use_canonical_name = new->use_canonical_name; }#ifdef RLIMIT_CPU if (new->limit_cpu) { conf->limit_cpu = new->limit_cpu; }#endif#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS) if (new->limit_mem) { conf->limit_mem = new->limit_mem; }#endif#ifdef RLIMIT_NPROC if (new->limit_nproc) { conf->limit_nproc = new->limit_nproc; }#endif if (new->limit_req_body != AP_LIMIT_REQ_BODY_UNSET) { conf->limit_req_body = new->limit_req_body; } if (new->limit_xml_body != AP_LIMIT_UNSET) conf->limit_xml_body = new->limit_xml_body; else conf->limit_xml_body = base->limit_xml_body; if (!conf->sec_file) { conf->sec_file = new->sec_file; } else if (new->sec_file) { /* If we merge, the merge-result must have it's own array */ conf->sec_file = apr_array_append(a, base->sec_file, new->sec_file); } /* Otherwise we simply use the base->sec_file array */ /* use a separate ->satisfy[] array either way */ conf->satisfy = apr_palloc(a, sizeof(*conf->satisfy) * METHODS); for (i = 0; i < METHODS; ++i) { if (new->satisfy[i] != SATISFY_NOSPEC) { conf->satisfy[i] = new->satisfy[i]; } else { conf->satisfy[i] = base->satisfy[i]; } } if (new->server_signature != srv_sig_unset) { conf->server_signature = new->server_signature; } if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) { conf->add_default_charset = new->add_default_charset; conf->add_default_charset_name = new->add_default_charset_name; } /* Overriding all negotiation */ if (new->mime_type) { conf->mime_type = new->mime_type; } if (new->handler) { conf->handler = new->handler; } if (new->output_filters) { conf->output_filters = new->output_filters; } if (new->input_filters) { conf->input_filters = new->input_filters; } if (conf->ct_output_filters && new->ct_output_filters) { conf->ct_output_filters = apr_hash_merge(a, new->ct_output_filters, conf->ct_output_filters, merge_ct_filters, NULL); } else if (new->ct_output_filters) { conf->ct_output_filters = apr_hash_copy(a, new->ct_output_filters); } else if (conf->ct_output_filters) { /* That memcpy above isn't enough. */ conf->ct_output_filters = apr_hash_copy(a, base->ct_output_filters); } /* * Now merge the setting of the FileETag directive. */ if (new->etag_bits == ETAG_UNSET) { conf->etag_add = (conf->etag_add & (~ new->etag_remove)) | new->etag_add; conf->etag_remove = (conf->opts_remove & (~ new->etag_add)) | new->etag_remove; conf->etag_bits = (conf->etag_bits & (~ conf->etag_remove)) | conf->etag_add; } else { conf->etag_bits = new->etag_bits; conf->etag_add = new->etag_add; conf->etag_remove = new->etag_remove; } if (conf->etag_bits != ETAG_NONE) { conf->etag_bits &= (~ ETAG_NONE); } if (new->enable_mmap != ENABLE_MMAP_UNSET) { conf->enable_mmap = new->enable_mmap; } if (new->enable_sendfile != ENABLE_SENDFILE_UNSET) { conf->enable_sendfile = new->enable_sendfile; } conf->allow_encoded_slashes = new->allow_encoded_slashes; return (void*)conf;}static void *create_core_server_config(apr_pool_t *a, server_rec *s){ core_server_config *conf; int is_virtual = s->is_virtual;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -