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

📄 mod_include.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 "apr.h"#include "apr_strings.h"#include "apr_thread_proc.h"#include "apr_hash.h"#include "apr_user.h"#include "apr_lib.h"#include "apr_optional.h"#define APR_WANT_STRFUNC#define APR_WANT_MEMFUNC#include "apr_want.h"#include "ap_config.h"#include "util_filter.h"#include "httpd.h"#include "http_config.h"#include "http_core.h"#include "http_request.h"#include "http_core.h"#include "http_protocol.h"#include "http_log.h"#include "http_main.h"#include "util_script.h"#include "http_core.h"#include "mod_include.h"/* helper for Latin1 <-> entity encoding */#if APR_CHARSET_EBCDIC#include "util_ebcdic.h"#define RAW_ASCII_CHAR(ch)  apr_xlate_conv_byte(ap_hdrs_from_ascii, \                                                (unsigned char)ch)#else /* APR_CHARSET_EBCDIC */#define RAW_ASCII_CHAR(ch)  (ch)#endif /* !APR_CHARSET_EBCDIC *//* * +-------------------------------------------------------+ * |                                                       | * |                 Types and Structures * |                                                       | * +-------------------------------------------------------+ *//* sll used for string expansion */typedef struct result_item {    struct result_item *next;    apr_size_t len;    const char *string;} result_item_t;/* conditional expression parser stuff */typedef enum {    TOKEN_STRING,    TOKEN_RE,    TOKEN_AND,    TOKEN_OR,    TOKEN_NOT,    TOKEN_EQ,    TOKEN_NE,    TOKEN_RBRACE,    TOKEN_LBRACE,    TOKEN_GROUP,    TOKEN_GE,    TOKEN_LE,    TOKEN_GT,    TOKEN_LT,    TOKEN_ACCESS} token_type_t;typedef struct {    token_type_t  type;    const char   *value;#ifdef DEBUG_INCLUDE    const char   *s;#endif} token_t;typedef struct parse_node {    struct parse_node *parent;    struct parse_node *left;    struct parse_node *right;    token_t token;    int value;    int done;#ifdef DEBUG_INCLUDE    int dump_done;#endif} parse_node_t;typedef enum {    XBITHACK_OFF,    XBITHACK_ON,    XBITHACK_FULL} xbithack_t;typedef struct {    const char *default_error_msg;    const char *default_time_fmt;    const char *undefined_echo;    xbithack_t  xbithack;    const int accessenable;} include_dir_config;typedef struct {    const char *default_start_tag;    const char *default_end_tag;} include_server_config;/* main parser states */typedef enum {    PARSE_PRE_HEAD,    PARSE_HEAD,    PARSE_DIRECTIVE,    PARSE_DIRECTIVE_POSTNAME,    PARSE_DIRECTIVE_TAIL,    PARSE_DIRECTIVE_POSTTAIL,    PARSE_PRE_ARG,    PARSE_ARG,    PARSE_ARG_NAME,    PARSE_ARG_POSTNAME,    PARSE_ARG_EQ,    PARSE_ARG_PREVAL,    PARSE_ARG_VAL,    PARSE_ARG_VAL_ESC,    PARSE_ARG_POSTVAL,    PARSE_TAIL,    PARSE_TAIL_SEQ,    PARSE_EXECUTE} parse_state_t;typedef struct arg_item {    struct arg_item  *next;    char             *name;    apr_size_t        name_len;    char             *value;    apr_size_t        value_len;} arg_item_t;typedef struct {    const char *source;    const char *rexp;    apr_size_t  nsub;    ap_regmatch_t match[AP_MAX_REG_MATCH];} backref_t;typedef struct {    unsigned int T[256];    unsigned int x;    apr_size_t pattern_len;} bndm_t;struct ssi_internal_ctx {    parse_state_t state;    int           seen_eos;    int           error;    char          quote;         /* quote character value (or \0) */    apr_size_t    parse_pos;     /* parse position of partial matches */    apr_size_t    bytes_read;    apr_bucket_brigade *tmp_bb;    request_rec  *r;    const char   *start_seq;    bndm_t       *start_seq_pat;    const char   *end_seq;    apr_size_t    end_seq_len;    char         *directive;     /* name of the current directive */    apr_size_t    directive_len; /* length of the current directive name */    arg_item_t   *current_arg;   /* currently parsed argument */    arg_item_t   *argv;          /* all arguments */    backref_t    *re;            /* NULL if there wasn't a regex yet */    const char   *undefined_echo;    apr_size_t    undefined_echo_len;    int         accessenable;    /* is using the access tests allowed? */#ifdef DEBUG_INCLUDE    struct {        ap_filter_t *f;        apr_bucket_brigade *bb;    } debug;#endif};/* * +-------------------------------------------------------+ * |                                                       | * |                  Debugging Utilities * |                                                       | * +-------------------------------------------------------+ */#ifdef DEBUG_INCLUDE#define TYPE_TOKEN(token, ttype) do { \    (token)->type = ttype;            \    (token)->s = #ttype;              \} while(0)#define CREATE_NODE(ctx, name) do {                       \    (name) = apr_palloc((ctx)->dpool, sizeof(*(name)));   \    (name)->parent = (name)->left = (name)->right = NULL; \    (name)->done = 0;                                     \    (name)->dump_done = 0;                                \} while(0)static void debug_printf(include_ctx_t *ctx, const char *fmt, ...){    va_list ap;    char *debug__str;    va_start(ap, fmt);    debug__str = apr_pvsprintf(ctx->pool, fmt, ap);    va_end(ap);    APR_BRIGADE_INSERT_TAIL(ctx->intern->debug.bb, apr_bucket_pool_create(                            debug__str, strlen(debug__str), ctx->pool,                            ctx->intern->debug.f->c->bucket_alloc));}#define DUMP__CHILD(ctx, is, node, child) if (1) {                           \    parse_node_t *d__c = node->child;                                        \    if (d__c) {                                                              \        if (!d__c->dump_done) {                                              \            if (d__c->parent != node) {                                      \                debug_printf(ctx, "!!! Parse tree is not consistent !!!\n"); \                if (!d__c->parent) {                                         \                    debug_printf(ctx, "Parent of " #child " child node is "  \                                 "NULL.\n");                                 \                }                                                            \                else {                                                       \                    debug_printf(ctx, "Parent of " #child " child node "     \                                 "points to another node (of type %s)!\n",   \                                 d__c->parent->token.s);                     \                }                                                            \                return;                                                      \            }                                                                \            node = d__c;                                                     \            continue;                                                        \        }                                                                    \    }                                                                        \    else {                                                                   \        debug_printf(ctx, "%s(missing)\n", is);                              \    }                                                                        \}static void debug_dump_tree(include_ctx_t *ctx, parse_node_t *root){    parse_node_t *current;    char *is;    if (!root) {        debug_printf(ctx, "     -- Parse Tree empty --\n\n");        return;    }    debug_printf(ctx, "     ----- Parse Tree -----\n");    current = root;    is = "     ";    while (current) {        switch (current->token.type) {        case TOKEN_STRING:        case TOKEN_RE:            debug_printf(ctx, "%s%s (%s)\n", is, current->token.s,                         current->token.value);            current->dump_done = 1;            current = current->parent;            continue;        case TOKEN_NOT:        case TOKEN_GROUP:        case TOKEN_RBRACE:        case TOKEN_LBRACE:            if (!current->dump_done) {                debug_printf(ctx, "%s%s\n", is, current->token.s);                is = apr_pstrcat(ctx->dpool, is, "    ", NULL);                current->dump_done = 1;            }            DUMP__CHILD(ctx, is, current, right)            if (!current->right || current->right->dump_done) {                is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);                if (current->right) current->right->dump_done = 0;                current = current->parent;            }            continue;        default:            if (!current->dump_done) {                debug_printf(ctx, "%s%s\n", is, current->token.s);                is = apr_pstrcat(ctx->dpool, is, "    ", NULL);                current->dump_done = 1;            }            DUMP__CHILD(ctx, is, current, left)            DUMP__CHILD(ctx, is, current, right)            if ((!current->left || current->left->dump_done) &&                (!current->right || current->right->dump_done)) {                is = apr_pstrmemdup(ctx->dpool, is, strlen(is) - 4);                if (current->left) current->left->dump_done = 0;                if (current->right) current->right->dump_done = 0;                current = current->parent;            }            continue;        }    }    /* it is possible to call this function within the parser loop, to see     * how the tree is built. That way, we must cleanup after us to dump     * always the whole tree     */    root->dump_done = 0;    if (root->left) root->left->dump_done = 0;    if (root->right) root->right->dump_done = 0;    debug_printf(ctx, "     --- End Parse Tree ---\n\n");    return;}#define DEBUG_INIT(ctx, filter, brigade) do { \    (ctx)->intern->debug.f = filter;          \    (ctx)->intern->debug.bb = brigade;        \} while(0)#define DEBUG_PRINTF(arg) debug_printf arg#define DEBUG_DUMP_TOKEN(ctx, token) do {                                     \    token_t *d__t = (token);                                                  \                                                                              \    if (d__t->type == TOKEN_STRING || d__t->type == TOKEN_RE) {               \        DEBUG_PRINTF(((ctx), "     Found: %s (%s)\n", d__t->s, d__t->value)); \    }                                                                         \    else {                                                                    \        DEBUG_PRINTF((ctx, "     Found: %s\n", d__t->s));                     \    }                                                                         \} while(0)#define DEBUG_DUMP_EVAL(ctx, node) do {                                       \    char c = '"';                                                             \    switch ((node)->token.type) {                                             \    case TOKEN_STRING:                                                        \        debug_printf((ctx), "     Evaluate: %s (%s) -> %c\n", (node)->token.s,\                     (node)->token.value, ((node)->value) ? '1':'0');         \        break;                                                                \    case TOKEN_AND:                                                           \    case TOKEN_OR:                                                            \        debug_printf((ctx), "     Evaluate: %s (Left: %s; Right: %s) -> %c\n",\                     (node)->token.s,                                         \                     (((node)->left->done) ? ((node)->left->value ?"1":"0")   \                                          : "short circuited"),               \                     (((node)->right->done) ? ((node)->right->value?"1":"0")  \                                          : "short circuited"),               \                     (node)->value ? '1' : '0');                              \        break;                                                                \    case TOKEN_EQ:                                                            \    case TOKEN_NE:                                                            \    case TOKEN_GT:                                                            \    case TOKEN_GE:                                                            \    case TOKEN_LT:                                                            \    case TOKEN_LE:                                                            \        if ((node)->right->token.type == TOKEN_RE) c = '/';                   \        debug_printf((ctx), "     Compare:  %s (\"%s\" with %c%s%c) -> %c\n", \                     (node)->token.s,                                         \                     (node)->left->token.value,                               \                     c, (node)->right->token.value, c,                        \                     (node)->value ? '1' : '0');                              \        break;                                                                \    default:                                                                  \        debug_printf((ctx), "     Evaluate: %s -> %c\n", (node)->token.s,     \                     (node)->value ? '1' : '0');                              \        break;                                                                \    }                                                                         \} while(0)#define DEBUG_DUMP_UNMATCHED(ctx, unmatched) do {                        \    if (unmatched) {                                                     \        DEBUG_PRINTF(((ctx), "     Unmatched %c\n", (char)(unmatched))); \    }                                                                    \} while(0)#define DEBUG_DUMP_COND(ctx, text)                                 \    DEBUG_PRINTF(((ctx), "**** %s cond status=\"%c\"\n", (text),   \                  ((ctx)->flags & SSI_FLAG_COND_TRUE) ? '1' : '0'))#define DEBUG_DUMP_TREE(ctx, root) debug_dump_tree(ctx, root)#else /* DEBUG_INCLUDE */#define TYPE_TOKEN(token, ttype) (token)->type = ttype

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -