Mercurial > hg > nginx-mail
comparison src/http/modules/ngx_http_rewrite_module.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | 4d3e880ce86c |
children |
comparison
equal
deleted
inserted
replaced
572:06419a2298a9 | 665:0b460e61bdcd |
---|---|
50 0, | 50 0, |
51 NULL }, | 51 NULL }, |
52 | 52 |
53 { ngx_string("return"), | 53 { ngx_string("return"), |
54 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 54 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
55 |NGX_CONF_TAKE1, | 55 |NGX_CONF_TAKE12, |
56 ngx_http_rewrite_return, | 56 ngx_http_rewrite_return, |
57 NGX_HTTP_LOC_CONF_OFFSET, | 57 NGX_HTTP_LOC_CONF_OFFSET, |
58 0, | 58 0, |
59 NULL }, | 59 NULL }, |
60 | 60 |
292 static char * | 292 static char * |
293 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 293 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
294 { | 294 { |
295 ngx_http_rewrite_loc_conf_t *lcf = conf; | 295 ngx_http_rewrite_loc_conf_t *lcf = conf; |
296 | 296 |
297 ngx_str_t *value, err; | 297 ngx_str_t *value; |
298 ngx_int_t n; | |
299 ngx_uint_t last; | 298 ngx_uint_t last; |
299 ngx_regex_compile_t rc; | |
300 ngx_http_script_code_pt *code; | 300 ngx_http_script_code_pt *code; |
301 ngx_http_script_compile_t sc; | 301 ngx_http_script_compile_t sc; |
302 ngx_http_script_regex_code_t *regex; | 302 ngx_http_script_regex_code_t *regex; |
303 ngx_http_script_regex_end_code_t *regex_end; | 303 ngx_http_script_regex_end_code_t *regex_end; |
304 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 304 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
311 | 311 |
312 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); | 312 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
313 | 313 |
314 value = cf->args->elts; | 314 value = cf->args->elts; |
315 | 315 |
316 err.len = NGX_MAX_CONF_ERRSTR; | 316 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
317 err.data = errstr; | 317 |
318 rc.pattern = value[1]; | |
319 rc.err.len = NGX_MAX_CONF_ERRSTR; | |
320 rc.err.data = errstr; | |
318 | 321 |
319 /* TODO: NGX_REGEX_CASELESS */ | 322 /* TODO: NGX_REGEX_CASELESS */ |
320 | 323 |
321 regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | 324 regex->regex = ngx_http_regex_compile(cf, &rc); |
322 | |
323 if (regex->regex == NULL) { | 325 if (regex->regex == NULL) { |
324 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
325 return NGX_CONF_ERROR; | 326 return NGX_CONF_ERROR; |
326 } | 327 } |
327 | 328 |
328 regex->code = ngx_http_script_regex_start_code; | 329 regex->code = ngx_http_script_regex_start_code; |
329 regex->uri = 1; | 330 regex->uri = 1; |
338 regex->add_args = 1; | 339 regex->add_args = 1; |
339 } | 340 } |
340 | 341 |
341 last = 0; | 342 last = 0; |
342 | 343 |
343 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { | 344 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0 |
344 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | 345 || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0 |
345 regex->redirect = 1; | 346 || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0) |
346 last = 1; | 347 { |
347 } | |
348 | |
349 if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) { | |
350 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | 348 regex->status = NGX_HTTP_MOVED_TEMPORARILY; |
351 regex->redirect = 1; | 349 regex->redirect = 1; |
352 last = 1; | 350 last = 1; |
353 } | 351 } |
354 | 352 |
392 return NGX_CONF_ERROR; | 390 return NGX_CONF_ERROR; |
393 } | 391 } |
394 | 392 |
395 regex = sc.main; | 393 regex = sc.main; |
396 | 394 |
397 regex->ncaptures = sc.ncaptures; | |
398 regex->size = sc.size; | 395 regex->size = sc.size; |
399 regex->args = sc.args; | 396 regex->args = sc.args; |
400 | 397 |
401 if (sc.variables == 0 && !sc.dup_capture) { | 398 if (sc.variables == 0 && !sc.dup_capture) { |
402 regex->lengths = NULL; | 399 regex->lengths = NULL; |
403 } | |
404 | |
405 n = ngx_regex_capture_count(regex->regex); | |
406 | |
407 if (n < 0) { | |
408 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
409 ngx_regex_capture_count_n " failed for " | |
410 "pattern \"%V\"", &value[1]); | |
411 return NGX_CONF_ERROR; | |
412 } | |
413 | |
414 if (regex->ncaptures > (ngx_uint_t) n) { | |
415 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
416 "pattern \"%V\" has less captures " | |
417 "than referrenced in substitution \"%V\"", | |
418 &value[1], &value[2]); | |
419 return NGX_CONF_ERROR; | |
420 } | |
421 | |
422 if (regex->ncaptures < (ngx_uint_t) n) { | |
423 regex->ncaptures = (ngx_uint_t) n; | |
424 } | |
425 | |
426 if (regex->ncaptures) { | |
427 regex->ncaptures = (regex->ncaptures + 1) * 3; | |
428 } | 400 } |
429 | 401 |
430 regex_end = ngx_http_script_add_code(lcf->codes, | 402 regex_end = ngx_http_script_add_code(lcf->codes, |
431 sizeof(ngx_http_script_regex_end_code_t), | 403 sizeof(ngx_http_script_regex_end_code_t), |
432 ®ex); | 404 ®ex); |
444 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), ®ex); | 416 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), ®ex); |
445 if (code == NULL) { | 417 if (code == NULL) { |
446 return NGX_CONF_ERROR; | 418 return NGX_CONF_ERROR; |
447 } | 419 } |
448 | 420 |
449 *code = (uintptr_t) NULL; | 421 *code = NULL; |
450 } | 422 } |
451 | 423 |
452 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | 424 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts |
453 - (u_char *) regex; | 425 - (u_char *) regex; |
454 | 426 |
459 static char * | 431 static char * |
460 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 432 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
461 { | 433 { |
462 ngx_http_rewrite_loc_conf_t *lcf = conf; | 434 ngx_http_rewrite_loc_conf_t *lcf = conf; |
463 | 435 |
464 ngx_str_t *value; | 436 u_char *p; |
465 ngx_http_script_return_code_t *ret; | 437 ngx_str_t *value, *v; |
438 ngx_http_script_return_code_t *ret; | |
439 ngx_http_compile_complex_value_t ccv; | |
466 | 440 |
467 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, | 441 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, |
468 sizeof(ngx_http_script_return_code_t)); | 442 sizeof(ngx_http_script_return_code_t)); |
469 if (ret == NULL) { | 443 if (ret == NULL) { |
470 return NGX_CONF_ERROR; | 444 return NGX_CONF_ERROR; |
471 } | 445 } |
472 | 446 |
473 value = cf->args->elts; | 447 value = cf->args->elts; |
474 | 448 |
449 ngx_memzero(ret, sizeof(ngx_http_script_return_code_t)); | |
450 | |
475 ret->code = ngx_http_script_return_code; | 451 ret->code = ngx_http_script_return_code; |
476 ret->null = (uintptr_t) NULL; | 452 |
477 | 453 p = value[1].data; |
478 ret->status = ngx_atoi(value[1].data, value[1].len); | 454 |
455 ret->status = ngx_atoi(p, value[1].len); | |
479 | 456 |
480 if (ret->status == (uintptr_t) NGX_ERROR) { | 457 if (ret->status == (uintptr_t) NGX_ERROR) { |
458 | |
459 if (cf->args->nelts == 2 | |
460 && (ngx_strncmp(p, "http://", sizeof("http://") - 1) == 0 | |
461 || ngx_strncmp(p, "https://", sizeof("https://") - 1) == 0 | |
462 || ngx_strncmp(p, "$scheme", sizeof("$scheme") - 1) == 0)) | |
463 { | |
464 ret->status = NGX_HTTP_MOVED_TEMPORARILY; | |
465 v = &value[1]; | |
466 | |
467 } else { | |
468 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
469 "invalid return code \"%V\"", &value[1]); | |
470 return NGX_CONF_ERROR; | |
471 } | |
472 | |
473 } else { | |
474 | |
475 if (cf->args->nelts == 2) { | |
476 return NGX_CONF_OK; | |
477 } | |
478 | |
479 v = &value[2]; | |
480 } | |
481 | |
482 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
483 | |
484 ccv.cf = cf; | |
485 ccv.value = v; | |
486 ccv.complex_value = &ret->text; | |
487 | |
488 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
481 return NGX_CONF_ERROR; | 489 return NGX_CONF_ERROR; |
482 } | 490 } |
483 | 491 |
484 return NGX_CONF_OK; | 492 return NGX_CONF_OK; |
485 } | 493 } |
622 static char * | 630 static char * |
623 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) | 631 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) |
624 { | 632 { |
625 u_char *p; | 633 u_char *p; |
626 size_t len; | 634 size_t len; |
627 ngx_str_t *value, err; | 635 ngx_str_t *value; |
628 ngx_uint_t cur, last, n; | 636 ngx_uint_t cur, last; |
637 ngx_regex_compile_t rc; | |
629 ngx_http_script_code_pt *code; | 638 ngx_http_script_code_pt *code; |
630 ngx_http_script_file_code_t *fop; | 639 ngx_http_script_file_code_t *fop; |
631 ngx_http_script_regex_code_t *regex; | 640 ngx_http_script_regex_code_t *regex; |
632 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 641 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
633 | 642 |
731 return NGX_CONF_ERROR; | 740 return NGX_CONF_ERROR; |
732 } | 741 } |
733 | 742 |
734 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); | 743 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
735 | 744 |
736 err.len = NGX_MAX_CONF_ERRSTR; | 745 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
737 err.data = errstr; | 746 |
738 | 747 rc.pattern = value[last]; |
739 regex->regex = ngx_regex_compile(&value[last], | 748 rc.options = (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0; |
740 (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0, | 749 rc.err.len = NGX_MAX_CONF_ERRSTR; |
741 cf->pool, &err); | 750 rc.err.data = errstr; |
742 | 751 |
752 regex->regex = ngx_http_regex_compile(cf, &rc); | |
743 if (regex->regex == NULL) { | 753 if (regex->regex == NULL) { |
744 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
745 return NGX_CONF_ERROR; | 754 return NGX_CONF_ERROR; |
746 } | 755 } |
747 | 756 |
748 regex->code = ngx_http_script_regex_start_code; | 757 regex->code = ngx_http_script_regex_start_code; |
749 regex->next = sizeof(ngx_http_script_regex_code_t); | 758 regex->next = sizeof(ngx_http_script_regex_code_t); |
750 regex->test = 1; | 759 regex->test = 1; |
751 if (p[0] == '!') { | 760 if (p[0] == '!') { |
752 regex->negative_test = 1; | 761 regex->negative_test = 1; |
753 } | 762 } |
754 regex->name = value[last]; | 763 regex->name = value[last]; |
755 | |
756 n = ngx_regex_capture_count(regex->regex); | |
757 | |
758 if (n) { | |
759 regex->ncaptures = (n + 1) * 3; | |
760 } | |
761 | 764 |
762 return NGX_CONF_OK; | 765 return NGX_CONF_OK; |
763 } | 766 } |
764 | 767 |
765 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 768 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |