Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_ssi_filter.c @ 239:574bea0142be
nginx-0.0.1-2004-01-26-11:52:49 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 26 Jan 2004 08:52:49 +0000 |
parents | 049e78b1f852 |
children | 725129fdd524 |
comparison
equal
deleted
inserted
replaced
238:674f85a4d00f | 239:574bea0142be |
---|---|
5 | 5 |
6 | 6 |
7 #define NGX_HTTP_SSI_COMMAND_LEN 31 | 7 #define NGX_HTTP_SSI_COMMAND_LEN 31 |
8 #define NGX_HTTP_SSI_PARAM_LEN 31 | 8 #define NGX_HTTP_SSI_PARAM_LEN 31 |
9 | 9 |
10 #define NGX_HTTP_SSI_DONE 1 | 10 #define NGX_HTTP_SSI_COPY 1 |
11 #define NGX_HTTP_SSI_INVALID_COMMAND 2 | 11 #define NGX_HTTP_SSI_INVALID_COMMAND 2 |
12 #define NGX_HTTP_SSI_INVALID_PARAM 3 | 12 #define NGX_HTTP_SSI_INVALID_PARAM 3 |
13 #define NGX_HTTP_SSI_INVALID_VALUE 4 | 13 #define NGX_HTTP_SSI_INVALID_VALUE 4 |
14 #define NGX_HTTP_SSI_LONG_VALUE 5 | 14 #define NGX_HTTP_SSI_LONG_VALUE 5 |
15 | 15 |
16 | 16 |
17 typedef struct { | 17 typedef struct { |
18 ngx_hunk_t *hunk; | 18 int enable; |
19 ngx_table_elt_t *param; | 19 } ngx_http_ssi_conf_t; |
20 ngx_str_t command; | 20 |
21 ngx_array_t params; | 21 |
22 int state; | 22 typedef struct { |
23 int looked; | 23 ngx_hunk_t *buf; |
24 char *pos; | 24 |
25 ngx_chain_t *incoming; | 25 char *start; |
26 int new_hunk; | 26 char *last; |
27 u_int value_len; | 27 char *pos; |
28 | |
29 ngx_table_elt_t *param; | |
30 ngx_str_t command; | |
31 ngx_array_t params; | |
32 int state; | |
33 | |
34 ngx_chain_t *in; | |
35 ngx_chain_t *current; | |
36 ngx_chain_t *out; | |
37 ngx_chain_t **last_out; | |
38 ngx_chain_t *busy; | |
39 | |
40 size_t prev; | |
41 | |
42 u_int value_len; | |
28 } ngx_http_ssi_ctx_t; | 43 } ngx_http_ssi_ctx_t; |
29 | 44 |
30 | 45 |
46 static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r, | |
47 ngx_http_ssi_ctx_t *ctx); | |
48 static void *ngx_http_ssi_create_conf(ngx_conf_t *cf); | |
49 static char *ngx_http_ssi_merge_conf(ngx_conf_t *cf, | |
50 void *parent, void *child); | |
31 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle); | 51 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle); |
52 | |
53 | |
54 static ngx_command_t ngx_http_ssi_filter_commands[] = { | |
55 | |
56 { ngx_string("ssi"), | |
57 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
58 ngx_conf_set_flag_slot, | |
59 NGX_HTTP_LOC_CONF_OFFSET, | |
60 offsetof(ngx_http_ssi_conf_t, enable), | |
61 NULL }, | |
62 | |
63 ngx_null_command | |
64 }; | |
65 | |
32 | 66 |
33 | 67 |
34 static ngx_http_module_t ngx_http_ssi_filter_module_ctx = { | 68 static ngx_http_module_t ngx_http_ssi_filter_module_ctx = { |
69 NULL, /* pre conf */ | |
70 | |
35 NULL, /* create main configuration */ | 71 NULL, /* create main configuration */ |
36 NULL, /* init main configuration */ | 72 NULL, /* init main configuration */ |
37 | 73 |
38 NULL, /* create server configuration */ | 74 NULL, /* create server configuration */ |
39 NULL, /* merge server configuration */ | 75 NULL, /* merge server configuration */ |
40 | 76 |
41 NULL, /* create location configuration */ | 77 ngx_http_ssi_create_conf, /* create location configuration */ |
42 NULL, /* merge location configuration */ | 78 ngx_http_ssi_merge_conf /* merge location configuration */ |
43 }; | 79 }; |
44 | 80 |
45 | 81 |
46 ngx_module_t ngx_http_ssi_filter_module = { | 82 ngx_module_t ngx_http_ssi_filter_module = { |
47 NGX_MODULE, | 83 NGX_MODULE, |
48 &ngx_http_ssi_filter_module_ctx, /* module context */ | 84 &ngx_http_ssi_filter_module_ctx, /* module context */ |
49 NULL, /* module directives */ | 85 ngx_http_ssi_filter_commands, /* module directives */ |
50 NGX_HTTP_MODULE, /* module type */ | 86 NGX_HTTP_MODULE, /* module type */ |
51 ngx_http_ssi_filter_init, /* init module */ | 87 ngx_http_ssi_filter_init, /* init module */ |
52 NULL /* init child */ | 88 NULL /* init child */ |
53 }; | 89 }; |
54 | 90 |
55 | 91 |
56 static int (*next_header_filter) (ngx_http_request_t *r); | 92 static int (*ngx_http_next_header_filter) (ngx_http_request_t *r); |
57 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); | 93 static int (*ngx_http_next_body_filter) (ngx_http_request_t *r, ngx_chain_t *in); |
58 | 94 |
59 | 95 |
60 | 96 |
61 static char comment_string[] = "<!--"; | 97 static char comment_string[] = "<!--"; |
98 static char error_string[] = "[an error occurred while processing " | |
99 "the directive]"; | |
62 | 100 |
63 | 101 |
64 static int ngx_http_ssi_header_filter(ngx_http_request_t *r) | 102 static int ngx_http_ssi_header_filter(ngx_http_request_t *r) |
65 { | 103 { |
104 ngx_http_ssi_ctx_t *ctx; | |
105 ngx_http_ssi_conf_t *conf; | |
106 | |
107 conf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); | |
108 | |
109 if (!conf->enable) { | |
110 return ngx_http_next_header_filter(r); | |
111 } | |
112 | |
113 ngx_http_create_ctx(r, ctx, ngx_http_ssi_filter_module, | |
114 sizeof(ngx_http_ssi_ctx_t), NGX_ERROR); | |
115 | |
116 ctx->last_out = &ctx->out; | |
117 /* STUB: conf */ ctx->value_len = 200; | |
118 | |
119 r->headers_out.content_length_n = -1; | |
120 if (r->headers_out.content_length) { | |
121 r->headers_out.content_length->key.len = 0; | |
122 r->headers_out.content_length = NULL; | |
123 } | |
124 | |
125 r->headers_out.last_modified_time = -1; | |
126 if (r->headers_out.last_modified) { | |
127 r->headers_out.last_modified->key.len = 0; | |
128 r->headers_out.last_modified = NULL; | |
129 } | |
130 | |
131 r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY; | |
132 | |
133 return ngx_http_next_header_filter(r); | |
134 } | |
135 | |
136 | |
137 static int ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
138 { | |
139 ngx_int_t rc; | |
140 ngx_hunk_t *hunk; | |
141 ngx_chain_t *cl, *tl; | |
66 ngx_http_ssi_ctx_t *ctx; | 142 ngx_http_ssi_ctx_t *ctx; |
67 | 143 |
68 /* if () */ { | 144 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); |
69 ngx_http_create_ctx(r, ctx, ngx_http_ssi_filter_module, | 145 |
70 sizeof(ngx_http_ssi_ctx_t), NGX_ERROR); | 146 if (ctx == NULL || (in == NULL && ctx->in == NULL)) { |
147 return ngx_http_next_body_filter(r, NULL); | |
148 } | |
149 | |
150 /* add the incoming hunk to the chain ctx->in */ | |
151 | |
152 if (in) { | |
153 if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) { | |
154 return NGX_ERROR; | |
155 } | |
156 | |
157 if (ctx->current == NULL) { | |
158 ctx->current = ctx->in; | |
159 } | |
160 } | |
161 | |
162 while (ctx->current) { | |
163 if (ctx->buf == NULL) { | |
164 ctx->buf = ctx->current->hunk; | |
165 ctx->current = ctx->current->next; | |
166 | |
167 ctx->start = ctx->buf->pos; | |
168 ctx->pos = ctx->buf->pos; | |
169 ctx->last = ctx->buf->pos; | |
170 } | |
171 | |
172 while (ctx->pos < ctx->buf->last) { | |
173 rc = ngx_http_ssi_parse(r, ctx); | |
174 | |
175 if (rc == NGX_ERROR) { | |
176 return rc; | |
177 | |
178 } else if (rc == NGX_HTTP_SSI_COPY) { | |
179 if (ctx->prev) { | |
180 | |
181 if (!(hunk = ngx_calloc_hunk(r->pool))) { | |
182 return NGX_ERROR; | |
183 } | |
184 | |
185 hunk->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
186 hunk->pos = comment_string; | |
187 hunk->last = comment_string + ctx->prev; | |
188 | |
189 ngx_alloc_link_and_set_hunk(cl, hunk, r->pool, NGX_ERROR); | |
190 | |
191 *ctx->last_out = cl; | |
192 ctx->last_out = &cl->next; | |
193 | |
194 ctx->prev = 0; | |
195 } | |
196 | |
197 if (ctx->pos == ctx->buf->last) { | |
198 ctx->prev = ctx->buf->last - ctx->last; | |
199 } | |
200 | |
201 if (!(hunk = ngx_calloc_hunk(r->pool))) { | |
202 return NGX_ERROR; | |
203 } | |
204 | |
205 hunk->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_RECYCLED; | |
206 hunk->pos = ctx->start; | |
207 hunk->last = ctx->last; | |
208 hunk->shadow = ctx->buf; | |
209 | |
210 ngx_alloc_link_and_set_hunk(cl, hunk, r->pool, NGX_ERROR); | |
211 | |
212 *ctx->last_out = cl; | |
213 ctx->last_out = &cl->next; | |
214 | |
215 continue; | |
216 | |
217 #if 0 | |
218 } else if (rc == NGX_HTTP_SSI_INVALID_COMMAND) { | |
219 } else if (rc == NGX_HTTP_SSI_INVALID_PARAM) { | |
220 } else if (rc == NGX_HTTP_SSI_INVALID_VALUE) { | |
221 } else if (rc == NGX_HTTP_SSI_LONG_VALUE) { | |
222 #endif | |
223 | |
224 } else { | |
225 if (!(hunk = ngx_calloc_hunk(r->pool))) { | |
226 return NGX_ERROR; | |
227 } | |
228 | |
229 hunk->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
230 hunk->pos = error_string; | |
231 hunk->last = error_string + sizeof(error_string) - 1; | |
232 | |
233 ngx_alloc_link_and_set_hunk(cl, hunk, r->pool, NGX_ERROR); | |
234 | |
235 *ctx->last_out = cl; | |
236 ctx->last_out = &cl->next; | |
237 } | |
238 } | |
239 } | |
240 | |
241 if (ctx->out) { | |
242 if (ngx_http_next_body_filter(r, ctx->out) == NGX_ERROR) { | |
243 return NGX_ERROR; | |
244 } | |
245 | |
246 if (ctx->busy == NULL) { | |
247 ctx->busy = ctx->out; | |
248 | |
249 } else { | |
250 for (tl = ctx->busy; /* void */ ; tl = tl->next) { | |
251 if (tl->next == NULL) { | |
252 tl->next = ctx->out; | |
253 break; | |
254 } | |
255 } | |
256 } | |
257 | |
258 ctx->out = NULL; | |
259 | |
260 while (ctx->busy) { | |
261 if (ngx_hunk_size(ctx->busy->hunk) != 0) { | |
262 break; | |
263 } | |
264 | |
265 if (ctx->busy->hunk->shadow) { | |
266 ctx->busy->hunk->shadow->pos = ctx->busy->hunk->pos; | |
267 } | |
268 | |
269 ctx->busy = ctx->busy->next; | |
270 } | |
71 } | 271 } |
72 | 272 |
73 return NGX_OK; | 273 return NGX_OK; |
74 } | 274 } |
75 | |
76 | |
77 static int ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
78 { | |
79 int rc; | |
80 ngx_chain_t chain; | |
81 ngx_http_ssi_ctx_t *ctx; | |
82 | |
83 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); | |
84 | |
85 if ((ctx == NULL) || (in == NULL && ctx->incoming == NULL)) { | |
86 return next_body_filter(r, NULL); | |
87 } | |
88 | |
89 if (ctx->hunk && | |
90 (((ctx->hunk->type & NGX_HUNK_FILE) | |
91 && (ctx->hunk->file_pos < ctx->hunk->file_last)) | |
92 || ((ctx->hunk->type & NGX_HUNK_IN_MEMORY) | |
93 && (ctx->hunk->pos < ctx->hunk->last)))) | |
94 { | |
95 rc = next_body_filter(r, NULL); | |
96 | |
97 if (rc == NGX_ERROR) { | |
98 return NGX_ERROR; | |
99 } | |
100 | |
101 if (ctx->hunk->shadow) { | |
102 if (ctx->hunk->type & NGX_HUNK_FILE) { | |
103 ctx->hunk->shadow->file_pos = ctx->hunk->file_pos; | |
104 } | |
105 | |
106 if (ctx->hunk->type & NGX_HUNK_IN_MEMORY) { | |
107 ctx->hunk->shadow->pos = ctx->hunk->pos; | |
108 } | |
109 } | |
110 | |
111 if (rc == NGX_AGAIN) { | |
112 return NGX_AGAIN; | |
113 } | |
114 | |
115 | |
116 } | |
117 | |
118 #if 0 | |
119 | |
120 add in to ctx->incoming chain | |
121 | |
122 while (ctx->incoming) { | |
123 rc == ngx_http_ssi_exec(r, ctx); | |
124 | |
125 if (rc != NGX_ERROR) { | |
126 return rc; | |
127 } | |
128 | |
129 ctx->incoming = ctx->incoming->next; | |
130 } | |
131 | |
132 #endif | |
133 | |
134 return NGX_OK; | |
135 } | |
136 | |
137 | |
138 #if 0 | |
139 | |
140 | |
141 while (ctx->incoming) { | |
142 rc = ngx_http_ssi_parse(r, ctx, ctx->incoming->hunk); | |
143 | |
144 if (rc == NGX_ERROR) { | |
145 return rc; | |
146 } | |
147 | |
148 if (rc == NGX_OK) { | |
149 ngx_test_null(temp, ngx_calloc_hunk(r->pool), NGX_ERROR); | |
150 temp->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
151 temp->pos = comment_string; | |
152 temp->last = comment_string + looked; | |
153 } | |
154 | |
155 if (rc == NGX_HTTP_SSI_DONE) { | |
156 | |
157 | |
158 - looked | |
159 | |
160 chain.hunk = ctx->incoming->hunk; | |
161 chain.next = NULL; | |
162 | |
163 rc = next_body_filter(r, &chain); | |
164 | |
165 if (rc != NGX_OK) { | |
166 ctx->incoming = ctx->incoming->next; | |
167 return rc; | |
168 } | |
169 | |
170 } else if (rc == NGX_HTTP_SSI_INVALID_COMMAND) { | |
171 } else if (rc == NGX_HTTP_SSI_INVALID_PARAM) { | |
172 } else if (rc == NGX_HTTP_SSI_INVALID_VALUE) { | |
173 } else if (rc == NGX_HTTP_SSI_LONG_VALUE) { | |
174 } | |
175 | |
176 ctx->incoming = ctx->incoming->next; | |
177 } | |
178 | |
179 #endif | |
180 | |
181 | |
182 | |
183 | 275 |
184 | 276 |
185 #if 0 | 277 #if 0 |
186 | 278 |
187 static int ngx_http_ssi_copy_opcode(ngx_http_request_t *r, | 279 static int ngx_http_ssi_copy_opcode(ngx_http_request_t *r, |
243 } | 335 } |
244 | 336 |
245 #endif | 337 #endif |
246 | 338 |
247 | 339 |
248 | 340 static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r, |
249 static int ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, | 341 ngx_http_ssi_ctx_t *ctx) |
250 ngx_hunk_t *h) | |
251 { | 342 { |
252 int looked; | 343 char *p, *last, *end, ch; |
253 char *p, ch; | |
254 ngx_hunk_t *temp; | |
255 ngx_chain_t chain; | |
256 | 344 |
257 enum { | 345 enum { |
258 ssi_start_state = 0, | 346 ssi_start_state = 0, |
259 ssi_tag_state, | 347 ssi_tag_state, |
260 ssi_comment0_state, | 348 ssi_comment0_state, |
273 ssi_comment_end0_state, | 361 ssi_comment_end0_state, |
274 ssi_comment_end1_state | 362 ssi_comment_end1_state |
275 } state; | 363 } state; |
276 | 364 |
277 | 365 |
278 looked = ctx->looked; | |
279 state = ctx->state; | 366 state = ctx->state; |
367 last = ctx->last; | |
280 p = ctx->pos; | 368 p = ctx->pos; |
281 | 369 end = ctx->buf->last; |
282 while (p < h->last) { | 370 |
371 while (p < end) { | |
283 ch = *p++; | 372 ch = *p++; |
284 | 373 |
285 switch (state) { | 374 switch (state) { |
286 | 375 |
287 case ssi_start_state: | 376 case ssi_start_state: |
288 | 377 |
289 if (ctx->new_hunk) { | 378 last = NULL; |
290 | 379 |
291 if (looked) { | 380 /* a tight loop */ |
292 ngx_test_null(temp, ngx_calloc_hunk(r->pool), NGX_ERROR); | |
293 temp->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
294 temp->pos = comment_string; | |
295 temp->last = comment_string + looked; | |
296 | |
297 chain.hunk = temp; | |
298 chain.next = NULL; | |
299 | |
300 if (next_body_filter(r, &chain) == NGX_ERROR) { | |
301 return NGX_ERROR; | |
302 } | |
303 } | |
304 | |
305 ctx->new_hunk = 0; | |
306 } | |
307 | |
308 /* tight loop */ | |
309 for ( ;; ) { | 381 for ( ;; ) { |
310 | 382 |
311 if (ch == '<') { | 383 if (ch == '<') { |
312 state = ssi_tag_state; | 384 state = ssi_tag_state; |
313 looked = 1; | 385 last = p - 1; |
314 break; | 386 break; |
315 } | 387 } |
316 | 388 |
317 if (p < h->last) { | 389 if (p == end) { |
318 ctx->state = ssi_start_state; | 390 ctx->state = ssi_start_state; |
319 ctx->looked = 0; | 391 ctx->last = p; |
320 ctx->pos = p; | 392 ctx->pos = p; |
321 return NGX_HTTP_SSI_DONE; | 393 |
394 return NGX_HTTP_SSI_COPY; | |
322 } | 395 } |
323 | 396 |
324 ch = *p++; | 397 ch = *p++; |
325 } | 398 } |
326 | 399 |
328 | 401 |
329 case ssi_tag_state: | 402 case ssi_tag_state: |
330 switch (ch) { | 403 switch (ch) { |
331 case '!': | 404 case '!': |
332 state = ssi_comment0_state; | 405 state = ssi_comment0_state; |
333 looked = 2; | |
334 break; | 406 break; |
335 | 407 |
336 case '<': | 408 case '<': |
409 last = p - 1; | |
337 break; | 410 break; |
338 | 411 |
339 default: | 412 default: |
340 state = ssi_start_state; | 413 state = ssi_start_state; |
341 looked = 0; | |
342 break; | 414 break; |
343 } | 415 } |
344 | 416 |
345 break; | 417 break; |
346 | 418 |
347 case ssi_comment0_state: | 419 case ssi_comment0_state: |
348 switch (ch) { | 420 switch (ch) { |
349 case '-': | 421 case '-': |
350 state = ssi_comment1_state; | 422 state = ssi_comment1_state; |
351 looked = 3; | |
352 break; | 423 break; |
353 | 424 |
354 case '<': | 425 case '<': |
426 last = p - 1; | |
355 state = ssi_tag_state; | 427 state = ssi_tag_state; |
356 looked = 1; | |
357 break; | 428 break; |
358 | 429 |
359 default: | 430 default: |
360 state = ssi_start_state; | 431 state = ssi_start_state; |
361 looked = 0; | |
362 break; | 432 break; |
363 } | 433 } |
364 | 434 |
365 break; | 435 break; |
366 | 436 |
367 case ssi_comment1_state: | 437 case ssi_comment1_state: |
368 switch (ch) { | 438 switch (ch) { |
369 case '-': | 439 case '-': |
370 state = ssi_sharp_state; | 440 state = ssi_sharp_state; |
371 looked = 4; | |
372 break; | 441 break; |
373 | 442 |
374 case '<': | 443 case '<': |
444 last = p - 1; | |
375 state = ssi_tag_state; | 445 state = ssi_tag_state; |
376 looked = 1; | |
377 break; | 446 break; |
378 | 447 |
379 default: | 448 default: |
380 state = ssi_start_state; | 449 state = ssi_start_state; |
381 looked = 0; | |
382 break; | 450 break; |
383 } | 451 } |
384 | 452 |
385 break; | 453 break; |
386 | 454 |
387 case ssi_sharp_state: | 455 case ssi_sharp_state: |
388 switch (ch) { | 456 switch (ch) { |
389 case '#': | 457 case '#': |
390 state = ssi_precommand_state; | 458 ctx->state = ssi_precommand_state; |
391 looked = 0; | 459 ctx->last = last; |
392 break; | 460 ctx->pos = p; |
461 | |
462 return NGX_HTTP_SSI_COPY; | |
393 | 463 |
394 case '<': | 464 case '<': |
465 last = p - 1; | |
395 state = ssi_tag_state; | 466 state = ssi_tag_state; |
396 looked = 1; | |
397 break; | 467 break; |
398 | 468 |
399 default: | 469 default: |
400 state = ssi_start_state; | 470 state = ssi_start_state; |
401 looked = 0; | |
402 break; | 471 break; |
403 } | 472 } |
404 | 473 |
405 break; | 474 break; |
406 | 475 |
411 case LF: | 480 case LF: |
412 case '\t': | 481 case '\t': |
413 break; | 482 break; |
414 | 483 |
415 default: | 484 default: |
416 ngx_test_null(ctx->command.data, | 485 ctx->command.data = |
417 ngx_palloc(r->pool, NGX_HTTP_SSI_COMMAND_LEN + 1), | 486 ngx_palloc(r->pool, NGX_HTTP_SSI_COMMAND_LEN + 1); |
418 NGX_ERROR); | 487 if (ctx->command.data == NULL) { |
488 return NGX_ERROR; | |
489 } | |
490 | |
419 ctx->command.data[0] = ch; | 491 ctx->command.data[0] = ch; |
420 ctx->command.len = 1; | 492 ctx->command.len = 1; |
421 state = ssi_command_state; | 493 state = ssi_command_state; |
422 break; | 494 break; |
423 } | 495 } |
460 case '-': | 532 case '-': |
461 state = ssi_comment_end0_state; | 533 state = ssi_comment_end0_state; |
462 break; | 534 break; |
463 | 535 |
464 default: | 536 default: |
465 ngx_test_null(ctx->param, ngx_push_array(&ctx->params), | 537 if (!(ctx->param = ngx_push_array(&ctx->params))) { |
466 NGX_ERROR); | 538 return NGX_ERROR; |
467 | 539 } |
468 ngx_test_null(ctx->param->key.data, | 540 |
469 ngx_palloc(r->pool, NGX_HTTP_SSI_PARAM_LEN + 1), | 541 ctx->param->key.data = |
470 NGX_ERROR); | 542 ngx_palloc(r->pool, NGX_HTTP_SSI_PARAM_LEN + 1); |
543 if (ctx->param->key.data == NULL) { | |
544 return NGX_ERROR; | |
545 } | |
471 ctx->param->key.data[0] = ch; | 546 ctx->param->key.data[0] = ch; |
472 ctx->param->key.len = 1; | 547 ctx->param->key.len = 1; |
473 | 548 |
474 ngx_test_null(ctx->param->value.data, | 549 ctx->param->value.data = |
475 ngx_palloc(r->pool, ctx->value_len + 1), | 550 ngx_palloc(r->pool, ctx->value_len + 1); |
476 NGX_ERROR); | 551 if (ctx->param->value.data == NULL) { |
552 return NGX_ERROR; | |
553 } | |
477 ctx->param->value.len = 0; | 554 ctx->param->value.len = 0; |
478 | 555 |
479 state = ssi_param_state; | 556 state = ssi_param_state; |
480 break; | 557 break; |
481 } | 558 } |
621 | 698 |
622 case ssi_comment_end1_state: | 699 case ssi_comment_end1_state: |
623 switch (ch) { | 700 switch (ch) { |
624 case '>': | 701 case '>': |
625 ctx->state = ssi_start_state; | 702 ctx->state = ssi_start_state; |
703 ctx->start = p; | |
626 ctx->pos = p; | 704 ctx->pos = p; |
627 return NGX_OK; | 705 return NGX_OK; |
628 | 706 |
629 default: | 707 default: |
630 return NGX_HTTP_SSI_INVALID_COMMAND; | 708 return NGX_HTTP_SSI_INVALID_COMMAND; |
633 break; | 711 break; |
634 } | 712 } |
635 } | 713 } |
636 | 714 |
637 ctx->state = state; | 715 ctx->state = state; |
638 ctx->looked = looked; | 716 ctx->last = last; |
639 ctx->pos = p; | 717 ctx->pos = p; |
640 | 718 |
641 return NGX_HTTP_SSI_DONE; | 719 return NGX_HTTP_SSI_COPY; |
720 } | |
721 | |
722 | |
723 static void *ngx_http_ssi_create_conf(ngx_conf_t *cf) | |
724 { | |
725 ngx_http_ssi_conf_t *conf; | |
726 | |
727 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_conf_t)))) { | |
728 return NGX_CONF_ERROR; | |
729 } | |
730 | |
731 conf->enable = NGX_CONF_UNSET; | |
732 | |
733 return conf; | |
734 } | |
735 | |
736 | |
737 static char *ngx_http_ssi_merge_conf(ngx_conf_t *cf, | |
738 void *parent, void *child) | |
739 { | |
740 ngx_http_ssi_conf_t *prev = parent; | |
741 ngx_http_ssi_conf_t *conf = child; | |
742 | |
743 ngx_conf_merge_value(conf->enable, prev->enable, 0); | |
744 | |
745 return NGX_CONF_OK; | |
642 } | 746 } |
643 | 747 |
644 | 748 |
645 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle) | 749 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle) |
646 { | 750 { |
647 next_header_filter = ngx_http_top_header_filter; | 751 ngx_http_next_header_filter = ngx_http_top_header_filter; |
648 ngx_http_top_header_filter = ngx_http_ssi_header_filter; | 752 ngx_http_top_header_filter = ngx_http_ssi_header_filter; |
649 | 753 |
650 next_body_filter = ngx_http_top_body_filter; | 754 ngx_http_next_body_filter = ngx_http_top_body_filter; |
651 ngx_http_top_body_filter = ngx_http_ssi_body_filter; | 755 ngx_http_top_body_filter = ngx_http_ssi_body_filter; |
652 | 756 |
653 return NGX_OK; | 757 return NGX_OK; |
654 } | 758 } |