comparison src/http/modules/ngx_http_rewrite_handler.c @ 36:a39d1b793287 NGINX_0_1_18

nginx 0.1.18 *) Workaround: the default values of the devpoll_events and the devpoll_changes directives changed from 512 to 32 to be compatible with Solaris 10. *) Bugfix: the proxy_set_x_var and fastcgi_set_var directives were not inherited. *) Bugfix: in the redirect rewrite directive the arguments were concatenated with URI by the "&" rather than the "?". *) Bugfix: the lines without trailing ";" in the file being included by the ngx_http_geo_module were silently ignored. *) Feature: the ngx_http_stub_status_module. *) Bugfix: the unknown log format in the access_log directive caused the segmentation fault. *) Feature: the new "document_root" parameter of the fastcgi_params directive. *) Feature: the fastcgi_redirect_errors directive. *) Feature: the new "break" modifier of the "rewrite" directive allows to stop the rewrite/location cycle and sets the current configuration to the request.
author Igor Sysoev <http://sysoev.ru>
date Wed, 09 Feb 2005 00:00:00 +0300
parents aab2ea7c0458
children 6cfc63e68377
comparison
equal deleted inserted replaced
35:ef53675fe4a6 36:a39d1b793287
45 45
46 /* add the r->args to the new arguments */ 46 /* add the r->args to the new arguments */
47 uintptr_t args:1; 47 uintptr_t args:1;
48 48
49 uintptr_t redirect:1; 49 uintptr_t redirect:1;
50 uintptr_t break_cycle:1;
50 51
51 ngx_str_t name; 52 ngx_str_t name;
52 } ngx_http_rewrite_regex_code_t; 53 } ngx_http_rewrite_regex_code_t;
53 54
54 55
119 120
120 121
121 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); 122 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle);
122 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); 123 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf);
123 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, 124 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf,
124 void *parent, void *child); 125 void *parent, void *child);
125 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 126 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
126 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, 127 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd,
127 void *conf); 128 void *conf);
128 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, 129 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd,
129 void *conf); 130 void *conf);
130 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, 131 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf,
131 void *conf); 132 ngx_command_t *cmd, void *conf);
132 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool, 133 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool,
133 ngx_array_t **codes, size_t size); 134 ngx_array_t **codes, size_t size);
134 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, 135 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size,
135 u_char **main); 136 void *code);
136 137
137 138
138 static ngx_command_t ngx_http_rewrite_commands[] = { 139 static ngx_command_t ngx_http_rewrite_commands[] = {
139 140
140 { ngx_string("rewrite"), 141 { ngx_string("rewrite"),
206 #define ngx_http_rewrite_exit (u_char *) &ngx_http_rewrite_exit_code 207 #define ngx_http_rewrite_exit (u_char *) &ngx_http_rewrite_exit_code
207 208
208 uintptr_t ngx_http_rewrite_exit_code = (uintptr_t) NULL; 209 uintptr_t ngx_http_rewrite_exit_code = (uintptr_t) NULL;
209 210
210 211
211 static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) 212 static ngx_int_t
213 ngx_http_rewrite_handler(ngx_http_request_t *r)
212 { 214 {
213 ngx_http_rewrite_code_pt code; 215 ngx_http_rewrite_code_pt code;
214 ngx_http_rewrite_engine_t *e; 216 ngx_http_rewrite_engine_t *e;
215 ngx_http_rewrite_loc_conf_t *cf; 217 ngx_http_rewrite_loc_conf_t *cf;
216 218
257 259
258 return e->status; 260 return e->status;
259 } 261 }
260 262
261 263
262 static void ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e) 264 static void
265 ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e)
263 { 266 {
264 ngx_int_t rc; 267 ngx_int_t rc;
265 ngx_uint_t n; 268 ngx_uint_t n;
266 ngx_http_request_t *r; 269 ngx_http_request_t *r;
267 ngx_http_rewrite_regex_code_t *code; 270 ngx_http_rewrite_regex_code_t *code;
316 } 319 }
317 320
318 e->buf.len = code->size; 321 e->buf.len = code->size;
319 322
320 if (code->uri) { 323 if (code->uri) {
321 r->uri_changed = 1; 324 if (!code->break_cycle) {
325 r->uri_changed = 1;
326 }
322 327
323 if (rc && (r->quoted_uri || r->plus_in_uri)) { 328 if (rc && (r->quoted_uri || r->plus_in_uri)) {
324 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, 329 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
325 NGX_ESCAPE_ARGS); 330 NGX_ESCAPE_ARGS);
326 } 331 }
346 351
347 e->ip += sizeof(ngx_http_rewrite_regex_code_t); 352 e->ip += sizeof(ngx_http_rewrite_regex_code_t);
348 } 353 }
349 354
350 355
351 static void ngx_http_rewrite_regex_end_code(ngx_http_rewrite_engine_t *e) 356 static void
357 ngx_http_rewrite_regex_end_code(ngx_http_rewrite_engine_t *e)
352 { 358 {
353 ngx_http_request_t *r; 359 ngx_http_request_t *r;
354 ngx_http_rewrite_regex_end_code_t *code; 360 ngx_http_rewrite_regex_end_code_t *code;
355 361
356 code = (ngx_http_rewrite_regex_end_code_t *) e->ip; 362 code = (ngx_http_rewrite_regex_end_code_t *) e->ip;
375 381
376 e->args = NULL; 382 e->args = NULL;
377 383
378 } else { 384 } else {
379 if (code->args && r->args.len) { 385 if (code->args && r->args.len) {
380 *e->pos++ = '&'; 386 *e->pos++ = '?';
381 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); 387 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
382 } 388 }
383 389
384 e->buf.len = e->pos - e->buf.data; 390 e->buf.len = e->pos - e->buf.data;
385 } 391 }
423 429
424 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t); 430 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t);
425 } 431 }
426 432
427 433
428 static void ngx_http_rewrite_copy_capture_code(ngx_http_rewrite_engine_t *e) 434 static void
435 ngx_http_rewrite_copy_capture_code(ngx_http_rewrite_engine_t *e)
429 { 436 {
430 ngx_http_rewrite_copy_capture_code_t *code; 437 ngx_http_rewrite_copy_capture_code_t *code;
431 438
432 code = (ngx_http_rewrite_copy_capture_code_t *) e->ip; 439 code = (ngx_http_rewrite_copy_capture_code_t *) e->ip;
433 440
448 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, 455 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
449 "http rewrite capture: \"%V\"", &e->buf); 456 "http rewrite capture: \"%V\"", &e->buf);
450 } 457 }
451 458
452 459
453 static void ngx_http_rewrite_copy_code(ngx_http_rewrite_engine_t *e) 460 static void
461 ngx_http_rewrite_copy_code(ngx_http_rewrite_engine_t *e)
454 { 462 {
455 ngx_http_rewrite_copy_code_t *code; 463 ngx_http_rewrite_copy_code_t *code;
456 464
457 code = (ngx_http_rewrite_copy_code_t *) e->ip; 465 code = (ngx_http_rewrite_copy_code_t *) e->ip;
458 466
465 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, 473 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
466 "http rewrite copy: \"%V\"", &e->buf); 474 "http rewrite copy: \"%V\"", &e->buf);
467 } 475 }
468 476
469 477
470 static void ngx_http_rewrite_start_args_code(ngx_http_rewrite_engine_t *e) 478 static void
479 ngx_http_rewrite_start_args_code(ngx_http_rewrite_engine_t *e)
471 { 480 {
472 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, 481 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
473 "http rewrite args"); 482 "http rewrite args");
474 483
475 e->args = e->pos; 484 e->args = e->pos;
476 e->ip += sizeof(uintptr_t); 485 e->ip += sizeof(uintptr_t);
477 } 486 }
478 487
479 488
480 static void ngx_http_rewrite_return_code(ngx_http_rewrite_engine_t *e) 489 static void
490 ngx_http_rewrite_return_code(ngx_http_rewrite_engine_t *e)
481 { 491 {
482 ngx_http_rewrite_return_code_t *code; 492 ngx_http_rewrite_return_code_t *code;
483 493
484 code = (ngx_http_rewrite_return_code_t *) e->ip; 494 code = (ngx_http_rewrite_return_code_t *) e->ip;
485 495
487 497
488 e->ip += sizeof(ngx_http_rewrite_return_code_t) - sizeof(uintptr_t); 498 e->ip += sizeof(ngx_http_rewrite_return_code_t) - sizeof(uintptr_t);
489 } 499 }
490 500
491 501
492 static void ngx_http_rewrite_if_code(ngx_http_rewrite_engine_t *e) 502 static void
503 ngx_http_rewrite_if_code(ngx_http_rewrite_engine_t *e)
493 { 504 {
494 ngx_http_rewrite_if_code_t *code; 505 ngx_http_rewrite_if_code_t *code;
495 506
496 code = (ngx_http_rewrite_if_code_t *) e->ip; 507 code = (ngx_http_rewrite_if_code_t *) e->ip;
497 508
512 523
513 e->ip += code->next; 524 e->ip += code->next;
514 } 525 }
515 526
516 527
517 static void ngx_http_rewrite_var_code(ngx_http_rewrite_engine_t *e) 528 static void
529 ngx_http_rewrite_var_code(ngx_http_rewrite_engine_t *e)
518 { 530 {
519 ngx_http_variable_value_t *value; 531 ngx_http_variable_value_t *value;
520 ngx_http_rewrite_var_code_t *code; 532 ngx_http_rewrite_var_code_t *code;
521 533
522 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, 534 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
538 550
539 *e->sp = value->value; 551 *e->sp = value->value;
540 } 552 }
541 553
542 554
543 static void ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e) 555 static void
556 ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_engine_t *e)
544 { 557 {
545 u_char *ref; 558 u_char *ref;
546 size_t len; 559 size_t len;
547 ngx_uint_t i, n; 560 ngx_uint_t i, n;
548 ngx_http_request_t *r; 561 ngx_http_request_t *r;
623 636
624 *e->sp = (uintptr_t) 1; 637 *e->sp = (uintptr_t) 1;
625 } 638 }
626 639
627 640
628 static void ngx_http_rewrite_nop_code(ngx_http_rewrite_engine_t *e) 641 static void
642 ngx_http_rewrite_nop_code(ngx_http_rewrite_engine_t *e)
629 { 643 {
630 e->ip += sizeof(uintptr_t); 644 e->ip += sizeof(uintptr_t);
631 } 645 }
632 646
633 647
634 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle) 648 static ngx_int_t
649 ngx_http_rewrite_init(ngx_cycle_t *cycle)
635 { 650 {
636 ngx_http_handler_pt *h; 651 ngx_http_handler_pt *h;
637 ngx_http_core_main_conf_t *cmcf; 652 ngx_http_core_main_conf_t *cmcf;
638 653
639 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); 654 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
647 662
648 return NGX_OK; 663 return NGX_OK;
649 } 664 }
650 665
651 666
652 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf) 667 static void *
668 ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
653 { 669 {
654 ngx_http_rewrite_loc_conf_t *conf; 670 ngx_http_rewrite_loc_conf_t *conf;
655 671
656 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)))) { 672 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)))) {
657 return NGX_CONF_ERROR; 673 return NGX_CONF_ERROR;
663 679
664 return conf; 680 return conf;
665 } 681 }
666 682
667 683
668 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, 684 static char *
669 void *parent, void *child) 685 ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
670 { 686 {
671 ngx_http_rewrite_loc_conf_t *prev = parent; 687 ngx_http_rewrite_loc_conf_t *prev = parent;
672 ngx_http_rewrite_loc_conf_t *conf = child; 688 ngx_http_rewrite_loc_conf_t *conf = child;
673 689
674 uintptr_t *code, *last; 690 uintptr_t *code, *last;
735 751
736 return NGX_CONF_OK; 752 return NGX_CONF_OK;
737 } 753 }
738 754
739 755
740 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 756 static char *
757 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
741 { 758 {
742 ngx_http_rewrite_loc_conf_t *lcf = conf; 759 ngx_http_rewrite_loc_conf_t *lcf = conf;
743 760
744 u_char *data; 761 u_char *data;
745 size_t len, size; 762 size_t len, size;
791 808
792 if (cf->args->nelts == 4) { 809 if (cf->args->nelts == 4) {
793 if (ngx_strcmp(value[3].data, "last") == 0) { 810 if (ngx_strcmp(value[3].data, "last") == 0) {
794 last = 1; 811 last = 1;
795 812
813 } else if (ngx_strcmp(value[3].data, "break") == 0) {
814 regex->break_cycle = 1;
815 last = 1;
816
796 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { 817 } else if (ngx_strcmp(value[3].data, "redirect") == 0) {
797 regex->status = NGX_HTTP_MOVED_TEMPORARILY; 818 regex->status = NGX_HTTP_MOVED_TEMPORARILY;
798 regex->redirect = 1; 819 regex->redirect = 1;
799 last = 1; 820 last = 1;
800 821
822 843
823 /* the "$1" - "$9" captures */ 844 /* the "$1" - "$9" captures */
824 845
825 copy_capture = ngx_http_rewrite_add_code(lcf->codes, 846 copy_capture = ngx_http_rewrite_add_code(lcf->codes,
826 sizeof(ngx_http_rewrite_copy_capture_code_t), 847 sizeof(ngx_http_rewrite_copy_capture_code_t),
827 (u_char **) &regex); 848 &regex);
828 if (copy_capture == NULL) { 849 if (copy_capture == NULL) {
829 return NGX_CONF_ERROR; 850 return NGX_CONF_ERROR;
830 } 851 }
831 852
832 i++; 853 i++;
855 break; 876 break;
856 } 877 }
857 878
858 if (!regex->redirect) { 879 if (!regex->redirect) {
859 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), 880 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t),
860 (u_char **) &regex); 881 &regex);
861 if (code == NULL) { 882 if (code == NULL) {
862 return NGX_CONF_ERROR; 883 return NGX_CONF_ERROR;
863 } 884 }
864 885
865 *code = ngx_http_rewrite_start_args_code; 886 *code = ngx_http_rewrite_start_args_code;
905 926
906 size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); 927 size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1);
907 928
908 copy = ngx_http_rewrite_add_code(lcf->codes, 929 copy = ngx_http_rewrite_add_code(lcf->codes,
909 sizeof(ngx_http_rewrite_copy_code_t) + size, 930 sizeof(ngx_http_rewrite_copy_code_t) + size,
910 (u_char **) &regex); 931 &regex);
911 if (copy == NULL) { 932 if (copy == NULL) {
912 return NGX_CONF_ERROR; 933 return NGX_CONF_ERROR;
913 } 934 }
914 935
915 copy->code = ngx_http_rewrite_copy_code; 936 copy->code = ngx_http_rewrite_copy_code;
937 regex->ncaptures = (regex->ncaptures + 1) * 3; 958 regex->ncaptures = (regex->ncaptures + 1) * 3;
938 } 959 }
939 960
940 regex_end = ngx_http_rewrite_add_code(lcf->codes, 961 regex_end = ngx_http_rewrite_add_code(lcf->codes,
941 sizeof(ngx_http_rewrite_regex_end_code_t), 962 sizeof(ngx_http_rewrite_regex_end_code_t),
942 (u_char **) &regex); 963 &regex);
943 if (regex_end == NULL) { 964 if (regex_end == NULL) {
944 return NGX_CONF_ERROR; 965 return NGX_CONF_ERROR;
945 } 966 }
946 967
947 regex_end->code = ngx_http_rewrite_regex_end_code; 968 regex_end->code = ngx_http_rewrite_regex_end_code;
949 regex_end->args = regex->args; 970 regex_end->args = regex->args;
950 regex_end->redirect = regex->redirect; 971 regex_end->redirect = regex->redirect;
951 972
952 if (last) { 973 if (last) {
953 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), 974 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t),
954 (u_char **) &regex); 975 &regex);
955 if (code == NULL) { 976 if (code == NULL) {
956 return NGX_CONF_ERROR; 977 return NGX_CONF_ERROR;
957 } 978 }
958 979
959 *code = (uintptr_t) NULL; 980 *code = (uintptr_t) NULL;
964 985
965 return NGX_CONF_OK; 986 return NGX_CONF_OK;
966 } 987 }
967 988
968 989
969 990 static char *
970 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, 991 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
971 void *conf)
972 { 992 {
973 ngx_http_rewrite_loc_conf_t *lcf = conf; 993 ngx_http_rewrite_loc_conf_t *lcf = conf;
974 994
975 ngx_str_t *value; 995 ngx_str_t *value;
976 ngx_http_rewrite_return_code_t *ret; 996 ngx_http_rewrite_return_code_t *ret;
994 1014
995 return NGX_CONF_OK; 1015 return NGX_CONF_OK;
996 } 1016 }
997 1017
998 1018
999 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 1019 static char *
1020 ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1000 { 1021 {
1001 ngx_http_rewrite_loc_conf_t *lcf = conf; 1022 ngx_http_rewrite_loc_conf_t *lcf = conf;
1002 1023
1003 void *mconf; 1024 void *mconf;
1004 char *rv; 1025 char *rv;
1177 1198
1178 return NGX_CONF_OK; 1199 return NGX_CONF_OK;
1179 } 1200 }
1180 1201
1181 1202
1182 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, 1203 static char *
1183 void *conf) 1204 ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1184 { 1205 {
1185 ngx_http_rewrite_loc_conf_t *lcf = conf; 1206 ngx_http_rewrite_loc_conf_t *lcf = conf;
1186 1207
1187 ngx_uint_t i, server_names; 1208 ngx_uint_t i, server_names;
1188 ngx_str_t *value; 1209 ngx_str_t *value;
1264 1285
1265 return NGX_CONF_OK; 1286 return NGX_CONF_OK;
1266 } 1287 }
1267 1288
1268 1289
1269 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool, 1290 static void *
1270 ngx_array_t **codes, size_t size) 1291 ngx_http_rewrite_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
1271 { 1292 {
1272 if (*codes == NULL) { 1293 if (*codes == NULL) {
1273 if (!(*codes = ngx_array_create(pool, 256, 1))) { 1294 if (!(*codes = ngx_array_create(pool, 256, 1))) {
1274 return NULL; 1295 return NULL;
1275 } 1296 }
1277 1298
1278 return ngx_array_push_n(*codes, size); 1299 return ngx_array_push_n(*codes, size);
1279 } 1300 }
1280 1301
1281 1302
1282 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, 1303 static void *
1283 u_char **main) 1304 ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, void *code)
1284 { 1305 {
1285 u_char *elts; 1306 u_char *elts, **p;
1286 void *new; 1307 void *new;
1287 1308
1288 elts = codes->elts; 1309 elts = codes->elts;
1289 1310
1290 if (!(new = ngx_array_push_n(codes, size))) { 1311 if (!(new = ngx_array_push_n(codes, size))) {
1291 return NGX_CONF_ERROR; 1312 return NGX_CONF_ERROR;
1292 } 1313 }
1293 1314
1294 if (elts != codes->elts) { 1315 if (elts != codes->elts) {
1295 *main += (u_char *) codes->elts - elts; 1316 p = code;
1317 *p += (u_char *) codes->elts - elts;
1296 } 1318 }
1297 1319
1298 return new; 1320 return new;
1299 } 1321 }