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 &regex); 404 &regex);
444 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), &regex); 416 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), &regex);
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,