aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_hunk.c22
-rw-r--r--src/http/modules/ngx_http_ssi_filter.c274
2 files changed, 180 insertions, 116 deletions
diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c
index 79a8ad748..1f05dc839 100644
--- a/src/core/ngx_hunk.c
+++ b/src/core/ngx_hunk.c
@@ -5,13 +5,15 @@
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
int before, int after)
{
- ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
+ ngx_hunk_t *h;
+
+ ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL);
#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
#endif
- h->pre_start = ngx_palloc(pool, size + before + after);
+ ngx_test_null(h->pre_start, ngx_palloc(pool, size + before + after), NULL);
h->start = h->pos.mem = h->last.mem = h->pre_start + before;
h->end = h->last.mem + size;
h->post_end = h->end + after;
@@ -25,7 +27,9 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
{
- ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
+ ngx_hunk_t *h;
+
+ ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL);
#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
@@ -42,8 +46,8 @@ ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
h->file = NULL;
} else {
- h->pre_start = h->start = h->pos.mem = h->last.mem
- = ngx_palloc(pool, size);
+ ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
+ h->start = h->pos.mem = h->last.mem = h->pre_start;
h->end = h->post_end = h->start + size;
h->type = NGX_HUNK_TEMP;
@@ -56,7 +60,9 @@ ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
ngx_hunk_t *ngx_create_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
{
- ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
+ ngx_hunk_t *h;
+
+ ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL);
#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
@@ -74,8 +80,8 @@ ngx_hunk_t *ngx_create_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
h->file = NULL;
} else {
- h->pre_start = h->start = h->pos.mem = h->last.mem =
- ngx_palloc(pool, size);
+ ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
+ h->start = h->pos.mem = h->last.mem = h->pre_start;
h->end = h->post_end = h->start + size;
h->type = NGX_HUNK_TEMP;
diff --git a/src/http/modules/ngx_http_ssi_filter.c b/src/http/modules/ngx_http_ssi_filter.c
index 4a94a2367..55194aaf4 100644
--- a/src/http/modules/ngx_http_ssi_filter.c
+++ b/src/http/modules/ngx_http_ssi_filter.c
@@ -39,172 +39,230 @@ int ngx_http_ssi_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_http_ssi_filter_ctx_t *ctx;
ngx_http_ssi_filter_conf_t *conf;
+ if (in == NULL)
+ return next_filter;
+
ctx = (ngx_http_ssi_filter_ctx_t *)
- ngx_get_module_ctx(r->main ? r->main : r,
- ngx_http_ssi_filter_module);
+ ngx_get_module_ctx(r, ngx_http_ssi_filter_module);
if (ctx == NULL) {
ngx_http_create_ctx(r, ctx,
ngx_http_ssi_filter_module,
sizeof(ngx_http_ssi_filter_ctx_t));
ctx->state = &ssi_start;
+ ctx->handler = ngx_http_ssi_find_start;
}
- state = ctx->state;
- length = ctx->length;
-
ch = in;
- p = ch->hunk->pos.mem;
+ ctx->start = ctx->pos = ch->hunk->pos.mem;
+
+ for ( ;; ) {
+ if (ctx->handler(r, ctx, ch) == NGX_ERROR)
+ return NGX_ERROR;
+
+ if (ctx->pos + ctx->length == ch->hunk->last.mem) {
+ ch = ch->next;
+ if (ch == NULL)
+ break;
+
+ ctx->start = ctx->pos = ch->hunk->pos.mem;
+ }
+ }
+}
+
+
- rc = ngx_http_ssi_parse(r, ctx, in);
- if (rc == NGX_SSI_FOUND) {
+static int ngx_http_ssi_find_start(ngx_http_request_t *r,
+ ngx_http_ssi_filter_ctx_t *ctx,
+ ngx_chain_t *ch)
+{
+ ngx_http_ssi_parse(r, ctx, ch->hunk);
+
+ if (ctx->state == ssi_command_state
+ || (ctx->length > 0 && ch->next == NULL)
+ || ctx->hunk_with_ssi)
+ {
+ ngx_test_null(h, ngx_palloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
+#if !(HAVE_OFFSET_EQUAL_PTR)
+ h->pos.file = h->last.file = 0;
+#endif
+ h->pre_start = h->start = h->pos.mem = ctx->start;
+ h->post_end = h->end = h->last.mem = ctx->pos;
+ h->type = NGX_HUNK_TEMP;
+ h->tag = 0;
+ h->file = NULL;
+
+ ngx_add_hunk_to_chain(ctx->last, h, r->pool, NGX_ERROR);
+
+ ngx_test_null(ssi_hunk, ngx_push_array(ctx->ssi_hunks), NGX_ERROR);
+ ssi_hunk->ssi_hunk = h;
+ ssi_hunk->hunk = ch->hunk;
+ ssi_hunk->pos = NULL;
}
+ if (ctx->state == ssi_command_state)
+ ctx->handler = ngx_http_ssi_find_command;
+ }
+
+ return NGX_OK;
}
-static int ngx_http_ssi_parse(ngx_http_request_t *r,
- ngx_http_ssi_filter_ctx_t *ctx, ngx_chain_t *in)
+static int ngx_http_ssi_find_command(ngx_http_request_t *r,
+ ngx_http_ssi_filter_ctx_t *ctx,
+ ngx_chain_t *ch)
{
- state = ctx->state;
- length = ctx->length;
+ ngx_http_ssi_parse_command(r, ctx, ch->hunk);
+}
+
+
+static char ssi_start[] = "<!--#";
+
+static char ssi_include[] = "include";
+
+static ssi_parser_t ssi_pre_command_state[] = {
+ { 1, (char *) ' ', ssi_pre_command_state, NULL },
+
+ { 7, "include", ssi_command_state, ssi_include_state },
+
+ { 4, "random", ssi_command_state, NULL },
+ { 0, NULL, ssi_error_state }
+};
+
+static ssi_parser_t ssi_include_state[] = {
+ { 1, (char *) ' ', ssi_include_state, NULL },
+ { 7, "virtual", ssi_equal_state, offsetof(ssi_include_t, virtual) },
+ { 0, NULL, ssi_error_state }
+};
+
+static ssi_parser_t ssi_equal_state[] = {
+ { 1, (char *) ' ', ssi_equal_state, NULL },
+ { 1, (char *) '=', ssi_param_state, NULL },
+};
+
+static char ssi_echo[] = "echo";
+
+static void ngx_http_ssi_parse(ngx_http_request_t *r,
+ ngx_http_ssi_filter_ctx_t *ctx,
+ ngx_hunk_t *hunk)
+
for ( ;; ) {
- if (state == ssi_start_state) {
- for (/* void */ ; p < ch->hunk->last.mem; p++) {
- if (*p == '<') {
- state = ssi_exclam_state;
- length = 1;
- break;
- }
- }
- }
+ for (/* void */ ; p < ch->hunk->last.mem; p++) {
- for (/* void */ ;
- p < ch->hunk->last.mem
- && (state > ssi_start_state && state < ssi_command_state)
- p++)
- {
switch (state) {
- case ssi_exclam_state:
- switch (*p) {
+ case ssi_start_state:
- case '!':
- state = ssi_dash1_state;
- length = 2;
- break;
+ /* tight loop */
+ while (p < ch->hunk->last.mem) {
+ if (*p++ == '<') {
+ state = ssi_comment_state;
+ length = 1;
+ break;
+ }
+ }
- case '<':
- state = ssi_exclam_state;
- length = 1;
- break;
+ /* fall through */
- default:
- state = ssi_start_state;
+ case ssi_comment_state:
+
+ if (*p == ssi_start[length]) {
+ length++;
+
+ } else {
length = 0;
- break;
+ flush = 1;
+ state = ssi_start_state;
}
- break;
+ if (length < 6)
+ continue;
- case ssi_dash1_state:
- switch (*p) {
+ state = ssi_space_before_command_state;
- case '-':
- state = ssi_dash2_state;
- length = 3;
- break;
+ /* fall through */
- case '<':
- state = ssi_exclam_state;
- length = 1;
- break;
+ case ssi_space_before_command_state:
- default:
- state = ssi_start_state;
- length = 0;
- break;
- }
-
- break;
+ if (*p == ' ' || *p == '\t' || *p == CR || *p == LF)
+ continue;
- case ssi_dash2_state:
- switch (*p) {
+ state = ssi_command_state;
- case '-':
- state = ssi_sharp_state;
- length = 4;
- break;
+ /* fall through */
- case '<':
- state = ssi_exclam_state;
- length = 1;
- break;
+ case ssi_choose_command_state:
- default:
- state = ssi_start_state;
- length = 0;
- break;
+ for (i = 0; ctx->name[i].len; i++) {
+ if (*p == ctx->name[i].name[0]) {
+ state = choos[i].state;
+ }
}
+ case ssi_command_state:
+ if (*p == ssi_include[n];
+ n++;
+
break;
- case ssi_sharp_state:
- switch (*p) {
+ }
+ }
- case '#':
- ctx->state = ssi_command_state;
- ctx->length = 5;
- return NGX_SSI_FOUND;
+ if (length == 6
+ || (length > 0 && ch->next == NULL)
+ || hunk_with_ssi) {
- case '<':
- state = ssi_exclam_state;
- length = 1;
- break;
+ if (ctx->saved > 0 && flush) {
+ add saved
+ ctx->saved = 0;
+ }
- default:
- state = ssi_start_state;
- length = 0;
- break;
+ for (c = ctx->in; c != hunk; c = c->next) {
+ ngx_add_hunk_to_chain(ctx->last, c->hunk,
+ r->pool, NGX_ERROR);
}
- break;
+ add duped;
+ push duped_hunk, hunk, NULL;
+
+ n = length - (hunk->last.mem - pos);
+ for (c = hunk; c; c->next) {
+ if (n > c->hunk->last.mem - c->hunk->pos.mem) {
+ n -= c->hunk->last.mem - c->hunk->pos.mem;
+ push NULL, c->hunk, NULL;
+ }
+ }
+
+ ctx->in = c;
}
}
- if (state > ssi_start_state) {
- ngx_add_hunk_to_chain(ch->hunk);
- }
+ } else {
- ch = ch->next;
- if (ch == NULL) {
- ctx->state = state;
+ for (/* void */ ; p < ch->hunk->last.mem; p++) {
+ if (*p == ' ' || *p == '\t' || *p == CR || *P == LF)
+ continue;
+
+ ctx->state = ssi_command_state;
break;
}
- p = ch->hunk->pos.mem;
+ if (
+
}
+}
+
+
+
+
+
+
- if (state > ssi_start_state)
- if (ngx_http_ssi_dup_hunk(r, ch->hunk) == NGX_ERROR)
- return NGX_ERROR;
-}
-static ngx_http_ssi_dup_hunk(ngx_http_request_t *r, ngx_hunk_t *hunk);
-{
- new dup_hunk
- set dup_hunk
- ngx_add_hunk_to_chain dup_hunk
-
- ngx_test_null(ssi_hunk, ngx_push_array);
- ssi_hunk->ssi_hunk = dup_hunk;
- ssi_hunk->hunk = hunk;
- ssi_hunk->pos = NULL;
-}