comparison src/http/ngx_http_core_module.c @ 396:6f3b20c1ac50

nginx-0.0.7-2004-07-18-23:11:20 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 18 Jul 2004 19:11:20 +0000
parents f8f0f1834266
children 69e851f83522
comparison
equal deleted inserted replaced
395:f8f0f1834266 396:6f3b20c1ac50
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_event.h> 4 #include <ngx_event.h>
5 #include <ngx_http.h> 5 #include <ngx_http.h>
6 #include <nginx.h> 6 #include <nginx.h>
7 7
8 /* STUB */
9 #define NGX_HTTP_LOCATION_EXACT 1
10 #define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
11 #define NGX_HTTP_LOCATION_REGEX 3
12
8 13
9 static void ngx_http_phase_event_handler(ngx_event_t *rev); 14 static void ngx_http_phase_event_handler(ngx_event_t *rev);
10 static void ngx_http_run_phases(ngx_http_request_t *r); 15 static void ngx_http_run_phases(ngx_http_request_t *r);
16 static ngx_int_t ngx_http_find_location(ngx_http_request_t *r,
17 ngx_array_t *locations);
11 18
12 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); 19 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
13 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); 20 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
14 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf); 21 static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
15 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf, 22 static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
101 NGX_HTTP_SRV_CONF_OFFSET, 108 NGX_HTTP_SRV_CONF_OFFSET,
102 offsetof(ngx_http_core_srv_conf_t, restrict_host_names), 109 offsetof(ngx_http_core_srv_conf_t, restrict_host_names),
103 &ngx_http_restrict_host_names }, 110 &ngx_http_restrict_host_names },
104 111
105 { ngx_string("location"), 112 { ngx_string("location"),
106 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, 113 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
107 ngx_location_block, 114 ngx_location_block,
108 NGX_HTTP_SRV_CONF_OFFSET, 115 NGX_HTTP_SRV_CONF_OFFSET,
109 0, 116 0,
110 NULL }, 117 NULL },
111 118
461 } 468 }
462 469
463 470
464 ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r) 471 ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r)
465 { 472 {
466 int rc; 473 ngx_int_t rc;
467 ngx_uint_t i; 474 ngx_http_core_loc_conf_t *clcf;
468 ngx_str_t *auto_redirect; 475 ngx_http_core_srv_conf_t *cscf;
469 ngx_http_core_loc_conf_t *clcf, **clcfp;
470 ngx_http_core_srv_conf_t *cscf;
471 #if (HAVE_PCRE)
472 ngx_uint_t exact;
473 #endif
474 476
475 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 477 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
476 auto_redirect = NULL; 478
477 #if (HAVE_PCRE) 479 rc = ngx_http_find_location(r, &cscf->locations);
478 exact = 0; 480
479 #endif 481 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
480 482 return rc;
481 clcfp = cscf->locations.elts; 483 }
482 for (i = 0; i < cscf->locations.nelts; i++) {
483
484 #if (HAVE_PCRE)
485
486 if (clcfp[i]->regex) {
487 break;
488 }
489 #endif
490
491 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
492 "find location: %s\"%s\"",
493 clcfp[i]->exact_match ? "= " : "",
494 clcfp[i]->name.data);
495
496 if (clcfp[i]->auto_redirect
497 && r->uri.len == clcfp[i]->name.len - 1
498 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
499 clcfp[i]->name.len - 1) == 0)
500 {
501 auto_redirect = &clcfp[i]->name;
502 continue;
503 }
504
505 if (r->uri.len < clcfp[i]->name.len) {
506 continue;
507 }
508
509 rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
510
511 if (rc < 0) {
512 /* locations are lexicographically sorted */
513 break;
514 }
515
516 if (rc == 0) {
517 r->loc_conf = clcfp[i]->loc_conf;
518 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
519 r->connection->log->file = clcf->err_log->file;
520 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
521 r->connection->log->log_level = clcf->err_log->log_level;
522 }
523
524 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
525 #if (HAVE_PCRE)
526 exact = 1;
527 #endif
528 break;
529 }
530 }
531 }
532
533 #if (HAVE_PCRE)
534
535 if (!exact && !auto_redirect) {
536 /* regex matches */
537
538 for (/* void */; i < cscf->locations.nelts; i++) {
539
540 if (!clcfp[i]->regex) {
541 continue;
542 }
543
544 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
545 "find location: %s\"%s\"",
546 clcfp[i]->exact_match ? "= " :
547 clcfp[i]->regex ? "~ " : "",
548 clcfp[i]->name.data);
549
550 rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
551
552 if (rc == NGX_DECLINED) {
553 continue;
554 }
555
556 if (rc < 0) {
557 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
558 ngx_regex_exec_n
559 " failed: %d on \"%s\" using \"%s\"",
560 rc, r->uri.data, clcfp[i]->name.data);
561 return NGX_HTTP_INTERNAL_SERVER_ERROR;
562 }
563
564 /* match */
565
566 r->loc_conf = clcfp[i]->loc_conf;
567 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
568 r->connection->log->file = clcf->err_log->file;
569 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
570 r->connection->log->log_level = clcf->err_log->log_level;
571 }
572
573 break;
574 }
575 }
576
577 #endif /* HAVE_PCRE */
578 484
579 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 485 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
486
487 r->connection->log->file = clcf->err_log->file;
488 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
489 r->connection->log->log_level = clcf->err_log->log_level;
490 }
580 491
581 if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) { 492 if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
582 r->sendfile = 0; 493 r->sendfile = 0;
583 494
584 } else { 495 } else {
607 518
608 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; 519 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
609 } 520 }
610 521
611 522
612 if (auto_redirect) { 523 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
613 if (!(r->headers_out.location = 524 if (!(r->headers_out.location =
614 ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) 525 ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
615 { 526 {
616 return NGX_HTTP_INTERNAL_SERVER_ERROR; 527 return NGX_HTTP_INTERNAL_SERVER_ERROR;
617 } 528 }
618 529
619 r->headers_out.location->value = *auto_redirect; 530 r->headers_out.location->value = clcf->name;
620 531
621 return NGX_HTTP_MOVED_PERMANENTLY; 532 return NGX_HTTP_MOVED_PERMANENTLY;
622 } 533 }
623 534
624 if (clcf->handler) { 535 if (clcf->handler) {
625 r->content_handler = clcf->handler; 536 r->content_handler = clcf->handler;
626 } 537 }
538
539 return NGX_OK;
540 }
541
542
543 static ngx_int_t ngx_http_find_location(ngx_http_request_t *r,
544 ngx_array_t *locations)
545 {
546 ngx_int_t n, rc;
547 ngx_uint_t i, found;
548 ngx_http_core_loc_conf_t *clcf, **clcfp;
549
550 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "find location");
551
552 found = 0;
553
554 clcfp = locations->elts;
555 for (i = 0; i < locations->nelts; i++) {
556
557 #if (HAVE_PCRE)
558 if (clcfp[i]->regex) {
559 break;
560 }
561 #endif
562
563 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
564 "find location: %s\"%s\"",
565 clcfp[i]->exact_match ? "= " : "",
566 clcfp[i]->name.data);
567
568 if (clcfp[i]->auto_redirect
569 && r->uri.len == clcfp[i]->name.len - 1
570 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
571 clcfp[i]->name.len - 1) == 0)
572 {
573 /* the locations are lexicographically sorted */
574
575 r->loc_conf = clcfp[i]->loc_conf;
576
577 return NGX_HTTP_LOCATION_AUTO_REDIRECT;
578 }
579
580 if (r->uri.len < clcfp[i]->name.len) {
581 continue;
582 }
583
584 n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
585
586 if (n < 0) {
587 /* the locations are lexicographically sorted */
588 break;
589 }
590
591 if (n == 0) {
592 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
593
594 if (clcf->name.len >= clcfp[i]->name.len) {
595 /* the previous match is longer */
596 break;
597 }
598
599 r->loc_conf = clcfp[i]->loc_conf;
600
601 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
602 return NGX_HTTP_LOCATION_EXACT;
603 }
604
605 found = 1;
606 }
607 }
608
609 if (found) {
610 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
611
612 if (clcf->locations.nelts) {
613 rc = ngx_http_find_location(r, &clcf->locations);
614
615 if (rc != NGX_OK) {
616 return rc;
617 }
618 }
619 }
620
621 #if (HAVE_PCRE)
622
623 /* regex matches */
624
625 for (/* void */; i < locations->nelts; i++) {
626
627 if (!clcfp[i]->regex) {
628 continue;
629 }
630
631 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
632 "find location: ~ \"%s\"",
633 clcfp[i]->name.data);
634
635 n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
636
637 if (n == NGX_DECLINED) {
638 continue;
639 }
640
641 if (n < 0) {
642 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
643 ngx_regex_exec_n
644 " failed: %d on \"%s\" using \"%s\"",
645 n, r->uri.data, clcfp[i]->name.data);
646 return NGX_HTTP_INTERNAL_SERVER_ERROR;
647 }
648
649 /* match */
650
651 r->loc_conf = clcfp[i]->loc_conf;
652
653 return NGX_HTTP_LOCATION_REGEX;
654 }
655
656 #endif /* HAVE_PCRE */
627 657
628 return NGX_OK; 658 return NGX_OK;
629 } 659 }
630 660
631 661
797 827
798 return NGX_DONE; 828 return NGX_DONE;
799 } 829 }
800 830
801 831
802 #if 1 /* STUB: test the delay http handler */ 832 #if 0 /* STUB: test the delay http handler */
803 833
804 int ngx_http_delay_handler(ngx_http_request_t *r) 834 int ngx_http_delay_handler(ngx_http_request_t *r)
805 { 835 {
806 static int on; 836 static int on;
807 837
861 { 891 {
862 int m; 892 int m;
863 char *rv; 893 char *rv;
864 ngx_http_module_t *module; 894 ngx_http_module_t *module;
865 ngx_conf_t pvcf; 895 ngx_conf_t pvcf;
866 ngx_http_conf_ctx_t *ctx, *hctx; 896 ngx_http_conf_ctx_t *ctx, *http_ctx;
867 ngx_http_core_main_conf_t *cmcf; 897 ngx_http_core_main_conf_t *cmcf;
868 ngx_http_core_srv_conf_t *cscf, **cscfp; 898 ngx_http_core_srv_conf_t *cscf, **cscfp;
869 899
870 ngx_test_null(ctx, 900 ngx_test_null(ctx,
871 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), 901 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
872 NGX_CONF_ERROR); 902 NGX_CONF_ERROR);
873 903
874 hctx = (ngx_http_conf_ctx_t *) cf->ctx; 904 http_ctx = cf->ctx;
875 ctx->main_conf = hctx->main_conf; 905 ctx->main_conf = http_ctx->main_conf;
876 906
877 /* the server{}'s srv_conf */ 907 /* the server{}'s srv_conf */
878 908
879 ngx_test_null(ctx->srv_conf, 909 ngx_test_null(ctx->srv_conf,
880 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), 910 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
926 if (rv != NGX_CONF_OK) { 956 if (rv != NGX_CONF_OK) {
927 return rv; 957 return rv;
928 } 958 }
929 959
930 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts, 960 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts,
931 sizeof(void *), ngx_cmp_locations); 961 sizeof(ngx_http_core_loc_conf_t *), ngx_cmp_locations);
932 962
933 return rv; 963 return rv;
934 } 964 }
935 965
936 966
937 static int ngx_cmp_locations(const void *one, const void *two) 967 static int ngx_cmp_locations(const void *one, const void *two)
938 { 968 {
939 ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; 969 ngx_int_t rc;
940 ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; 970 ngx_http_core_loc_conf_t *first, *second;
941 971
942 ngx_int_t rc; 972 first = *(ngx_http_core_loc_conf_t **) one;
973 second = *(ngx_http_core_loc_conf_t **) two;
943 974
944 #if (HAVE_PCRE) 975 #if (HAVE_PCRE)
945 976
946 if (first->regex && !second->regex) { 977 if (first->regex && !second->regex) {
947 /* shift regex matches to the end */ 978 /* shift the regex matches to the end */
948 return 1; 979 return 1;
949 } 980 }
950 981
951 if (first->regex || second->regex) { 982 if (first->regex || second->regex) {
952 /* do not sort regex matches */ 983 /* do not sort the regex matches */
953 return 0; 984 return 0;
954 } 985 }
955 986
956 #endif 987 #endif
957 988
969 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) 1000 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
970 { 1001 {
971 char *rv; 1002 char *rv;
972 ngx_int_t m; 1003 ngx_int_t m;
973 ngx_str_t *value; 1004 ngx_str_t *value;
1005 ngx_conf_t pcf;
974 ngx_http_module_t *module; 1006 ngx_http_module_t *module;
975 ngx_conf_t pvcf; 1007 ngx_http_conf_ctx_t *ctx, *pctx;
976 ngx_http_conf_ctx_t *ctx, *pvctx;
977 ngx_http_core_srv_conf_t *cscf; 1008 ngx_http_core_srv_conf_t *cscf;
978 ngx_http_core_loc_conf_t *clcf, **clcfp; 1009 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
979 #if (HAVE_PCRE) 1010 #if (HAVE_PCRE)
980 ngx_str_t err; 1011 ngx_str_t err;
981 u_char errstr[NGX_MAX_CONF_ERRSTR]; 1012 u_char errstr[NGX_MAX_CONF_ERRSTR];
982 #endif 1013 #endif
983 1014
984 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { 1015 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) {
985 return NGX_CONF_ERROR; 1016 return NGX_CONF_ERROR;
986 } 1017 }
987 1018
988 pvctx = (ngx_http_conf_ctx_t *) cf->ctx; 1019 pctx = cf->ctx;
989 ctx->main_conf = pvctx->main_conf; 1020 ctx->main_conf = pctx->main_conf;
990 ctx->srv_conf = pvctx->srv_conf; 1021 ctx->srv_conf = pctx->srv_conf;
991 1022
992 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); 1023 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
993 if (ctx->loc_conf == NULL) { 1024 if (ctx->loc_conf == NULL) {
994 return NGX_CONF_ERROR; 1025 return NGX_CONF_ERROR;
995 } 1026 }
1058 } else { 1089 } else {
1059 clcf->name.len = value[1].len; 1090 clcf->name.len = value[1].len;
1060 clcf->name.data = value[1].data; 1091 clcf->name.data = value[1].data;
1061 } 1092 }
1062 1093
1063 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; 1094 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
1064 if (!(clcfp = ngx_push_array(&cscf->locations))) { 1095
1065 return NGX_CONF_ERROR; 1096 if (pclcf->name.len == 0) {
1066 } 1097 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
1098 if (!(clcfp = ngx_push_array(&cscf->locations))) {
1099 return NGX_CONF_ERROR;
1100 }
1101
1102 } else {
1103 clcf->prev_location = pclcf;
1104
1105 if (pclcf->exact_match) {
1106 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1107 "location \"%s\" could not be inside "
1108 "the exact location \"%s\"",
1109 clcf->name.data, pclcf->name.data);
1110 return NGX_CONF_ERROR;
1111 }
1112
1113 if (clcf->regex == NULL
1114 && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
1115 != 0)
1116 {
1117 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1118 "location \"%s\" is outside location \"%s\"",
1119 clcf->name.data, pclcf->name.data);
1120 return NGX_CONF_ERROR;
1121 }
1122
1123 if (pclcf->locations.elts == NULL) {
1124 ngx_init_array(pclcf->locations, cf->pool, 5, sizeof(void *),
1125 NGX_CONF_ERROR);
1126 }
1127
1128 if (!(clcfp = ngx_push_array(&pclcf->locations))) {
1129 return NGX_CONF_ERROR;
1130 }
1131 }
1132
1067 *clcfp = clcf; 1133 *clcfp = clcf;
1068 1134
1069 pvcf = *cf; 1135 pcf = *cf;
1070 cf->ctx = ctx; 1136 cf->ctx = ctx;
1071 cf->cmd_type = NGX_HTTP_LOC_CONF; 1137 cf->cmd_type = NGX_HTTP_LOC_CONF;
1072 rv = ngx_conf_parse(cf, NULL); 1138 rv = ngx_conf_parse(cf, NULL);
1073 *cf = pvcf; 1139 *cf = pcf;
1074 1140
1075 return rv; 1141 return rv;
1076 } 1142 }
1077 1143
1078 1144
1218 } 1284 }
1219 1285
1220 n->name.len = ngx_strlen(n->name.data); 1286 n->name.len = ngx_strlen(n->name.data);
1221 n->core_srv_conf = conf; 1287 n->core_srv_conf = conf;
1222 1288
1289 #if 0
1223 ctx = (ngx_http_conf_ctx_t *) 1290 ctx = (ngx_http_conf_ctx_t *)
1224 cf->cycle->conf_ctx[ngx_http_module.index]; 1291 cf->cycle->conf_ctx[ngx_http_module.index];
1225 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; 1292 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
1293 #endif
1294 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
1226 1295
1227 if (cmcf->max_server_name_len < n->name.len) { 1296 if (cmcf->max_server_name_len < n->name.len) {
1228 cmcf->max_server_name_len = n->name.len; 1297 cmcf->max_server_name_len = n->name.len;
1229 } 1298 }
1230 } 1299 }
1476 ngx_http_core_main_conf_t *cmcf; 1545 ngx_http_core_main_conf_t *cmcf;
1477 1546
1478 /* TODO: several names */ 1547 /* TODO: several names */
1479 /* TODO: warn about duplicate 'server_name' directives */ 1548 /* TODO: warn about duplicate 'server_name' directives */
1480 1549
1550 #if 0
1481 ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index]; 1551 ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index];
1482 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; 1552 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
1553 #endif
1554 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
1483 1555
1484 value = cf->args->elts; 1556 value = cf->args->elts;
1485 1557
1486 for (i = 1; i < cf->args->nelts; i++) { 1558 for (i = 1; i < cf->args->nelts; i++) {
1487 if (value[i].len == 0) { 1559 if (value[i].len == 0) {