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

📄 ngx_http_ssi_filter_module.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>#define NGX_HTTP_SSI_ERROR          1#define NGX_HTTP_SSI_DATE_LEN       2048#define NGX_HTTP_SSI_ADD_PREFIX     1#define NGX_HTTP_SSI_ADD_ZERO       2#define NGX_HTTP_SSI_EXPR_TEST      4typedef struct {    ngx_flag_t    enable;    ngx_flag_t    silent_errors;    ngx_flag_t    ignore_recycled_buffers;    ngx_array_t  *types;     /* array of ngx_str_t */    size_t        min_file_chunk;    size_t        value_len;} ngx_http_ssi_loc_conf_t;typedef struct {    ngx_str_t     name;    ngx_uint_t    key;    ngx_str_t     value;} ngx_http_ssi_var_t;typedef struct {    ngx_str_t     name;    ngx_chain_t  *bufs;    ngx_uint_t    count;} ngx_http_ssi_block_t;typedef enum {    ssi_start_state = 0,    ssi_tag_state,    ssi_comment0_state,    ssi_comment1_state,    ssi_sharp_state,    ssi_precommand_state,    ssi_command_state,    ssi_preparam_state,    ssi_param_state,    ssi_preequal_state,    ssi_prevalue_state,    ssi_double_quoted_value_state,    ssi_quoted_value_state,    ssi_quoted_symbol_state,    ssi_postparam_state,    ssi_comment_end0_state,    ssi_comment_end1_state,    ssi_error_state,    ssi_error_end0_state,    ssi_error_end1_state} ngx_http_ssi_state_e;static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx);static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx);static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,    ngx_str_t *name, ngx_uint_t key);static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,    ngx_int_t rc);static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data,    ngx_int_t rc);static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_set(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_if(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_block(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_endblock(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,    ngx_http_variable_value_t *v,  uintptr_t gmt);static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);static void *ngx_http_ssi_create_loc_conf(ngx_conf_t *cf);static char *ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf,    void *parent, void *child);static ngx_int_t ngx_http_ssi_filter_init(ngx_conf_t *cf);static ngx_command_t  ngx_http_ssi_filter_commands[] = {    { ngx_string("ssi"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF                        |NGX_CONF_FLAG,      ngx_conf_set_flag_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_ssi_loc_conf_t, enable),      NULL },    { ngx_string("ssi_silent_errors"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,      ngx_conf_set_flag_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_ssi_loc_conf_t, silent_errors),      NULL },    { ngx_string("ssi_ignore_recycled_buffers"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,      ngx_conf_set_flag_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_ssi_loc_conf_t, ignore_recycled_buffers),      NULL },    { ngx_string("ssi_min_file_chunk"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,      ngx_conf_set_size_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_ssi_loc_conf_t, min_file_chunk),      NULL },    { ngx_string("ssi_value_length"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,      ngx_conf_set_size_slot,      NGX_HTTP_LOC_CONF_OFFSET,      offsetof(ngx_http_ssi_loc_conf_t, value_len),      NULL },    { ngx_string("ssi_types"),      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,      ngx_http_ssi_types,      NGX_HTTP_LOC_CONF_OFFSET,      0,      NULL },      ngx_null_command};static ngx_http_module_t  ngx_http_ssi_filter_module_ctx = {    ngx_http_ssi_preconfiguration,         /* preconfiguration */    ngx_http_ssi_filter_init,              /* postconfiguration */    ngx_http_ssi_create_main_conf,         /* create main configuration */    ngx_http_ssi_init_main_conf,           /* init main configuration */    NULL,                                  /* create server configuration */    NULL,                                  /* merge server configuration */    ngx_http_ssi_create_loc_conf,          /* create location configuration */    ngx_http_ssi_merge_loc_conf            /* merge location configuration */};ngx_module_t  ngx_http_ssi_filter_module = {    NGX_MODULE_V1,    &ngx_http_ssi_filter_module_ctx,       /* module context */    ngx_http_ssi_filter_commands,          /* module directives */    NGX_HTTP_MODULE,                       /* module type */    NULL,                                  /* init master */    NULL,                                  /* init module */    NULL,                                  /* init process */    NULL,                                  /* init thread */    NULL,                                  /* exit thread */    NULL,                                  /* exit process */    NULL,                                  /* exit master */    NGX_MODULE_V1_PADDING};static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;static u_char ngx_http_ssi_string[] = "<!--";static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;#define  NGX_HTTP_SSI_INCLUDE_VIRTUAL  0#define  NGX_HTTP_SSI_INCLUDE_FILE     1#define  NGX_HTTP_SSI_INCLUDE_WAIT     2#define  NGX_HTTP_SSI_INCLUDE_SET      3#define  NGX_HTTP_SSI_INCLUDE_STUB     4#define  NGX_HTTP_SSI_ECHO_VAR         0#define  NGX_HTTP_SSI_ECHO_DEFAULT     1#define  NGX_HTTP_SSI_ECHO_ENCODING    2#define  NGX_HTTP_SSI_CONFIG_ERRMSG    0#define  NGX_HTTP_SSI_CONFIG_TIMEFMT   1#define  NGX_HTTP_SSI_SET_VAR          0#define  NGX_HTTP_SSI_SET_VALUE        1#define  NGX_HTTP_SSI_IF_EXPR          0#define  NGX_HTTP_SSI_BLOCK_NAME       0static ngx_http_ssi_param_t  ngx_http_ssi_include_params[] = {    { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },    { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },    { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },    { ngx_string("set"), NGX_HTTP_SSI_INCLUDE_SET, 0, 0 },    { ngx_string("stub"), NGX_HTTP_SSI_INCLUDE_STUB, 0, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_echo_params[] = {    { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },    { ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },    { ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_config_params[] = {    { ngx_string("errmsg"), NGX_HTTP_SSI_CONFIG_ERRMSG, 0, 0 },    { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_set_params[] = {    { ngx_string("var"), NGX_HTTP_SSI_SET_VAR, 1, 0 },    { ngx_string("value"), NGX_HTTP_SSI_SET_VALUE, 1, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_if_params[] = {    { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 1, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_block_params[] = {    { ngx_string("name"), NGX_HTTP_SSI_BLOCK_NAME, 1, 0 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_param_t  ngx_http_ssi_no_params[] = {    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_command_t  ngx_http_ssi_commands[] = {    { ngx_string("include"), ngx_http_ssi_include,                       ngx_http_ssi_include_params, 0, 0, 1 },    { ngx_string("echo"), ngx_http_ssi_echo,                       ngx_http_ssi_echo_params, 0, 0, 0 },    { ngx_string("config"), ngx_http_ssi_config,                       ngx_http_ssi_config_params, 0, 0, 0 },    { ngx_string("set"), ngx_http_ssi_set, ngx_http_ssi_set_params, 0, 0, 0 },    { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0, 0 },    { ngx_string("elif"), ngx_http_ssi_if, ngx_http_ssi_if_params,                       NGX_HTTP_SSI_COND_IF, 0, 0 },    { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params,                       NGX_HTTP_SSI_COND_IF, 0, 0 },    { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params,                       NGX_HTTP_SSI_COND_ELSE, 0, 0 },    { ngx_string("block"), ngx_http_ssi_block,                       ngx_http_ssi_block_params, 0, 0, 0 },    { ngx_string("endblock"), ngx_http_ssi_endblock,                       ngx_http_ssi_no_params, 0, 1, 0 },    { ngx_null_string, NULL, NULL, 0, 0, 0 }};static ngx_http_variable_t  ngx_http_ssi_vars[] = {    { ngx_string("date_local"), NULL, ngx_http_ssi_date_gmt_local_variable, 0,      NGX_HTTP_VAR_NOCACHEABLE, 0 },    { ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,      NGX_HTTP_VAR_NOCACHEABLE, 0 },    { ngx_null_string, NULL, NULL, 0, 0, 0 }};static ngx_int_tngx_http_ssi_header_filter(ngx_http_request_t *r){    ngx_uint_t                i;    ngx_str_t                *type;    ngx_http_ssi_ctx_t       *ctx;    ngx_http_ssi_loc_conf_t  *slcf;    slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);    if (!slcf->enable        || r->headers_out.content_type.len == 0        || r->headers_out.content_length_n == 0)    {        return ngx_http_next_header_filter(r);    }    type = slcf->types->elts;    for (i = 0; i < slcf->types->nelts; i++) {        if (r->headers_out.content_type.len >= type[i].len            && ngx_strncasecmp(r->headers_out.content_type.data,                               type[i].data, type[i].len) == 0)        {            goto found;        }    }    return ngx_http_next_header_filter(r);found:    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));    if (ctx == NULL) {        return NGX_ERROR;    }    ngx_http_set_ctx(r, ctx, ngx_http_ssi_filter_module);    ctx->value_len = slcf->value_len;    ctx->last_out = &ctx->out;    ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;    ctx->output = 1;    ctx->params.elts = ctx->params_array;    ctx->params.size = sizeof(ngx_table_elt_t);    ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;    ctx->params.pool = r->pool;    ctx->timefmt.len = sizeof("%A, %d-%b-%Y %H:%M:%S %Z") - 1;    ctx->timefmt.data = (u_char *) "%A, %d-%b-%Y %H:%M:%S %Z";    ctx->errmsg.len =              sizeof("[an error occurred while processing the directive]") - 1;    ctx->errmsg.data = (u_char *)                     "[an error occurred while processing the directive]";    r->filter_need_in_memory = 1;    if (r == r->main) {        ngx_http_clear_content_length(r);        ngx_http_clear_last_modified(r);    }    return ngx_http_next_header_filter(r);}static ngx_int_tngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in){    size_t                     len;    ngx_int_t                  rc;    ngx_buf_t                 *b;    ngx_uint_t                 i, index;    ngx_chain_t               *cl, **ll;    ngx_table_elt_t           *param;    ngx_http_request_t        *pr;    ngx_http_ssi_ctx_t        *ctx, *mctx;    ngx_http_ssi_block_t      *bl;    ngx_http_ssi_param_t      *prm;    ngx_http_ssi_command_t    *cmd;    ngx_http_ssi_loc_conf_t   *slcf;    ngx_http_ssi_main_conf_t  *smcf;    ngx_str_t                 *params[NGX_HTTP_SSI_MAX_PARAMS + 1];    ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);    if (ctx == NULL        || (in == NULL            && ctx->buf == NULL            && ctx->in == NULL            && ctx->busy == NULL))    {        return ngx_http_next_body_filter(r, in);    }    /* add the incoming chain to the chain ctx->in */    if (in) {        if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {            return NGX_ERROR;        }    }    if (ctx->wait) {        if (r->connection->data != r) {            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                           "http ssi filter \"%V\" wait", &r->uri);            return NGX_AGAIN;        }        for (pr = ctx->wait->parent; pr; pr = pr->parent) {            if (pr == r) {                ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                               "http ssi filter \"%V\" flush", &r->uri);                rc = ngx_http_next_body_filter(r, NULL);                if (ctx->wait->done) {                    ctx->wait = NULL;                }                if (rc == NGX_ERROR || rc == NGX_AGAIN) {                    return rc;                }                break;            }        }        if (ctx->wait == r) {            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                           "http ssi filter \"%V\" continue", &r->uri);            ctx->wait = NULL;        }    }    slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "http ssi filter \"%V\"", &r->uri);    while (ctx->in || ctx->buf) {        if (ctx->buf == NULL ){            ctx->buf = ctx->in->buf;            ctx->in = ctx->in->next;            ctx->pos = ctx->buf->pos;        }        if (ctx->state == ssi_start_state) {

⌨️ 快捷键说明

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