Mercurial > hg > nginx
comparison src/http/modules/ngx_http_ssi_filter.c @ 128:1947c683490f
nginx-0.0.1-2003-08-08-19:13:24 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 08 Aug 2003 15:13:24 +0000 |
parents | 4cbe22f9907f |
children | 7a886b9a67dc |
comparison
equal
deleted
inserted
replaced
127:4cbe22f9907f | 128:1947c683490f |
---|---|
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | 5 |
6 | 6 |
7 #define NGX_HTTP_SSI_COMMAND_LEN 31 | |
8 #define NGX_HTTP_SSI_PARAM_LEN 31 | |
9 | |
10 #define NGX_HTTP_SSI_DONE 1 | |
11 #define NGX_HTTP_SSI_INVALID_COMMAND 2 | |
12 #define NGX_HTTP_SSI_INVALID_PARAM 3 | |
13 #define NGX_HTTP_SSI_INVALID_VALUE 4 | |
14 #define NGX_HTTP_SSI_LONG_VALUE 5 | |
15 | |
16 | |
7 typedef struct { | 17 typedef struct { |
8 } ngx_http_ssi_filter_ctx_t; | 18 ngx_table_elt_t *param; |
19 ngx_str_t command; | |
20 ngx_array_t params; | |
21 int state; | |
22 int looked; | |
23 char *pos; | |
24 ngx_chain_t *out; | |
25 int new_hunk; | |
26 u_int value_len; | |
27 } ngx_http_ssi_ctx_t; | |
9 | 28 |
10 | 29 |
11 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle); | 30 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle); |
12 | 31 |
13 | 32 |
35 | 54 |
36 static int (*next_header_filter) (ngx_http_request_t *r); | 55 static int (*next_header_filter) (ngx_http_request_t *r); |
37 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); | 56 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch); |
38 | 57 |
39 | 58 |
40 static comment_string = "<!--"; | 59 |
60 static char comment_string[] = "<!--"; | |
41 | 61 |
42 | 62 |
43 static int ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 63 static int ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
44 { | 64 { |
45 | 65 ngx_chain_t chain; |
66 ngx_http_ssi_ctx_t *ctx; | |
67 | |
68 ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); | |
69 | |
70 if (ctx == NULL) { | |
71 ngx_http_create_ctx(r, ctx, ngx_http_ssi_filter_module, | |
72 sizeof(ngx_http_ssi_ctx_t), NGX_ERROR); | |
73 } | |
74 | |
75 if (in == NULL && ctx->out == NULL) { | |
76 return next_body_filter(r, NULL); | |
77 } | |
78 | |
79 #if 0 | |
80 | |
81 add in to ctx->out chain | |
82 | |
83 while (ctx->out) { | |
84 rc = ngx_http_ssi_parse(r, ctx, ctx->out->hunk); | |
85 | |
86 if (rc == NGX_HTTP_SSI_DONE) { | |
87 chain.hunk = ctx->out->hunk; | |
88 chain.next = NULL; | |
89 | |
90 rc = next_body_filter(r, &chain); | |
91 if (rc != NGX_OK) { | |
92 return rc; | |
93 } | |
94 } | |
95 | |
96 ctx->out = ctx->out->next; | |
97 } | |
98 | |
99 #endif | |
100 | |
101 return NGX_OK; | |
46 } | 102 } |
47 | 103 |
48 | 104 |
49 | 105 |
50 | 106 |
51 | 107 |
52 | 108 |
53 static int ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, | 109 static int ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, |
54 ngx_hunk_t *h) | 110 ngx_hunk_t *h) |
55 { | 111 { |
56 int looked, state; | 112 int looked; |
57 char *p; | 113 char *p, ch; |
58 ngx_hunk_t *temp; | 114 ngx_hunk_t *temp; |
59 ngx_chain_t chain; | 115 ngx_chain_t chain; |
60 | 116 |
117 enum { | |
118 ssi_start_state = 0, | |
119 ssi_tag_state, | |
120 ssi_comment0_state, | |
121 ssi_comment1_state, | |
122 ssi_sharp_state, | |
123 ssi_precommand_state, | |
124 ssi_command_state, | |
125 ssi_preparam_state, | |
126 ssi_param_state, | |
127 ssi_preequal_state, | |
128 ssi_prevalue_state, | |
129 ssi_double_quoted_value_state, | |
130 ssi_double_quoted_value_quote_state, | |
131 ssi_quoted_value_state, | |
132 ssi_quoted_value_quote_state, | |
133 ssi_comment_end0_state, | |
134 ssi_comment_end1_state | |
135 } state; | |
136 | |
137 | |
61 looked = ctx->looked; | 138 looked = ctx->looked; |
62 state = ctx->state; | 139 state = ctx->state; |
63 p = h->pos; | 140 p = ctx->pos; |
64 | 141 |
65 while (p < h->last) { | 142 while (p < h->last) { |
66 ch = *p++; | 143 ch = *p++; |
67 | 144 |
68 switch (state) { | 145 switch (state) { |
98 } | 175 } |
99 | 176 |
100 if (p < h->last) { | 177 if (p < h->last) { |
101 ctx->state = ssi_start_state; | 178 ctx->state = ssi_start_state; |
102 ctx->looked = 0; | 179 ctx->looked = 0; |
180 ctx->pos = p; | |
103 return NGX_HTTP_SSI_DONE; | 181 return NGX_HTTP_SSI_DONE; |
104 } | 182 } |
105 | 183 |
106 ch = *p++; | 184 ch = *p++; |
107 } | 185 } |
194 case '\t': | 272 case '\t': |
195 break; | 273 break; |
196 | 274 |
197 default: | 275 default: |
198 ngx_test_null(ctx->command.data, | 276 ngx_test_null(ctx->command.data, |
199 ngx_palloc(r->pool, NGX_HTTP_SSI_COMMAND_LEN), | 277 ngx_palloc(r->pool, NGX_HTTP_SSI_COMMAND_LEN + 1), |
200 NGX_ERROR); | 278 NGX_ERROR); |
201 ctx->command.data[0] = ch; | 279 ctx->command.data[0] = ch; |
202 ctx->command.len = 1; | 280 ctx->command.len = 1; |
203 state = ssi_command_state; | 281 state = ssi_command_state; |
204 break; | 282 break; |
214 case '\t': | 292 case '\t': |
215 ctx->command.data[ctx->command.len] = 0; | 293 ctx->command.data[ctx->command.len] = 0; |
216 state = ssi_preparam_state; | 294 state = ssi_preparam_state; |
217 break; | 295 break; |
218 | 296 |
297 case '-': | |
298 ctx->command.data[ctx->command.len] = 0; | |
299 state = ssi_comment_end0_state; | |
300 break; | |
301 | |
219 default: | 302 default: |
220 if (ctx->command.len >= NGX_HTTP_SSI_COMMAND_LEN) { | 303 if (ctx->command.len >= NGX_HTTP_SSI_COMMAND_LEN) { |
221 return NGX_HTTP_SSI_INVALID_COMMAND; | 304 return NGX_HTTP_SSI_INVALID_COMMAND; |
222 } | 305 } |
223 | 306 |
237 case '-': | 320 case '-': |
238 state = ssi_comment_end0_state; | 321 state = ssi_comment_end0_state; |
239 break; | 322 break; |
240 | 323 |
241 default: | 324 default: |
242 ngx_test_null(param, ngx_push_array(&ctx->params), NGX_ERROR); | 325 ngx_test_null(ctx->param, ngx_push_array(&ctx->params), |
243 | |
244 ngx_test_null(param->name.data, | |
245 ngx_palloc(r->pool, NGX_HTTP_SSI_PARAM_LEN), | |
246 NGX_ERROR); | 326 NGX_ERROR); |
247 param->name.data[0] = ch; | 327 |
248 param->name.len = 1; | 328 ngx_test_null(ctx->param->key.data, |
249 | 329 ngx_palloc(r->pool, NGX_HTTP_SSI_PARAM_LEN + 1), |
250 ngx_test_null(param->value.data, | |
251 ngx_palloc(r->pool, NGX_HTTP_SSI_VALUE_LEN), | |
252 NGX_ERROR); | 330 NGX_ERROR); |
253 param->value.len = 0; | 331 ctx->param->key.data[0] = ch; |
332 ctx->param->key.len = 1; | |
333 | |
334 ngx_test_null(ctx->param->value.data, | |
335 ngx_palloc(r->pool, ctx->value_len + 1), | |
336 NGX_ERROR); | |
337 ctx->param->value.len = 0; | |
254 | 338 |
255 state = ssi_param_state; | 339 state = ssi_param_state; |
256 break; | 340 break; |
257 } | 341 } |
258 | 342 |
262 switch (ch) { | 346 switch (ch) { |
263 case ' ': | 347 case ' ': |
264 case CR: | 348 case CR: |
265 case LF: | 349 case LF: |
266 case '\t': | 350 case '\t': |
267 ctx->param.data[ctx->param.len] = 0; | 351 ctx->param->key.data[ctx->param->key.len] = 0; |
268 state = ssi_preequal_state; | 352 state = ssi_preequal_state; |
269 break; | 353 break; |
270 | 354 |
271 case '=': | 355 case '=': |
272 ctx->param.data[ctx->param.len] = 0; | 356 ctx->param->key.data[ctx->param->key.len] = 0; |
273 state = ssi_prevalue_state; | 357 state = ssi_prevalue_state; |
274 break; | 358 break; |
275 | 359 |
276 default: | 360 default: |
277 if (ctx->param.len >= NGX_HTTP_SSI_PARAM_LEN) { | 361 if (ctx->param->key.len >= NGX_HTTP_SSI_PARAM_LEN) { |
278 return NGX_HTTP_SSI_INVALID_PARAM; | 362 return NGX_HTTP_SSI_INVALID_PARAM; |
279 } | 363 } |
280 | 364 |
281 ctx->param.data[ctx->param.len++] = ch; | 365 ctx->param->key.data[ctx->param->key.len++] = ch; |
282 } | 366 } |
283 | 367 |
284 break; | 368 break; |
285 | 369 |
286 case ssi_preequal_state: | 370 case ssi_preequal_state: |
294 case '=': | 378 case '=': |
295 state = ssi_prevalue_state; | 379 state = ssi_prevalue_state; |
296 break; | 380 break; |
297 | 381 |
298 default: | 382 default: |
299 return NGX_HTTP_SSI_PARSE_INVALID_PARAM; | 383 return NGX_HTTP_SSI_INVALID_PARAM; |
300 } | 384 } |
301 | 385 |
302 break; | 386 break; |
303 | 387 |
304 case ssi_prevalue_state: | 388 case ssi_prevalue_state: |
308 case LF: | 392 case LF: |
309 case '\t': | 393 case '\t': |
310 break; | 394 break; |
311 | 395 |
312 case '"': | 396 case '"': |
313 state = ssi_value_state; | 397 state = ssi_double_quoted_value_state; |
314 break; | 398 break; |
315 | 399 |
316 default: | 400 case '\'': |
317 return NGX_HTTP_SSI_PARSE_INVALID_PARAM; | 401 state = ssi_quoted_value_state; |
318 } | 402 break; |
319 | 403 |
320 break; | 404 default: |
321 | 405 return NGX_HTTP_SSI_INVALID_VALUE; |
322 case ssi_value_state: | 406 } |
323 switch (ch) { | 407 |
324 case '\': | 408 break; |
325 state = ssi_quote_state; | 409 |
410 case ssi_double_quoted_value_state: | |
411 switch (ch) { | |
412 case '\\': | |
413 state = ssi_double_quoted_value_quote_state; | |
326 break; | 414 break; |
327 | 415 |
328 case '"': | 416 case '"': |
329 state = ssi_postvalue_state; | 417 state = ssi_preparam_state; |
330 break; | 418 break; |
331 | 419 |
332 default: | 420 default: |
333 return NGX_SSI_PARSE_INVALID_PARAM; | 421 if (ctx->param->value.len >= ctx->value_len) { |
334 } | 422 return NGX_HTTP_SSI_LONG_VALUE; |
335 | 423 } |
336 break; | 424 |
337 | 425 ctx->param->value.data[ctx->param->value.len++] = ch; |
338 case ssi_quote_state: | 426 } |
339 state = ssi_expression_state; | 427 |
340 | 428 break; |
341 break; | 429 |
342 | 430 case ssi_double_quoted_value_quote_state: |
431 if (ctx->param->value.len >= ctx->value_len) { | |
432 return NGX_HTTP_SSI_LONG_VALUE; | |
433 } | |
434 | |
435 ctx->param->value.data[ctx->param->value.len++] = ch; | |
436 | |
437 state = ssi_double_quoted_value_state; | |
438 break; | |
439 | |
440 case ssi_quoted_value_state: | |
441 switch (ch) { | |
442 case '\\': | |
443 state = ssi_quoted_value_quote_state; | |
444 break; | |
445 | |
446 case '\'': | |
447 state = ssi_preparam_state; | |
448 break; | |
449 | |
450 default: | |
451 if (ctx->param->value.len >= ctx->value_len) { | |
452 return NGX_HTTP_SSI_LONG_VALUE; | |
453 } | |
454 | |
455 ctx->param->value.data[ctx->param->value.len++] = ch; | |
456 } | |
457 | |
458 break; | |
459 | |
460 case ssi_quoted_value_quote_state: | |
461 if (ctx->param->value.len >= ctx->value_len) { | |
462 return NGX_HTTP_SSI_LONG_VALUE; | |
463 } | |
464 | |
465 ctx->param->value.data[ctx->param->value.len++] = ch; | |
466 | |
467 state = ssi_quoted_value_state; | |
468 break; | |
469 | |
470 case ssi_comment_end0_state: | |
471 switch (ch) { | |
472 case '-': | |
473 state = ssi_comment_end1_state; | |
474 break; | |
475 | |
476 default: | |
477 return NGX_HTTP_SSI_INVALID_COMMAND; | |
478 } | |
479 | |
480 break; | |
481 | |
482 case ssi_comment_end1_state: | |
483 switch (ch) { | |
484 case '>': | |
485 ctx->state = ssi_start_state; | |
486 ctx->pos = p; | |
487 return NGX_OK; | |
488 | |
489 default: | |
490 return NGX_HTTP_SSI_INVALID_COMMAND; | |
491 } | |
492 | |
493 break; | |
343 } | 494 } |
344 } | 495 } |
345 | 496 |
346 ctx->state = state; | 497 ctx->state = state; |
347 ctx->looked = looked; | 498 ctx->looked = looked; |
499 ctx->pos = p; | |
348 | 500 |
349 return NGX_HTTP_SSI_DONE; | 501 return NGX_HTTP_SSI_DONE; |
350 } | 502 } |
351 | 503 |
352 | 504 |
353 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle) | 505 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle) |
354 { | 506 { |
507 #if 0 | |
355 next_header_filter = ngx_http_top_header_filter; | 508 next_header_filter = ngx_http_top_header_filter; |
356 ngx_http_top_header_filter = ngx_http_ssi_header_filter; | 509 ngx_http_top_header_filter = ngx_http_ssi_header_filter; |
510 #endif | |
357 | 511 |
358 next_body_filter = ngx_http_top_body_filter; | 512 next_body_filter = ngx_http_top_body_filter; |
359 ngx_http_top_body_filter = ngx_http_ssi_body_filter; | 513 ngx_http_top_body_filter = ngx_http_ssi_body_filter; |
360 | 514 |
361 return NGX_OK; | 515 return NGX_OK; |