comparison src/http/modules/ngx_http_sub_filter_module.c @ 584:016632f0fb18 NGINX_0_8_44

nginx 0.8.44 *) Change: now nginx does not cache by default backend responses, if they have a "Set-Cookie" header line. *) Feature: the "listen" directive supports the "setfib" parameter. Thanks to Andrew Filonov. *) Bugfix: the "sub_filter" directive might change character case on partial match. *) Bugfix: compatibility with HP/UX. *) Bugfix: compatibility with AIX xcl_r compiler. *) Bugfix: nginx treated a large SSLv2 packets as plain requests. Thanks to Miroslaw Jaworski.
author Igor Sysoev <http://sysoev.ru>
date Mon, 05 Jul 2010 00:00:00 +0400
parents c456a023113c
children
comparison
equal deleted inserted replaced
583:39e50617266a 584:016632f0fb18
27 } ngx_http_sub_state_e; 27 } ngx_http_sub_state_e;
28 28
29 29
30 typedef struct { 30 typedef struct {
31 ngx_str_t match; 31 ngx_str_t match;
32 ngx_str_t saved;
33 ngx_str_t looked;
32 34
33 ngx_uint_t once; /* unsigned once:1 */ 35 ngx_uint_t once; /* unsigned once:1 */
34 36
35 ngx_buf_t *buf; 37 ngx_buf_t *buf;
36 38
45 ngx_chain_t *free; 47 ngx_chain_t *free;
46 48
47 ngx_str_t sub; 49 ngx_str_t sub;
48 50
49 ngx_uint_t state; 51 ngx_uint_t state;
50 size_t saved;
51 size_t looked;
52 } ngx_http_sub_ctx_t; 52 } ngx_http_sub_ctx_t;
53 53
54 54
55 static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r, 55 static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r,
56 ngx_http_sub_ctx_t *ctx); 56 ngx_http_sub_ctx_t *ctx);
145 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); 145 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
146 if (ctx == NULL) { 146 if (ctx == NULL) {
147 return NGX_ERROR; 147 return NGX_ERROR;
148 } 148 }
149 149
150 ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len);
151 if (ctx->saved.data == NULL) {
152 return NGX_ERROR;
153 }
154
155 ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len);
156 if (ctx->looked.data == NULL) {
157 return NGX_ERROR;
158 }
159
150 ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); 160 ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
151 161
152 ctx->match = slcf->match; 162 ctx->match = slcf->match;
153 ctx->last_out = &ctx->out; 163 ctx->last_out = &ctx->out;
154 164
224 b = NULL; 234 b = NULL;
225 235
226 while (ctx->pos < ctx->buf->last) { 236 while (ctx->pos < ctx->buf->last) {
227 237
228 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 238 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
229 "saved: %d state: %d", ctx->saved, ctx->state); 239 "saved: \"%V\" state: %d", &ctx->saved, ctx->state);
230 240
231 rc = ngx_http_sub_parse(r, ctx); 241 rc = ngx_http_sub_parse(r, ctx);
232 242
233 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 243 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
234 "parse: %d, looked: %d %p-%p", 244 "parse: %d, looked: \"%V\" %p-%p",
235 rc, ctx->looked, ctx->copy_start, ctx->copy_end); 245 rc, &ctx->looked, ctx->copy_start, ctx->copy_end);
236 246
237 if (rc == NGX_ERROR) { 247 if (rc == NGX_ERROR) {
238 return rc; 248 return rc;
239 } 249 }
240 250
241 if (ctx->copy_start != ctx->copy_end) { 251 if (ctx->copy_start != ctx->copy_end) {
242 252
243 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 253 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
244 "saved: %d", ctx->saved); 254 "saved: \"%V\"", &ctx->saved);
245 255
246 if (ctx->saved) { 256 if (ctx->saved.len) {
247 257
248 if (ctx->free) { 258 if (ctx->free) {
249 cl = ctx->free; 259 cl = ctx->free;
250 ctx->free = ctx->free->next; 260 ctx->free = ctx->free->next;
251 b = cl->buf; 261 b = cl->buf;
263 } 273 }
264 274
265 cl->buf = b; 275 cl->buf = b;
266 } 276 }
267 277
278 b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
279 if (b->pos == NULL) {
280 return NGX_ERROR;
281 }
282
283 ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
284 b->last = b->pos + ctx->saved.len;
268 b->memory = 1; 285 b->memory = 1;
269 b->pos = ctx->match.data;
270 b->last = ctx->match.data + ctx->saved;
271 286
272 *ctx->last_out = cl; 287 *ctx->last_out = cl;
273 ctx->last_out = &cl->next; 288 ctx->last_out = &cl->next;
274 289
275 ctx->saved = 0; 290 ctx->saved.len = 0;
276 } 291 }
277 292
278 if (ctx->free) { 293 if (ctx->free) {
279 cl = ctx->free; 294 cl = ctx->free;
280 ctx->free = ctx->free->next; 295 ctx->free = ctx->free->next;
403 b->recycled = ctx->buf->recycled; 418 b->recycled = ctx->buf->recycled;
404 } 419 }
405 420
406 ctx->buf = NULL; 421 ctx->buf = NULL;
407 422
408 ctx->saved = ctx->looked; 423 ctx->saved.len = ctx->looked.len;
424 ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->looked.len);
409 } 425 }
410 426
411 if (ctx->out == NULL && ctx->busy == NULL) { 427 if (ctx->out == NULL && ctx->busy == NULL) {
412 return NGX_OK; 428 return NGX_OK;
413 } 429 }
494 510
495 if (ctx->once) { 511 if (ctx->once) {
496 ctx->copy_start = ctx->pos; 512 ctx->copy_start = ctx->pos;
497 ctx->copy_end = ctx->buf->last; 513 ctx->copy_end = ctx->buf->last;
498 ctx->pos = ctx->buf->last; 514 ctx->pos = ctx->buf->last;
499 ctx->looked = 0; 515 ctx->looked.len = 0;
500 516
501 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once"); 517 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once");
502 518
503 return NGX_AGAIN; 519 return NGX_AGAIN;
504 } 520 }
505 521
506 state = ctx->state; 522 state = ctx->state;
507 looked = ctx->looked; 523 looked = ctx->looked.len;
508 last = ctx->buf->last; 524 last = ctx->buf->last;
509 copy_end = ctx->copy_end; 525 copy_end = ctx->copy_end;
510 526
511 for (p = ctx->pos; p < last; p++) { 527 for (p = ctx->pos; p < last; p++) {
512 528
520 match = ctx->match.data[0]; 536 match = ctx->match.data[0];
521 537
522 for ( ;; ) { 538 for ( ;; ) {
523 if (ch == match) { 539 if (ch == match) {
524 copy_end = p; 540 copy_end = p;
541 ctx->looked.data[0] = *p;
525 looked = 1; 542 looked = 1;
526 state = sub_match_state; 543 state = sub_match_state;
527 544
528 goto match_started; 545 goto match_started;
529 } 546 }
536 ch = ngx_tolower(ch); 553 ch = ngx_tolower(ch);
537 } 554 }
538 555
539 ctx->state = state; 556 ctx->state = state;
540 ctx->pos = p; 557 ctx->pos = p;
541 ctx->looked = looked; 558 ctx->looked.len = looked;
542 ctx->copy_end = p; 559 ctx->copy_end = p;
543 560
544 if (ctx->copy_start == NULL) { 561 if (ctx->copy_start == NULL) {
545 ctx->copy_start = ctx->buf->pos; 562 ctx->copy_start = ctx->buf->pos;
546 } 563 }
553 } 570 }
554 571
555 /* state == sub_match_state */ 572 /* state == sub_match_state */
556 573
557 if (ch == ctx->match.data[looked]) { 574 if (ch == ctx->match.data[looked]) {
575 ctx->looked.data[looked] = *p;
558 looked++; 576 looked++;
559 577
560 if (looked == ctx->match.len) { 578 if (looked == ctx->match.len) {
561 if ((size_t) (p - ctx->pos) < looked) { 579 if ((size_t) (p - ctx->pos) < looked) {
562 ctx->saved = 0; 580 ctx->saved.len = 0;
563 } 581 }
564 582
565 ctx->state = sub_start_state; 583 ctx->state = sub_start_state;
566 ctx->pos = p + 1; 584 ctx->pos = p + 1;
567 ctx->looked = 0; 585 ctx->looked.len = 0;
568 ctx->copy_end = copy_end; 586 ctx->copy_end = copy_end;
569 587
570 if (ctx->copy_start == NULL && copy_end) { 588 if (ctx->copy_start == NULL && copy_end) {
571 ctx->copy_start = ctx->buf->pos; 589 ctx->copy_start = ctx->buf->pos;
572 } 590 }
574 return NGX_OK; 592 return NGX_OK;
575 } 593 }
576 594
577 } else if (ch == ctx->match.data[0]) { 595 } else if (ch == ctx->match.data[0]) {
578 copy_end = p; 596 copy_end = p;
597 ctx->looked.data[0] = *p;
579 looked = 1; 598 looked = 1;
580 599
581 } else { 600 } else {
582 copy_end = p; 601 copy_end = p;
583 looked = 0; 602 looked = 0;
585 } 604 }
586 } 605 }
587 606
588 ctx->state = state; 607 ctx->state = state;
589 ctx->pos = p; 608 ctx->pos = p;
590 ctx->looked = looked; 609 ctx->looked.len = looked;
591 610
592 ctx->copy_end = (state == sub_start_state) ? p : copy_end; 611 ctx->copy_end = (state == sub_start_state) ? p : copy_end;
593 612
594 if (ctx->copy_start == NULL && ctx->copy_end) { 613 if (ctx->copy_start == NULL && ctx->copy_end) {
595 ctx->copy_start = ctx->buf->pos; 614 ctx->copy_start = ctx->buf->pos;