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;