Mercurial > hg > nginx
comparison src/http/ngx_http_core_module.c @ 195:8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 25 Nov 2003 20:44:56 +0000 |
parents | 2357fa41738a |
children | 267ea1d98683 |
comparison
equal
deleted
inserted
replaced
194:2357fa41738a | 195:8dee38ea9117 |
---|---|
86 NGX_HTTP_SRV_CONF_OFFSET, | 86 NGX_HTTP_SRV_CONF_OFFSET, |
87 offsetof(ngx_http_core_srv_conf_t, large_client_header), | 87 offsetof(ngx_http_core_srv_conf_t, large_client_header), |
88 NULL}, | 88 NULL}, |
89 | 89 |
90 {ngx_string("location"), | 90 {ngx_string("location"), |
91 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, | 91 NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, |
92 ngx_location_block, | 92 ngx_location_block, |
93 NGX_HTTP_SRV_CONF_OFFSET, | 93 NGX_HTTP_SRV_CONF_OFFSET, |
94 0, | 94 0, |
95 NULL}, | 95 NULL}, |
96 | 96 |
366 } | 366 } |
367 | 367 |
368 | 368 |
369 int ngx_http_find_location_config(ngx_http_request_t *r) | 369 int ngx_http_find_location_config(ngx_http_request_t *r) |
370 { | 370 { |
371 int i, rc; | 371 ngx_int_t i, rc, exact; |
372 ngx_str_t *auto_redirect; | 372 ngx_str_t *auto_redirect; |
373 ngx_http_core_loc_conf_t *clcf, **clcfp; | 373 ngx_http_core_loc_conf_t *clcf, **clcfp; |
374 ngx_http_core_srv_conf_t *cscf; | 374 ngx_http_core_srv_conf_t *cscf; |
375 | 375 |
376 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | 376 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
377 auto_redirect = NULL; | 377 auto_redirect = NULL; |
378 exact = 0; | |
378 | 379 |
379 clcfp = cscf->locations.elts; | 380 clcfp = cscf->locations.elts; |
380 for (i = 0; i < cscf->locations.nelts; i++) { | 381 for (i = 0; i < cscf->locations.nelts; i++) { |
381 #if 0 | 382 |
382 ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); | 383 #if 1 |
384 ngx_log_debug(r->connection->log, "trans: %s: %d" _ | |
385 clcfp[i]->name.data _ clcfp[i]->exact_match); | |
383 #endif | 386 #endif |
387 | |
388 if (clcfp[i]->regex) { | |
389 break; | |
390 } | |
391 | |
384 if (clcfp[i]->auto_redirect | 392 if (clcfp[i]->auto_redirect |
385 && r->uri.len == clcfp[i]->name.len - 1 | 393 && r->uri.len == clcfp[i]->name.len - 1 |
386 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, | 394 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, |
387 clcfp[i]->name.len - 1) == 0) | 395 clcfp[i]->name.len - 1) == 0) |
388 { | 396 { |
404 if (rc == 0) { | 412 if (rc == 0) { |
405 r->loc_conf = clcfp[i]->loc_conf; | 413 r->loc_conf = clcfp[i]->loc_conf; |
406 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 414 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
407 r->connection->log->file = clcf->err_log->file; | 415 r->connection->log->file = clcf->err_log->file; |
408 r->connection->log->log_level = clcf->err_log->log_level; | 416 r->connection->log->log_level = clcf->err_log->log_level; |
417 | |
418 if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { | |
419 exact = 1; | |
420 break; | |
421 } | |
422 } | |
423 } | |
424 | |
425 if (!exact && !auto_redirect) { | |
426 /* regex matches */ | |
427 | |
428 for (/* void */; i < cscf->locations.nelts; i++) { | |
429 | |
430 #if 1 | |
431 ngx_log_debug(r->connection->log, "trans: %s: %d" _ | |
432 clcfp[i]->name.data _ clcfp[i]->exact_match); | |
433 #endif | |
434 | |
435 if (!clcfp[i]->regex) { | |
436 continue; | |
437 } | |
438 | |
439 rc = ngx_regex_exec(clcfp[i]->regex, &r->uri); | |
440 | |
441 if (rc == NGX_DECLINED) { | |
442 continue; | |
443 } | |
444 | |
445 if (rc < 0) { | |
446 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
447 ngx_regex_exec_n | |
448 " failed: %d on \"%s\" using \"%s\"", | |
449 rc, r->uri.data, clcfp[i]->name.data); | |
450 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
451 } | |
452 | |
453 /* match */ | |
454 | |
455 r->loc_conf = clcfp[i]->loc_conf; | |
456 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
457 r->connection->log->file = clcf->err_log->file; | |
458 r->connection->log->log_level = clcf->err_log->log_level; | |
459 | |
460 break; | |
409 } | 461 } |
410 } | 462 } |
411 | 463 |
412 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 464 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
413 | 465 |
667 | 719 |
668 return rv; | 720 return rv; |
669 } | 721 } |
670 | 722 |
671 | 723 |
672 static int ngx_cmp_locations(const void *first, const void *second) | 724 static int ngx_cmp_locations(const void *one, const void *two) |
673 { | 725 { |
674 ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first; | 726 ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; |
675 ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second; | 727 ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; |
676 | 728 |
677 return ngx_strcmp(one->name.data, two->name.data); | 729 ngx_int_t rc; |
730 | |
731 if (first->regex && !second->regex) { | |
732 /* shift regex matches to the end */ | |
733 return 1; | |
734 } | |
735 | |
736 if (first->regex || second->regex) { | |
737 /* do not sort regex matches */ | |
738 return 0; | |
739 } | |
740 | |
741 rc = ngx_strcmp(first->name.data, second->name.data); | |
742 | |
743 if (rc == 0 && second->exact_match) { | |
744 /* an exact match must be before the same inclusive one */ | |
745 return 1; | |
746 } | |
747 | |
748 return rc; | |
678 } | 749 } |
679 | 750 |
680 | 751 |
681 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | 752 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) |
682 { | 753 { |
683 int m; | |
684 char *rv; | 754 char *rv; |
685 ngx_str_t *location; | 755 ngx_int_t m; |
756 ngx_str_t *value, err; | |
686 ngx_http_module_t *module; | 757 ngx_http_module_t *module; |
687 ngx_conf_t pvcf; | 758 ngx_conf_t pvcf; |
688 ngx_http_conf_ctx_t *ctx, *pvctx; | 759 ngx_http_conf_ctx_t *ctx, *pvctx; |
689 ngx_http_core_srv_conf_t *cscf; | 760 ngx_http_core_srv_conf_t *cscf; |
690 ngx_http_core_loc_conf_t *clcf, **clcfp; | 761 ngx_http_core_loc_conf_t *clcf, **clcfp; |
691 | 762 char errstr[NGX_MAX_CONF_ERRSTR]; |
692 ngx_test_null(ctx, | 763 |
693 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), | 764 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { |
694 NGX_CONF_ERROR); | 765 return NGX_CONF_ERROR; |
766 } | |
695 | 767 |
696 pvctx = (ngx_http_conf_ctx_t *) cf->ctx; | 768 pvctx = (ngx_http_conf_ctx_t *) cf->ctx; |
697 ctx->main_conf = pvctx->main_conf; | 769 ctx->main_conf = pvctx->main_conf; |
698 ctx->srv_conf = pvctx->srv_conf; | 770 ctx->srv_conf = pvctx->srv_conf; |
699 | 771 |
700 ngx_test_null(ctx->loc_conf, | 772 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); |
701 ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), | 773 if (ctx->loc_conf == NULL) { |
702 NGX_CONF_ERROR); | 774 return NGX_CONF_ERROR; |
775 } | |
703 | 776 |
704 for (m = 0; ngx_modules[m]; m++) { | 777 for (m = 0; ngx_modules[m]; m++) { |
705 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | 778 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { |
706 continue; | 779 continue; |
707 } | 780 } |
708 | 781 |
709 module = ngx_modules[m]->ctx; | 782 module = ngx_modules[m]->ctx; |
710 | 783 |
711 if (module->create_loc_conf) { | 784 if (module->create_loc_conf) { |
712 ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], | 785 ctx->loc_conf[ngx_modules[m]->ctx_index] = |
713 module->create_loc_conf(cf), | 786 module->create_loc_conf(cf); |
714 NGX_CONF_ERROR); | 787 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) { |
788 return NGX_CONF_ERROR; | |
789 } | |
715 } | 790 } |
716 } | 791 } |
717 | 792 |
718 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | 793 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; |
719 location = (ngx_str_t *) cf->args->elts; | |
720 clcf->name.len = location[1].len; | |
721 clcf->name.data = location[1].data; | |
722 clcf->loc_conf = ctx->loc_conf; | 794 clcf->loc_conf = ctx->loc_conf; |
723 | 795 |
796 value = (ngx_str_t *) cf->args->elts; | |
797 | |
798 if (cf->args->nelts == 3) { | |
799 if (value[1].len == 1 && value[1].data[0] == '=') { | |
800 clcf->name.len = value[2].len; | |
801 clcf->name.data = value[2].data; | |
802 clcf->exact_match = 1; | |
803 | |
804 } else if ((value[1].len == 1 && value[1].data[0] == '~') | |
805 || (value[1].len == 2 | |
806 && value[1].data[0] == '~' | |
807 && value[1].data[1] == '*')) | |
808 { | |
809 err.len = NGX_MAX_CONF_ERRSTR; | |
810 err.data = errstr; | |
811 | |
812 clcf->regex = ngx_regex_compile(&value[2], | |
813 value[1].len == 2 ? NGX_REGEX_CASELESS: 0, | |
814 cf->pool, &err); | |
815 | |
816 if (clcf->regex == NULL) { | |
817 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
818 return NGX_CONF_ERROR; | |
819 } | |
820 | |
821 clcf->name.len = value[2].len; | |
822 clcf->name.data = value[2].data; | |
823 | |
824 } else { | |
825 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
826 "invalid location modifier \"%s\"", | |
827 value[1].data); | |
828 return NGX_CONF_ERROR; | |
829 } | |
830 | |
831 } else { | |
832 clcf->name.len = value[1].len; | |
833 clcf->name.data = value[1].data; | |
834 } | |
835 | |
724 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; | 836 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; |
725 ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); | 837 if (!(clcfp = ngx_push_array(&cscf->locations))) { |
838 return NGX_CONF_ERROR; | |
839 } | |
726 *clcfp = clcf; | 840 *clcfp = clcf; |
727 | 841 |
728 pvcf = *cf; | 842 pvcf = *cf; |
729 cf->ctx = ctx; | 843 cf->ctx = ctx; |
730 cf->cmd_type = NGX_HTTP_LOC_CONF; | 844 cf->cmd_type = NGX_HTTP_LOC_CONF; |
908 lcf->types = NULL; | 1022 lcf->types = NULL; |
909 lcf->default_type.len = 0; | 1023 lcf->default_type.len = 0; |
910 lcf->default_type.data = NULL; | 1024 lcf->default_type.data = NULL; |
911 lcf->err_log = NULL; | 1025 lcf->err_log = NULL; |
912 lcf->error_pages = NULL; | 1026 lcf->error_pages = NULL; |
1027 | |
1028 lcf->regex = NULL; | |
1029 lcf->exact_match = 0; | |
1030 lcf->auto_redirect = 0; | |
913 | 1031 |
914 */ | 1032 */ |
915 | 1033 |
916 lcf->client_body_timeout = NGX_CONF_UNSET; | 1034 lcf->client_body_timeout = NGX_CONF_UNSET; |
917 lcf->sendfile = NGX_CONF_UNSET; | 1035 lcf->sendfile = NGX_CONF_UNSET; |
1077 "can not resolve host \"%s\" " | 1195 "can not resolve host \"%s\" " |
1078 "in \"%s\" directive", addr, cmd->name.data); | 1196 "in \"%s\" directive", addr, cmd->name.data); |
1079 return NGX_CONF_ERROR; | 1197 return NGX_CONF_ERROR; |
1080 } | 1198 } |
1081 | 1199 |
1082 ls->addr = *(u_int32_t *)(h->h_addr_list[0]); | 1200 ls->addr = *(in_addr_t *)(h->h_addr_list[0]); |
1083 } | 1201 } |
1084 | 1202 |
1085 return NGX_CONF_OK; | 1203 return NGX_CONF_OK; |
1086 } | 1204 } |
1087 | 1205 |