📄 core.c
字号:
d->opts_add |= opt; d->opts_remove &= ~opt; d->opts |= opt; } else { d->opts |= opt; } } return NULL;}/* * Note what data should be used when forming file ETag values. * It would be nicer to do this as an ITERATE, but then we couldn't * remember the +/- state properly. */static const char *set_etag_bits(cmd_parms *cmd, void *mconfig, const char *args_p){ core_dir_config *cfg; etag_components_t bit; char action; char *token; const char *args; int valid; int first; int explicit; cfg = (core_dir_config *)mconfig; args = args_p; first = 1; explicit = 0; while (args[0] != '\0') { action = '*'; bit = ETAG_UNSET; valid = 1; token = ap_getword_conf(cmd->pool, &args); if ((*token == '+') || (*token == '-')) { action = *token; token++; } else { /* * The occurrence of an absolute setting wipes * out any previous relative ones. The first such * occurrence forgets any inherited ones, too. */ if (first) { cfg->etag_bits = ETAG_UNSET; cfg->etag_add = ETAG_UNSET; cfg->etag_remove = ETAG_UNSET; first = 0; } } if (strcasecmp(token, "None") == 0) { if (action != '*') { valid = 0; } else { cfg->etag_bits = bit = ETAG_NONE; explicit = 1; } } else if (strcasecmp(token, "All") == 0) { if (action != '*') { valid = 0; } else { explicit = 1; cfg->etag_bits = bit = ETAG_ALL; } } else if (strcasecmp(token, "Size") == 0) { bit = ETAG_SIZE; } else if ((strcasecmp(token, "LMTime") == 0) || (strcasecmp(token, "MTime") == 0) || (strcasecmp(token, "LastModified") == 0)) { bit = ETAG_MTIME; } else if (strcasecmp(token, "INode") == 0) { bit = ETAG_INODE; } else { return apr_pstrcat(cmd->pool, "Unknown keyword '", token, "' for ", cmd->cmd->name, " directive", NULL); } if (! valid) { return apr_pstrcat(cmd->pool, cmd->cmd->name, " keyword '", token, "' cannot be used with '+' or '-'", NULL); } if (action == '+') { /* * Make sure it's in the 'add' list and absent from the * 'subtract' list. */ cfg->etag_add |= bit; cfg->etag_remove &= (~ bit); } else if (action == '-') { cfg->etag_remove |= bit; cfg->etag_add &= (~ bit); } else { /* * Non-relative values wipe out any + or - values * accumulated so far. */ cfg->etag_bits |= bit; cfg->etag_add = ETAG_UNSET; cfg->etag_remove = ETAG_UNSET; explicit = 1; } } /* * Any setting at all will clear the 'None' and 'Unset' bits. */ if (cfg->etag_add != ETAG_UNSET) { cfg->etag_add &= (~ ETAG_UNSET); } if (cfg->etag_remove != ETAG_UNSET) { cfg->etag_remove &= (~ ETAG_UNSET); } if (explicit) { cfg->etag_bits &= (~ ETAG_UNSET); if ((cfg->etag_bits & ETAG_NONE) != ETAG_NONE) { cfg->etag_bits &= (~ ETAG_NONE); } } return NULL;}static const char *set_enable_mmap(cmd_parms *cmd, void *d_, const char *arg){ core_dir_config *d = d_; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); if (err != NULL) { return err; } if (strcasecmp(arg, "on") == 0) { d->enable_mmap = ENABLE_MMAP_ON; } else if (strcasecmp(arg, "off") == 0) { d->enable_mmap = ENABLE_MMAP_OFF; } else { return "parameter must be 'on' or 'off'"; } return NULL;}static const char *set_enable_sendfile(cmd_parms *cmd, void *d_, const char *arg){ core_dir_config *d = d_; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); if (err != NULL) { return err; } if (strcasecmp(arg, "on") == 0) { d->enable_sendfile = ENABLE_SENDFILE_ON; } else if (strcasecmp(arg, "off") == 0) { d->enable_sendfile = ENABLE_SENDFILE_OFF; } else { return "parameter must be 'on' or 'off'"; } return NULL;}static const char *satisfy(cmd_parms *cmd, void *c_, const char *arg){ core_dir_config *c = c_; int satisfy = SATISFY_NOSPEC; int i; if (!strcasecmp(arg, "all")) { satisfy = SATISFY_ALL; } else if (!strcasecmp(arg, "any")) { satisfy = SATISFY_ANY; } else { return "Satisfy either 'any' or 'all'."; } for (i = 0; i < METHODS; ++i) { if (cmd->limited & (AP_METHOD_BIT << i)) { c->satisfy[i] = satisfy; } } return NULL;}static const char *require(cmd_parms *cmd, void *c_, const char *arg){ require_line *r; core_dir_config *c = c_; if (!c->ap_requires) { c->ap_requires = apr_array_make(cmd->pool, 2, sizeof(require_line)); } r = (require_line *)apr_array_push(c->ap_requires); r->requirement = apr_pstrdup(cmd->pool, arg); r->method_mask = cmd->limited; return NULL;}AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg){ const char *limited_methods = ap_getword(cmd->pool, &arg, '>'); void *tog = cmd->cmd->cmd_data; apr_int64_t limited = 0; const char *errmsg; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); if (err != NULL) { return err; } while (limited_methods[0]) { char *method = ap_getword_conf(cmd->pool, &limited_methods); int methnum; /* check for builtin or module registered method number */ methnum = ap_method_number_of(method); if (methnum == M_TRACE && !tog) { return "TRACE cannot be controlled by <Limit>"; } else if (methnum == M_INVALID) { /* method has not been registered yet, but resorce restriction * is always checked before method handling, so register it. */ methnum = ap_method_register(cmd->pool, method); } limited |= (AP_METHOD_BIT << methnum); } /* Killing two features with one function, * if (tog == NULL) <Limit>, else <LimitExcept> */ cmd->limited = tog ? ~limited : limited; errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context); cmd->limited = -1; return errmsg;}/* XXX: Bogus - need to do this differently (at least OS2/Netware suffer * the same problem!!! * We use this in <DirectoryMatch> and <FilesMatch>, to ensure that * people don't get bitten by wrong-cased regex matches */#ifdef WIN32#define USE_ICASE REG_ICASE#else#define USE_ICASE 0#endif/* * Report a missing-'>' syntax error. */static char *unclosed_directive(cmd_parms *cmd){ return apr_pstrcat(cmd->pool, cmd->cmd->name, "> directive missing closing '>'", NULL);}static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg){ const char *errmsg; const char *endp = ap_strrchr_c(arg, '>'); int old_overrides = cmd->override; char *old_path = cmd->path; core_dir_config *conf; ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool); regex_t *r = NULL; const command_rec *thiscmd = cmd->cmd; const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); if (err != NULL) { return err; } if (endp == NULL) { return unclosed_directive(cmd); } arg = apr_pstrndup(cmd->pool, arg, endp - arg); if (!arg) { if (thiscmd->cmd_data) return "<DirectoryMatch > block must specify a path"; else return "<Directory > block must specify a path"; } cmd->path = ap_getword_conf(cmd->pool, &arg); cmd->override = OR_ALL|ACCESS_CONF; if (!strcmp(cmd->path, "~")) { cmd->path = ap_getword_conf(cmd->pool, &arg); if (!cmd->path) return "<Directory ~ > block must specify a path"; r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); if (!r) { return "Regex could not be compiled"; } } else if (thiscmd->cmd_data) { /* <DirectoryMatch> */ r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED|USE_ICASE); if (!r) { return "Regex could not be compiled"; } } else if (!strcmp(cmd->path, "/") == 0) { char *newpath; /* * Ensure that the pathname is canonical, and append the trailing / */ apr_status_t rv = apr_filepath_merge(&newpath, NULL, cmd->path, APR_FILEPATH_TRUENAME, cmd->pool); if (rv != APR_SUCCESS && rv != APR_EPATHWILD) { return apr_pstrcat(cmd->pool, "<Directory \"", cmd->path, "\"> path is invalid.", NULL); } cmd->path = newpath; if (cmd->path[strlen(cmd->path) - 1] != '/') cmd->path = apr_pstrcat(cmd->pool, cmd->path, "/", NULL); } /* initialize our config and fetch it */ conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path, &core_module, cmd->pool); errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf); if (errmsg != NULL) return errmsg; conf->r = r; conf->d = cmd->path; conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0); /* Make this explicit - the "/" root has 0 elements, that is, we * will always merge it, and it will always sort and merge first. * All others are sorted and tested by the number of slashes. */ if (strcmp(conf->d, "/") == 0) conf->d_components = 0; else conf->d_components = ap_count_dirs(conf->d); ap_add_per_dir_conf(cmd->server, new_dir_conf); if (*arg != '\0') { return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, "> arguments not (yet) supported.", NULL); } cmd->path = old_path; cmd->override = old_overrides; return NULL;}static const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg){ const char *errmsg; const char *endp = ap_strrchr_c(arg, '>'); int old_overrides = cmd->override; char *old_path = cmd->path; core_dir_config *conf; regex_t *r = NULL; const command_rec *thiscmd = cmd->cmd; ap_conf_vector_t *new_url_conf = ap_create_per_dir_config(cmd->pool); const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); if (err != NULL) { return err; } if (endp == NULL) { return unclosed_directive(cmd); } arg = apr_pstrndup(cmd->pool, arg, endp - arg); cmd->path = ap_getword_conf(cmd->pool, &arg); cmd->override = OR_ALL|ACCESS_CONF; if (thiscmd->cmd_data) { /* <LocationMatch> */ r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); if (!r) { return "Regex could not be compiled"; } } else if (!strcmp(cmd->path, "~")) { cmd->path = ap_getword_conf(cmd->pool, &arg); r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); if (!r) { return "Regex could not be compiled"; } } /* initialize our config and fetch it */ conf = ap_set_config_vectors(cmd->server, new_url_conf, cmd->path, &core_module, cmd->pool); errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_url_conf); if (errmsg != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -