📄 mod_include.c
字号:
default: break; } break; case TOKEN_EQ: case TOKEN_NE: case TOKEN_GE: case TOKEN_GT: case TOKEN_LE: case TOKEN_LT: if (current->token.type == TOKEN_STRING) { current = current->parent; if (!current) { new->left = root; root->parent = new; current = root = new; continue; } switch (current->token.type) { case TOKEN_LBRACE: case TOKEN_AND: case TOKEN_OR: new->left = current->right; new->left->parent = new; new->parent = current; current = current->right = new; continue; default: break; } } break; case TOKEN_RBRACE: while (current && current->token.type != TOKEN_LBRACE) { current = current->parent; } if (current) { TYPE_TOKEN(¤t->token, TOKEN_GROUP); continue; } error = "Unmatched ')' in \"%s\" in file %s"; break; case TOKEN_NOT: case TOKEN_ACCESS: case TOKEN_LBRACE: switch (current->token.type) { case TOKEN_STRING: case TOKEN_RE: case TOKEN_RBRACE: case TOKEN_GROUP: break; default: current->right = new; new->parent = current; current = new; continue; } break; default: break; } ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr, r->filename); *was_error = 1; return 0; } DEBUG_DUMP_TREE(ctx, root); /* Evaluate Parse Tree */ current = root; error = NULL; while (current) { switch (current->token.type) { case TOKEN_STRING: current->token.value = ap_ssi_parse_string(ctx, current->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->value = !!*current->token.value; break; case TOKEN_AND: case TOKEN_OR: if (!current->left || !current->right) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return 0; } if (!current->left->done) { switch (current->left->token.type) { case TOKEN_STRING: current->left->token.value = ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->left->value = !!*current->left->token.value; DEBUG_DUMP_EVAL(ctx, current->left); current->left->done = 1; break; default: current = current->left; continue; } } /* short circuit evaluation */ if (!current->right->done && !regex && ((current->token.type == TOKEN_AND && !current->left->value) || (current->token.type == TOKEN_OR && current->left->value))) { current->value = current->left->value; } else { if (!current->right->done) { switch (current->right->token.type) { case TOKEN_STRING: current->right->token.value = ap_ssi_parse_string(ctx,current->right->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->right->value = !!*current->right->token.value; DEBUG_DUMP_EVAL(ctx, current->right); current->right->done = 1; break; default: current = current->right; continue; } } if (current->token.type == TOKEN_AND) { current->value = current->left->value && current->right->value; } else { current->value = current->left->value || current->right->value; } } break; case TOKEN_EQ: case TOKEN_NE: if (!current->left || !current->right || current->left->token.type != TOKEN_STRING || (current->right->token.type != TOKEN_STRING && current->right->token.type != TOKEN_RE)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return 0; } current->left->token.value = ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->right->token.value = ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); if (current->right->token.type == TOKEN_RE) { current->value = re_check(ctx, current->left->token.value, current->right->token.value); --regex; } else { current->value = !strcmp(current->left->token.value, current->right->token.value); } if (current->token.type == TOKEN_NE) { current->value = !current->value; } break; case TOKEN_GE: case TOKEN_GT: case TOKEN_LE: case TOKEN_LT: if (!current->left || !current->right || current->left->token.type != TOKEN_STRING || current->right->token.type != TOKEN_STRING) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s", expr, r->filename); *was_error = 1; return 0; } current->left->token.value = ap_ssi_parse_string(ctx, current->left->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->right->token.value = ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); current->value = strcmp(current->left->token.value, current->right->token.value); switch (current->token.type) { case TOKEN_GE: current->value = current->value >= 0; break; case TOKEN_GT: current->value = current->value > 0; break; case TOKEN_LE: current->value = current->value <= 0; break; case TOKEN_LT: current->value = current->value < 0; break; default: current->value = 0; break; /* should not happen */ } break; case TOKEN_NOT: case TOKEN_GROUP: if (current->right) { if (!current->right->done) { current = current->right; continue; } current->value = current->right->value; } else { current->value = 1; } if (current->token.type == TOKEN_NOT) { current->value = !current->value; } break; case TOKEN_ACCESS: if (current->left || !current->right || (current->right->token.type != TOKEN_STRING && current->right->token.type != TOKEN_RE)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid expression \"%s\" in file %s: Token '-A' must be followed by a URI string.", expr, r->filename); *was_error = 1; return 0; } current->right->token.value = ap_ssi_parse_string(ctx, current->right->token.value, NULL, 0, SSI_EXPAND_DROP_NAME); rr = ap_sub_req_lookup_uri(current->right->token.value, r, NULL); /* 400 and higher are considered access denied */ if (rr->status < HTTP_BAD_REQUEST) { current->value = 1; } else { current->value = 0; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r, "mod_include: The tested " "subrequest -A \"%s\" returned an error code.", current->right->token.value); } ap_destroy_sub_req(rr); break; case TOKEN_RE: if (!error) { error = "No operator before regex in expr \"%s\" in file %s"; } case TOKEN_LBRACE: if (!error) { error = "Unmatched '(' in \"%s\" in file %s"; } default: if (!error) { error = "internal parser error in \"%s\" in file %s"; } ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, error, expr,r->filename); *was_error = 1; return 0; } DEBUG_DUMP_EVAL(ctx, current); current->done = 1; current = current->parent; } return (root ? root->value : 0);}/* * +-------------------------------------------------------+ * | | * | Action Handlers * | | * +-------------------------------------------------------+ *//* * Extract the next tag name and value. * If there are no more tags, set the tag name to NULL. * The tag value is html decoded if dodecode is non-zero. * The tag value may be NULL if there is no tag value.. */static void ap_ssi_get_tag_and_value(include_ctx_t *ctx, char **tag, char **tag_val, int dodecode){ if (!ctx->intern->argv) { *tag = NULL; *tag_val = NULL; return; } *tag_val = ctx->intern->argv->value; *tag = ctx->intern->argv->name; ctx->intern->argv = ctx->intern->argv->next; if (dodecode && *tag_val) { decodehtml(*tag_val); } return;}static int find_file(request_rec *r, const char *directive, const char *tag, char *tag_val, apr_finfo_t *finfo){ char *to_send = tag_val; request_rec *rr = NULL; int ret=0; char *error_fmt = NULL; apr_status_t rv = APR_SUCCESS; if (!strcmp(tag, "file")) { char *newpath; /* be safe; only files in this directory or below allowed */ rv = apr_filepath_merge(&newpath, NULL, tag_val, APR_FILEPATH_SECUREROOTTEST | APR_FILEPATH_NOTABSOLUTE, r->pool); if (rv != APR_SUCCESS) { error_fmt = "unable to access file \"%s\" " "in parsed file %s"; } else { /* note: it is okay to pass NULL for the "next filter" since we never attempt to "run" this sub request. */ rr = ap_sub_req_lookup_file(newpath, r, NULL); if (rr->status == HTTP_OK && rr->finfo.filetype != 0) { to_send = rr->filename; if ((rv = apr_stat(finfo, to_send, APR_FINFO_GPROT | APR_FINFO_MIN, rr->pool)) != APR_SUCCESS && rv != APR_INCOMPLETE) { error_fmt = "unable to get information about \"%s\" " "in parsed file %s"; } } else { error_fmt = "unable to lookup information about \"%s\" " "in parsed file %s"; } } if (error_fmt) { ret = -1; ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, error_fmt, to_send, r->filename); } if (rr) ap_destroy_sub_req(rr); return ret; } else if (!strcmp(tag, "virtual")) { /* note: it is okay to pass NULL for the "next filter" since we never attempt to "run" this sub request. */ rr = ap_sub_req_lookup_uri(tag_val, r, NULL); if (rr->status == HTTP_OK && rr->finfo.filetype != 0) { memcpy((char *) finfo, (const char *) &rr->finfo, sizeof(rr->finfo)); ap_destroy_sub_req(rr); return 0; } else { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unable to get " "information about \"%s\" in parsed file %s", tag_val, r->filename); ap_destroy_sub_req(rr); return -1; } } else { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "unknown parameter \"%s\" " "to tag %s in %s", tag, directive, r->filename); return -1; }}/* * <!--#include virtual|file="..." [virtual|file="..."] ... --> */static apr_status_t handle_include(include_ctx_t *ctx, ap_filter_t *f, apr_bucket_brigade *bb){ request_rec *r = f->r; if (!ctx->argc) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -