⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -