aboutsummaryrefslogtreecommitdiffstats
path: root/app/nginx/src/http/modules/ngx_http_sub_filter_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/nginx/src/http/modules/ngx_http_sub_filter_module.c')
-rw-r--r--app/nginx/src/http/modules/ngx_http_sub_filter_module.c1018
1 files changed, 0 insertions, 1018 deletions
diff --git a/app/nginx/src/http/modules/ngx_http_sub_filter_module.c b/app/nginx/src/http/modules/ngx_http_sub_filter_module.c
deleted file mode 100644
index de58c6f..0000000
--- a/app/nginx/src/http/modules/ngx_http_sub_filter_module.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_complex_value_t match;
- ngx_http_complex_value_t value;
-} ngx_http_sub_pair_t;
-
-
-typedef struct {
- ngx_str_t match;
- ngx_http_complex_value_t *value;
-} ngx_http_sub_match_t;
-
-
-typedef struct {
- ngx_uint_t min_match_len;
- ngx_uint_t max_match_len;
-
- u_char index[257];
- u_char shift[256];
-} ngx_http_sub_tables_t;
-
-
-typedef struct {
- ngx_uint_t dynamic; /* unsigned dynamic:1; */
-
- ngx_array_t *pairs;
-
- ngx_http_sub_tables_t *tables;
-
- ngx_hash_t types;
-
- ngx_flag_t once;
- ngx_flag_t last_modified;
-
- ngx_array_t *types_keys;
- ngx_array_t *matches;
-} ngx_http_sub_loc_conf_t;
-
-
-typedef struct {
- ngx_str_t saved;
- ngx_str_t looked;
-
- ngx_uint_t once; /* unsigned once:1 */
-
- ngx_buf_t *buf;
-
- u_char *pos;
- u_char *copy_start;
- u_char *copy_end;
-
- ngx_chain_t *in;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
- ngx_chain_t *busy;
- ngx_chain_t *free;
-
- ngx_str_t *sub;
- ngx_uint_t applied;
-
- ngx_int_t offset;
- ngx_uint_t index;
-
- ngx_http_sub_tables_t *tables;
- ngx_array_t *matches;
-} ngx_http_sub_ctx_t;
-
-
-static ngx_uint_t ngx_http_sub_cmp_index;
-
-
-static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r,
- ngx_http_sub_ctx_t *ctx);
-static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r,
- ngx_http_sub_ctx_t *ctx, ngx_uint_t flush);
-static ngx_int_t ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start,
- ngx_str_t *m);
-
-static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static void *ngx_http_sub_create_conf(ngx_conf_t *cf);
-static char *ngx_http_sub_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static void ngx_http_sub_init_tables(ngx_http_sub_tables_t *tables,
- ngx_http_sub_match_t *match, ngx_uint_t n);
-static ngx_int_t ngx_http_sub_cmp_matches(const void *one, const void *two);
-static ngx_int_t ngx_http_sub_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_sub_filter_commands[] = {
-
- { ngx_string("sub_filter"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_sub_filter,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("sub_filter_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_sub_loc_conf_t, types_keys),
- &ngx_http_html_default_types[0] },
-
- { ngx_string("sub_filter_once"),
- 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_sub_loc_conf_t, once),
- NULL },
-
- { ngx_string("sub_filter_last_modified"),
- 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_sub_loc_conf_t, last_modified),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_sub_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_sub_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_sub_create_conf, /* create location configuration */
- ngx_http_sub_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_sub_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_sub_filter_module_ctx, /* module context */
- ngx_http_sub_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 ngx_int_t
-ngx_http_sub_header_filter(ngx_http_request_t *r)
-{
- ngx_str_t *m;
- ngx_uint_t i, j, n;
- ngx_http_sub_ctx_t *ctx;
- ngx_http_sub_pair_t *pairs;
- ngx_http_sub_match_t *matches;
- ngx_http_sub_loc_conf_t *slcf;
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
-
- if (slcf->pairs == NULL
- || r->headers_out.content_length_n == 0
- || ngx_http_test_content_type(r, &slcf->types) == NULL)
- {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (slcf->dynamic == 0) {
- ctx->tables = slcf->tables;
- ctx->matches = slcf->matches;
-
- } else {
- pairs = slcf->pairs->elts;
- n = slcf->pairs->nelts;
-
- matches = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_match_t) * n);
- if (matches == NULL) {
- return NGX_ERROR;
- }
-
- j = 0;
- for (i = 0; i < n; i++) {
- matches[j].value = &pairs[i].value;
-
- if (pairs[i].match.lengths == NULL) {
- matches[j].match = pairs[i].match.value;
- j++;
- continue;
- }
-
- m = &matches[j].match;
- if (ngx_http_complex_value(r, &pairs[i].match, m) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (m->len == 0) {
- continue;
- }
-
- ngx_strlow(m->data, m->data, m->len);
- j++;
- }
-
- if (j == 0) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx->matches = ngx_palloc(r->pool, sizeof(ngx_array_t));
- if (ctx->matches == NULL) {
- return NGX_ERROR;
- }
-
- ctx->matches->elts = matches;
- ctx->matches->nelts = j;
-
- ctx->tables = ngx_palloc(r->pool, sizeof(ngx_http_sub_tables_t));
- if (ctx->tables == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_sub_init_tables(ctx->tables, ctx->matches->elts,
- ctx->matches->nelts);
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
-
- ctx->saved.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1);
- if (ctx->saved.data == NULL) {
- return NGX_ERROR;
- }
-
- ctx->looked.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1);
- if (ctx->looked.data == NULL) {
- return NGX_ERROR;
- }
-
- ctx->offset = ctx->tables->min_match_len - 1;
- ctx->last_out = &ctx->out;
-
- r->filter_need_in_memory = 1;
-
- if (r == r->main) {
- ngx_http_clear_content_length(r);
-
- if (!slcf->last_modified) {
- ngx_http_clear_last_modified(r);
- ngx_http_clear_etag(r);
-
- } else {
- ngx_http_weak_etag(r);
- }
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_str_t *sub;
- ngx_uint_t flush, last;
- ngx_chain_t *cl;
- ngx_http_sub_ctx_t *ctx;
- ngx_http_sub_match_t *match;
- ngx_http_sub_loc_conf_t *slcf;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_sub_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- if ((in == NULL
- && ctx->buf == NULL
- && ctx->in == NULL
- && ctx->busy == NULL))
- {
- return ngx_http_next_body_filter(r, in);
- }
-
- if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) {
-
- if (ctx->busy) {
- if (ngx_http_sub_output(r, ctx) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- 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_OK) {
- return NGX_ERROR;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http sub filter \"%V\"", &r->uri);
-
- flush = 0;
- last = 0;
-
- 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->buf->flush || ctx->buf->recycled) {
- flush = 1;
- }
-
- if (ctx->in == NULL) {
- last = flush;
- }
-
- b = NULL;
-
- while (ctx->pos < ctx->buf->last) {
-
- rc = ngx_http_sub_parse(r, ctx, last);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "parse: %i, looked: \"%V\" %p-%p",
- rc, &ctx->looked, ctx->copy_start, ctx->copy_end);
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- if (ctx->saved.len) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: \"%V\"", &ctx->saved);
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
- if (b->pos == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
- b->last = b->pos + ctx->saved.len;
- b->memory = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->saved.len = 0;
- }
-
- if (ctx->copy_start != ctx->copy_end) {
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
-
- b->pos = ctx->copy_start;
- b->last = ctx->copy_end;
- b->shadow = NULL;
- b->last_buf = 0;
- b->last_in_chain = 0;
- b->recycled = 0;
-
- if (b->in_file) {
- b->file_last = b->file_pos + (b->last - ctx->buf->pos);
- b->file_pos += b->pos - ctx->buf->pos;
- }
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- }
-
- if (rc == NGX_AGAIN) {
- continue;
- }
-
-
- /* rc == NGX_OK */
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
-
- if (ctx->sub == NULL) {
- ctx->sub = ngx_pcalloc(r->pool, sizeof(ngx_str_t)
- * ctx->matches->nelts);
- if (ctx->sub == NULL) {
- return NGX_ERROR;
- }
- }
-
- sub = &ctx->sub[ctx->index];
-
- if (sub->data == NULL) {
- match = ctx->matches->elts;
-
- if (ngx_http_complex_value(r, match[ctx->index].value, sub)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- if (sub->len) {
- b->memory = 1;
- b->pos = sub->data;
- b->last = sub->data + sub->len;
-
- } else {
- b->sync = 1;
- }
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->index = 0;
- ctx->once = slcf->once && (++ctx->applied == ctx->matches->nelts);
-
- continue;
- }
-
- if (ctx->looked.len
- && (ctx->buf->last_buf || ctx->buf->last_in_chain))
- {
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = ctx->looked.data;
- b->last = b->pos + ctx->looked.len;
- b->memory = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->looked.len = 0;
- }
-
- if (ctx->buf->last_buf || ctx->buf->flush || ctx->buf->sync
- || ngx_buf_in_memory(ctx->buf))
- {
- if (b == NULL) {
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->sync = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- }
-
- b->last_buf = ctx->buf->last_buf;
- b->last_in_chain = ctx->buf->last_in_chain;
- b->flush = ctx->buf->flush;
- b->shadow = ctx->buf;
-
- b->recycled = ctx->buf->recycled;
- }
-
- ctx->buf = NULL;
- }
-
- if (ctx->out == NULL && ctx->busy == NULL) {
- return NGX_OK;
- }
-
- return ngx_http_sub_output(r, ctx);
-}
-
-
-static ngx_int_t
-ngx_http_sub_output(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
-#if 1
- b = NULL;
- for (cl = ctx->out; cl; cl = cl->next) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "sub out: %p %p", cl->buf, cl->buf->pos);
- if (cl->buf == b) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "the same buf was used in sub");
- ngx_debug_point();
- return NGX_ERROR;
- }
- b = cl->buf;
- }
-#endif
-
- rc = ngx_http_next_body_filter(r, ctx->out);
-
- if (ctx->busy == NULL) {
- ctx->busy = ctx->out;
-
- } else {
- for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }
- cl->next = ctx->out;
- }
-
- ctx->out = NULL;
- ctx->last_out = &ctx->out;
-
- while (ctx->busy) {
-
- cl = ctx->busy;
- b = cl->buf;
-
- if (ngx_buf_size(b) != 0) {
- break;
- }
-
- if (b->shadow) {
- b->shadow->pos = b->shadow->last;
- }
-
- ctx->busy = cl->next;
-
- if (ngx_buf_in_memory(b) || b->in_file) {
- /* add data bufs only to the free buf chain */
-
- cl->next = ctx->free;
- ctx->free = cl;
- }
- }
-
- if (ctx->in || ctx->buf) {
- r->buffered |= NGX_HTTP_SUB_BUFFERED;
-
- } else {
- r->buffered &= ~NGX_HTTP_SUB_BUFFERED;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx,
- ngx_uint_t flush)
-{
- u_char *p, c;
- ngx_str_t *m;
- ngx_int_t offset, start, next, end, len, rc;
- ngx_uint_t shift, i, j;
- ngx_http_sub_match_t *match;
- ngx_http_sub_tables_t *tables;
- ngx_http_sub_loc_conf_t *slcf;
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
- tables = ctx->tables;
- match = ctx->matches->elts;
-
- offset = ctx->offset;
- end = ctx->buf->last - ctx->pos;
-
- if (ctx->once) {
- /* sets start and next to end */
- offset = end + (ngx_int_t) tables->min_match_len - 1;
- goto again;
- }
-
- while (offset < end) {
-
- c = offset < 0 ? ctx->looked.data[ctx->looked.len + offset]
- : ctx->pos[offset];
-
- c = ngx_tolower(c);
-
- shift = tables->shift[c];
- if (shift > 0) {
- offset += shift;
- continue;
- }
-
- /* a potential match */
-
- start = offset - (ngx_int_t) tables->min_match_len + 1;
-
- i = ngx_max((ngx_uint_t) tables->index[c], ctx->index);
- j = tables->index[c + 1];
-
- while (i != j) {
-
- if (slcf->once && ctx->sub && ctx->sub[i].data) {
- goto next;
- }
-
- m = &match[i].match;
-
- rc = ngx_http_sub_match(ctx, start, m);
-
- if (rc == NGX_DECLINED) {
- goto next;
- }
-
- ctx->index = i;
-
- if (rc == NGX_AGAIN) {
- goto again;
- }
-
- ctx->offset = offset + (ngx_int_t) m->len;
- next = start + (ngx_int_t) m->len;
- end = ngx_max(next, 0);
- rc = NGX_OK;
-
- goto done;
-
- next:
-
- i++;
- }
-
- offset++;
- ctx->index = 0;
- }
-
- if (flush) {
- for ( ;; ) {
- start = offset - (ngx_int_t) tables->min_match_len + 1;
-
- if (start >= end) {
- break;
- }
-
- for (i = 0; i < ctx->matches->nelts; i++) {
- m = &match[i].match;
-
- if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) {
- goto again;
- }
- }
-
- offset++;
- }
- }
-
-again:
-
- ctx->offset = offset;
- start = offset - (ngx_int_t) tables->min_match_len + 1;
- next = start;
- rc = NGX_AGAIN;
-
-done:
-
- /* send [ - looked.len, start ] to client */
-
- ctx->saved.len = ctx->looked.len + ngx_min(start, 0);
- ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len);
-
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->pos + ngx_max(start, 0);
-
- /* save [ next, end ] in looked */
-
- len = ngx_min(next, 0);
- p = ctx->looked.data;
- p = ngx_movemem(p, p + ctx->looked.len + len, - len);
-
- len = ngx_max(next, 0);
- p = ngx_cpymem(p, ctx->pos + len, end - len);
- ctx->looked.len = p - ctx->looked.data;
-
- /* update position */
-
- ctx->pos += end;
- ctx->offset -= end;
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_sub_match(ngx_http_sub_ctx_t *ctx, ngx_int_t start, ngx_str_t *m)
-{
- u_char *p, *last, *pat, *pat_end;
-
- pat = m->data;
- pat_end = m->data + m->len;
-
- if (start >= 0) {
- p = ctx->pos + start;
-
- } else {
- last = ctx->looked.data + ctx->looked.len;
- p = last + start;
-
- while (p < last && pat < pat_end) {
- if (ngx_tolower(*p) != *pat) {
- return NGX_DECLINED;
- }
-
- p++;
- pat++;
- }
-
- p = ctx->pos;
- }
-
- while (p < ctx->buf->last && pat < pat_end) {
- if (ngx_tolower(*p) != *pat) {
- return NGX_DECLINED;
- }
-
- p++;
- pat++;
- }
-
- if (pat != pat_end) {
- /* partial match */
- return NGX_AGAIN;
- }
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_sub_loc_conf_t *slcf = conf;
-
- ngx_str_t *value;
- ngx_http_sub_pair_t *pair;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (value[1].len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty search pattern");
- return NGX_CONF_ERROR;
- }
-
- if (slcf->pairs == NULL) {
- slcf->pairs = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_sub_pair_t));
- if (slcf->pairs == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (slcf->pairs->nelts == 255) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "number of search patterns exceeds 255");
- return NGX_CONF_ERROR;
- }
-
- ngx_strlow(value[1].data, value[1].data, value[1].len);
-
- pair = ngx_array_push(slcf->pairs);
- if (pair == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &pair->match;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ccv.complex_value->lengths != NULL) {
- slcf->dynamic = 1;
-
- } else {
- ngx_strlow(pair->match.value.data, pair->match.value.data,
- pair->match.value.len);
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &pair->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_sub_create_conf(ngx_conf_t *cf)
-{
- ngx_http_sub_loc_conf_t *slcf;
-
- slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
- if (slcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->dynamic = 0;
- * conf->pairs = NULL;
- * conf->tables = NULL;
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- * conf->matches = NULL;
- */
-
- slcf->once = NGX_CONF_UNSET;
- slcf->last_modified = NGX_CONF_UNSET;
-
- return slcf;
-}
-
-
-static char *
-ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_uint_t i, n;
- ngx_http_sub_pair_t *pairs;
- ngx_http_sub_match_t *matches;
- ngx_http_sub_loc_conf_t *prev = parent;
- ngx_http_sub_loc_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->once, prev->once, 1);
- ngx_conf_merge_value(conf->last_modified, prev->last_modified, 0);
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_html_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->pairs == NULL) {
- conf->dynamic = prev->dynamic;
- conf->pairs = prev->pairs;
- conf->matches = prev->matches;
- conf->tables = prev->tables;
- }
-
- if (conf->pairs && conf->dynamic == 0 && conf->tables == NULL) {
- pairs = conf->pairs->elts;
- n = conf->pairs->nelts;
-
- matches = ngx_palloc(cf->pool, sizeof(ngx_http_sub_match_t) * n);
- if (matches == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; i < n; i++) {
- matches[i].match = pairs[i].match.value;
- matches[i].value = &pairs[i].value;
- }
-
- conf->matches = ngx_palloc(cf->pool, sizeof(ngx_array_t));
- if (conf->matches == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->matches->elts = matches;
- conf->matches->nelts = n;
-
- conf->tables = ngx_palloc(cf->pool, sizeof(ngx_http_sub_tables_t));
- if (conf->tables == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_http_sub_init_tables(conf->tables, conf->matches->elts,
- conf->matches->nelts);
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void
-ngx_http_sub_init_tables(ngx_http_sub_tables_t *tables,
- ngx_http_sub_match_t *match, ngx_uint_t n)
-{
- u_char c;
- ngx_uint_t i, j, min, max, ch;
-
- min = match[0].match.len;
- max = match[0].match.len;
-
- for (i = 1; i < n; i++) {
- min = ngx_min(min, match[i].match.len);
- max = ngx_max(max, match[i].match.len);
- }
-
- tables->min_match_len = min;
- tables->max_match_len = max;
-
- ngx_http_sub_cmp_index = tables->min_match_len - 1;
- ngx_sort(match, n, sizeof(ngx_http_sub_match_t), ngx_http_sub_cmp_matches);
-
- min = ngx_min(min, 255);
- ngx_memset(tables->shift, min, 256);
-
- ch = 0;
-
- for (i = 0; i < n; i++) {
-
- for (j = 0; j < min; j++) {
- c = match[i].match.data[tables->min_match_len - 1 - j];
- tables->shift[c] = ngx_min(tables->shift[c], (u_char) j);
- }
-
- c = match[i].match.data[tables->min_match_len - 1];
- while (ch <= (ngx_uint_t) c) {
- tables->index[ch++] = (u_char) i;
- }
- }
-
- while (ch < 257) {
- tables->index[ch++] = (u_char) n;
- }
-}
-
-
-static ngx_int_t
-ngx_http_sub_cmp_matches(const void *one, const void *two)
-{
- ngx_int_t c1, c2;
- ngx_http_sub_match_t *first, *second;
-
- first = (ngx_http_sub_match_t *) one;
- second = (ngx_http_sub_match_t *) two;
-
- c1 = first->match.data[ngx_http_sub_cmp_index];
- c2 = second->match.data[ngx_http_sub_cmp_index];
-
- return c1 - c2;
-}
-
-
-static ngx_int_t
-ngx_http_sub_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_sub_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_sub_body_filter;
-
- return NGX_OK;
-}