Mercurial > hg > nginx-mail
comparison src/http/modules/ngx_http_proxy_module.c @ 503:c8cfb6c462ef NGINX_0_7_44
nginx 0.7.44
*) Feature: the ngx_http_proxy_module preliminary cache support.
*) Feature: the --with-pcre option in the configure.
*) Feature: the "try_files" directive is now allowed on the server
block level.
*) Bugfix: the "try_files" directive handled incorrectly a query string
in a fallback parameter.
*) Bugfix: the "try_files" directive might test incorrectly directories.
*) Bugfix: if there is the single server for given address:port pair,
then captures in regular expressions in a "server_name" directive
did not work.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 23 Mar 2009 00:00:00 +0300 |
parents | dc98ed169c03 |
children | 9eda3153223b |
comparison
equal
deleted
inserted
replaced
502:51cb914e6d3a | 503:c8cfb6c462ef |
---|---|
30 } replacement; | 30 } replacement; |
31 }; | 31 }; |
32 | 32 |
33 | 33 |
34 typedef struct { | 34 typedef struct { |
35 ngx_str_t key_start; | |
35 ngx_str_t schema; | 36 ngx_str_t schema; |
36 ngx_str_t host_header; | 37 ngx_str_t host_header; |
37 ngx_str_t port; | 38 ngx_str_t port; |
38 ngx_str_t uri; | 39 ngx_str_t uri; |
39 } ngx_http_proxy_vars_t; | 40 } ngx_http_proxy_vars_t; |
87 #define NGX_HTTP_PROXY_PARSE_NO_HEADER 20 | 88 #define NGX_HTTP_PROXY_PARSE_NO_HEADER 20 |
88 | 89 |
89 | 90 |
90 static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, | 91 static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, |
91 ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf); | 92 ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf); |
93 #if (NGX_HTTP_CACHE) | |
94 static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r); | |
95 #endif | |
92 static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r); | 96 static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r); |
93 static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r); | 97 static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r); |
94 static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r); | 98 static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r); |
95 static ngx_int_t ngx_http_proxy_parse_status_line(ngx_http_request_t *r, | 99 static ngx_int_t ngx_http_proxy_parse_status_line(ngx_http_request_t *r, |
96 ngx_http_proxy_ctx_t *ctx); | 100 ngx_http_proxy_ctx_t *ctx); |
114 | 118 |
115 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); | 119 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); |
116 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); | 120 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
117 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, | 121 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, |
118 void *parent, void *child); | 122 void *parent, void *child); |
123 static ngx_int_t ngx_http_proxy_merge_headers(ngx_conf_t *cf, | |
124 ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev); | |
119 | 125 |
120 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, | 126 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
121 void *conf); | 127 void *conf); |
122 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, | 128 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, |
123 void *conf); | 129 void *conf); |
124 static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, | 130 static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, |
125 void *conf); | 131 void *conf); |
132 #if (NGX_HTTP_CACHE) | |
133 static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, | |
134 void *conf); | |
135 #endif | |
126 | 136 |
127 static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); | 137 static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); |
128 | 138 |
129 static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, | 139 static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf, |
130 ngx_command_t *cmd, void *conf); | 140 ngx_command_t *cmd, void *conf); |
133 | 143 |
134 #if (NGX_HTTP_SSL) | 144 #if (NGX_HTTP_SSL) |
135 static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, | 145 static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, |
136 ngx_http_proxy_loc_conf_t *plcf); | 146 ngx_http_proxy_loc_conf_t *plcf); |
137 #endif | 147 #endif |
138 static ngx_int_t ngx_http_proxy_set_vars(ngx_pool_t *pool, ngx_url_t *u, | 148 static void ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v); |
139 ngx_http_proxy_vars_t *v); | |
140 | 149 |
141 | 150 |
142 static ngx_conf_post_t ngx_http_proxy_lowat_post = | 151 static ngx_conf_post_t ngx_http_proxy_lowat_post = |
143 { ngx_http_proxy_lowat_check }; | 152 { ngx_http_proxy_lowat_check }; |
144 | 153 |
155 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, | 164 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
156 { ngx_null_string, 0 } | 165 { ngx_null_string, 0 } |
157 }; | 166 }; |
158 | 167 |
159 | 168 |
169 ngx_module_t ngx_http_proxy_module; | |
170 | |
171 | |
160 static ngx_command_t ngx_http_proxy_commands[] = { | 172 static ngx_command_t ngx_http_proxy_commands[] = { |
161 | 173 |
162 { ngx_string("proxy_pass"), | 174 { ngx_string("proxy_pass"), |
163 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, | 175 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, |
164 ngx_http_proxy_pass, | 176 ngx_http_proxy_pass, |
304 ngx_conf_set_size_slot, | 316 ngx_conf_set_size_slot, |
305 NGX_HTTP_LOC_CONF_OFFSET, | 317 NGX_HTTP_LOC_CONF_OFFSET, |
306 offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf), | 318 offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf), |
307 NULL }, | 319 NULL }, |
308 | 320 |
321 #if (NGX_HTTP_CACHE) | |
322 | |
323 { ngx_string("proxy_cache"), | |
324 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
325 ngx_http_proxy_cache, | |
326 NGX_HTTP_LOC_CONF_OFFSET, | |
327 offsetof(ngx_http_proxy_loc_conf_t, upstream.cache), | |
328 NULL }, | |
329 | |
330 { ngx_string("proxy_cache_path"), | |
331 NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE, | |
332 ngx_http_file_cache_set_slot, | |
333 0, | |
334 0, | |
335 &ngx_http_proxy_module }, | |
336 | |
337 { ngx_string("proxy_cache_valid"), | |
338 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
339 ngx_http_file_cache_valid_set_slot, | |
340 NGX_HTTP_LOC_CONF_OFFSET, | |
341 offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_valid), | |
342 NULL }, | |
343 | |
344 { ngx_string("proxy_cache_min_uses"), | |
345 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
346 ngx_conf_set_num_slot, | |
347 NGX_HTTP_LOC_CONF_OFFSET, | |
348 offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_min_uses), | |
349 NULL }, | |
350 | |
351 { ngx_string("proxy_cache_use_stale"), | |
352 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
353 ngx_conf_set_bitmask_slot, | |
354 NGX_HTTP_LOC_CONF_OFFSET, | |
355 offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale), | |
356 &ngx_http_proxy_next_upstream_masks }, | |
357 | |
358 #endif | |
359 | |
309 { ngx_string("proxy_temp_path"), | 360 { ngx_string("proxy_temp_path"), |
310 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, | 361 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, |
311 ngx_conf_set_path_slot, | 362 ngx_conf_set_path_slot, |
312 NGX_HTTP_LOC_CONF_OFFSET, | 363 NGX_HTTP_LOC_CONF_OFFSET, |
313 offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_path), | 364 offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_path), |
314 (void *) ngx_garbage_collector_temp_handler }, | 365 NULL }, |
315 | 366 |
316 { ngx_string("proxy_max_temp_file_size"), | 367 { ngx_string("proxy_max_temp_file_size"), |
317 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 368 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
318 ngx_conf_set_size_slot, | 369 ngx_conf_set_size_slot, |
319 NGX_HTTP_LOC_CONF_OFFSET, | 370 NGX_HTTP_LOC_CONF_OFFSET, |
453 | 504 |
454 { ngx_null_string, NULL, NULL, 0, 0, 0 } | 505 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
455 }; | 506 }; |
456 | 507 |
457 | 508 |
509 static ngx_path_init_t ngx_http_proxy_temp_path = { | |
510 ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 } | |
511 }; | |
512 | |
513 | |
458 static ngx_int_t | 514 static ngx_int_t |
459 ngx_http_proxy_handler(ngx_http_request_t *r) | 515 ngx_http_proxy_handler(ngx_http_request_t *r) |
460 { | 516 { |
461 ngx_int_t rc; | 517 ngx_int_t rc; |
462 ngx_http_upstream_t *u; | 518 ngx_http_upstream_t *u; |
500 | 556 |
501 u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module; | 557 u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module; |
502 | 558 |
503 u->conf = &plcf->upstream; | 559 u->conf = &plcf->upstream; |
504 | 560 |
561 #if (NGX_HTTP_CACHE) | |
562 u->create_key = ngx_http_proxy_create_key; | |
563 #endif | |
505 u->create_request = ngx_http_proxy_create_request; | 564 u->create_request = ngx_http_proxy_create_request; |
506 u->reinit_request = ngx_http_proxy_reinit_request; | 565 u->reinit_request = ngx_http_proxy_reinit_request; |
507 u->process_header = ngx_http_proxy_process_status_line; | 566 u->process_header = ngx_http_proxy_process_status_line; |
508 u->abort_request = ngx_http_proxy_abort_request; | 567 u->abort_request = ngx_http_proxy_abort_request; |
509 u->finalize_request = ngx_http_proxy_finalize_request; | 568 u->finalize_request = ngx_http_proxy_finalize_request; |
535 | 594 |
536 static ngx_int_t | 595 static ngx_int_t |
537 ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, | 596 ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, |
538 ngx_http_proxy_loc_conf_t *plcf) | 597 ngx_http_proxy_loc_conf_t *plcf) |
539 { | 598 { |
540 u_char *p; | 599 u_char *p; |
541 size_t add; | 600 size_t add; |
542 u_short port; | 601 u_short port; |
543 ngx_str_t proxy; | 602 ngx_str_t proxy; |
544 ngx_url_t u; | 603 ngx_url_t url; |
604 ngx_http_upstream_t *u; | |
545 | 605 |
546 if (ngx_http_script_run(r, &proxy, plcf->proxy_lengths->elts, 0, | 606 if (ngx_http_script_run(r, &proxy, plcf->proxy_lengths->elts, 0, |
547 plcf->proxy_values->elts) | 607 plcf->proxy_values->elts) |
548 == NULL) | 608 == NULL) |
549 { | 609 { |
569 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 629 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
570 "invalid URL prefix in \"%V\"", &proxy); | 630 "invalid URL prefix in \"%V\"", &proxy); |
571 return NGX_ERROR; | 631 return NGX_ERROR; |
572 } | 632 } |
573 | 633 |
574 r->upstream->schema.len = add; | 634 u = r->upstream; |
575 r->upstream->schema.data = proxy.data; | 635 |
576 | 636 u->schema.len = add; |
577 ngx_memzero(&u, sizeof(ngx_url_t)); | 637 u->schema.data = proxy.data; |
578 | 638 |
579 u.url.len = proxy.len - add; | 639 ngx_memzero(&url, sizeof(ngx_url_t)); |
580 u.url.data = proxy.data + add; | 640 |
581 u.default_port = port; | 641 url.url.len = proxy.len - add; |
582 u.uri_part = 1; | 642 url.url.data = proxy.data + add; |
583 u.no_resolve = 1; | 643 url.default_port = port; |
584 | 644 url.uri_part = 1; |
585 if (ngx_parse_url(r->pool, &u) != NGX_OK) { | 645 url.no_resolve = 1; |
586 if (u.err) { | 646 |
647 if (ngx_parse_url(r->pool, &url) != NGX_OK) { | |
648 if (url.err) { | |
587 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 649 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
588 "%s in upstream \"%V\"", u.err, &u.url); | 650 "%s in upstream \"%V\"", url.err, &url.url); |
589 } | 651 } |
590 | 652 |
591 return NGX_ERROR; | 653 return NGX_ERROR; |
592 } | 654 } |
593 | 655 |
594 if (u.uri.len && u.uri.data[0] == '?') { | 656 if (url.uri.len && url.uri.data[0] == '?') { |
595 p = ngx_pnalloc(r->pool, u.uri.len + 1); | 657 p = ngx_pnalloc(r->pool, url.uri.len + 1); |
596 if (p == NULL) { | 658 if (p == NULL) { |
597 return NGX_ERROR; | 659 return NGX_ERROR; |
598 } | 660 } |
599 | 661 |
600 *p++ = '/'; | 662 *p++ = '/'; |
601 ngx_memcpy(p, u.uri.data, u.uri.len); | 663 ngx_memcpy(p, url.uri.data, url.uri.len); |
602 | 664 |
603 u.uri.len++; | 665 url.uri.len++; |
604 u.uri.data = p - 1; | 666 url.uri.data = p - 1; |
605 } | 667 } |
606 | 668 |
607 if (ngx_http_proxy_set_vars(r->pool, &u, &ctx->vars) != NGX_OK) { | 669 ctx->vars.key_start = u->schema; |
670 | |
671 ngx_http_proxy_set_vars(&url, &ctx->vars); | |
672 | |
673 u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); | |
674 if (u->resolved == NULL) { | |
608 return NGX_ERROR; | 675 return NGX_ERROR; |
609 } | 676 } |
610 | 677 |
611 r->upstream->resolved = ngx_pcalloc(r->pool, | 678 if (url.addrs && url.addrs[0].sockaddr) { |
612 sizeof(ngx_http_upstream_resolved_t)); | 679 u->resolved->sockaddr = url.addrs[0].sockaddr; |
613 if (r->upstream->resolved == NULL) { | 680 u->resolved->socklen = url.addrs[0].socklen; |
681 u->resolved->naddrs = 1; | |
682 u->resolved->host = url.addrs[0].name; | |
683 | |
684 } else { | |
685 u->resolved->host = url.host; | |
686 u->resolved->port = (in_port_t) (url.no_port ? port : url.port); | |
687 u->resolved->no_port = url.no_port; | |
688 } | |
689 | |
690 return NGX_OK; | |
691 } | |
692 | |
693 | |
694 #if (NGX_HTTP_CACHE) | |
695 | |
696 static ngx_int_t | |
697 ngx_http_proxy_create_key(ngx_http_request_t *r) | |
698 { | |
699 size_t len, loc_len; | |
700 u_char *p; | |
701 uintptr_t escape; | |
702 ngx_str_t *key; | |
703 ngx_http_upstream_t *u; | |
704 ngx_http_proxy_ctx_t *ctx; | |
705 ngx_http_proxy_loc_conf_t *plcf; | |
706 | |
707 u = r->upstream; | |
708 | |
709 plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); | |
710 | |
711 ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); | |
712 | |
713 key = ngx_array_push(&r->cache->keys); | |
714 if (key == NULL) { | |
614 return NGX_ERROR; | 715 return NGX_ERROR; |
615 } | 716 } |
616 | 717 |
617 if (u.addrs && u.addrs[0].sockaddr) { | 718 *key = ctx->vars.key_start; |
618 r->upstream->resolved->sockaddr = u.addrs[0].sockaddr; | 719 |
619 r->upstream->resolved->socklen = u.addrs[0].socklen; | 720 key = ngx_array_push(&r->cache->keys); |
620 r->upstream->resolved->naddrs = 1; | 721 if (key == NULL) { |
621 r->upstream->resolved->host = u.addrs[0].name; | 722 return NGX_ERROR; |
622 | 723 } |
724 | |
725 if (plcf->proxy_lengths) { | |
726 | |
727 *key = ctx->vars.uri; | |
728 u->uri = ctx->vars.uri; | |
729 | |
730 return NGX_OK; | |
731 | |
732 } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) | |
733 { | |
734 *key = r->unparsed_uri; | |
735 u->uri = r->unparsed_uri; | |
736 | |
737 return NGX_OK; | |
738 } | |
739 | |
740 loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0; | |
741 | |
742 if (r->quoted_uri || r->internal) { | |
743 escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, | |
744 r->uri.len - loc_len, NGX_ESCAPE_URI); | |
623 } else { | 745 } else { |
624 r->upstream->resolved->host = u.host; | 746 escape = 0; |
625 r->upstream->resolved->port = (in_port_t) (u.no_port ? u.default_port: | 747 } |
626 u.port); | 748 |
627 r->upstream->resolved->no_port = u.no_port; | 749 len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
628 } | 750 + sizeof("?") - 1 + r->args.len; |
751 | |
752 p = ngx_pnalloc(r->pool, len); | |
753 if (p == NULL) { | |
754 return NGX_ERROR; | |
755 } | |
756 | |
757 key->data = p; | |
758 | |
759 if (r->valid_location) { | |
760 p = ngx_copy(p, ctx->vars.uri.data, ctx->vars.uri.len); | |
761 } | |
762 | |
763 if (escape) { | |
764 ngx_escape_uri(p, r->uri.data + loc_len, | |
765 r->uri.len - loc_len, NGX_ESCAPE_URI); | |
766 p += r->uri.len - loc_len + escape; | |
767 | |
768 } else { | |
769 p = ngx_copy(p, r->uri.data + loc_len, r->uri.len - loc_len); | |
770 } | |
771 | |
772 if (r->args.len > 0) { | |
773 *p++ = '?'; | |
774 p = ngx_copy(p, r->args.data, r->args.len); | |
775 } | |
776 | |
777 key->len = p - key->data; | |
778 u->uri = *key; | |
629 | 779 |
630 return NGX_OK; | 780 return NGX_OK; |
631 } | 781 } |
782 | |
783 #endif | |
632 | 784 |
633 | 785 |
634 static ngx_int_t | 786 static ngx_int_t |
635 ngx_http_proxy_create_request(ngx_http_request_t *r) | 787 ngx_http_proxy_create_request(ngx_http_request_t *r) |
636 { | 788 { |
637 size_t len, loc_len, body_len; | 789 size_t len, uri_len, loc_len, body_len; |
638 uintptr_t escape; | 790 uintptr_t escape; |
639 ngx_buf_t *b; | 791 ngx_buf_t *b; |
640 ngx_str_t method; | 792 ngx_str_t method; |
641 ngx_uint_t i, unparsed_uri; | 793 ngx_uint_t i, unparsed_uri; |
642 ngx_chain_t *cl, *body; | 794 ngx_chain_t *cl, *body; |
673 unparsed_uri = 0; | 825 unparsed_uri = 0; |
674 | 826 |
675 ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); | 827 ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
676 | 828 |
677 if (plcf->proxy_lengths) { | 829 if (plcf->proxy_lengths) { |
678 len += ctx->vars.uri.len; | 830 uri_len = ctx->vars.uri.len; |
679 | 831 |
680 } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) | 832 } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) |
681 { | 833 { |
682 unparsed_uri = 1; | 834 unparsed_uri = 1; |
683 len += r->unparsed_uri.len; | 835 uri_len = r->unparsed_uri.len; |
684 | 836 |
685 } else { | 837 } else { |
686 loc_len = (r->valid_location && ctx->vars.uri.len) ? | 838 loc_len = (r->valid_location && ctx->vars.uri.len) ? |
687 plcf->location.len : 0; | 839 plcf->location.len : 0; |
688 | 840 |
689 if (r->quoted_uri || r->internal) { | 841 if (r->quoted_uri || r->internal) { |
690 escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, | 842 escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
691 r->uri.len - loc_len, NGX_ESCAPE_URI); | 843 r->uri.len - loc_len, NGX_ESCAPE_URI); |
692 } | 844 } |
693 | 845 |
694 len += ctx->vars.uri.len + r->uri.len - loc_len + escape | 846 uri_len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
695 + sizeof("?") - 1 + r->args.len; | 847 + sizeof("?") - 1 + r->args.len; |
696 } | 848 } |
849 | |
850 if (uri_len == 0) { | |
851 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
852 "zero length URI to proxy"); | |
853 return NGX_ERROR; | |
854 } | |
855 | |
856 len += uri_len; | |
697 | 857 |
698 ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes); | 858 ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes); |
699 | 859 |
700 if (plcf->body_set_len) { | 860 if (plcf->body_set_len) { |
701 le.ip = plcf->body_set_len->elts; | 861 le.ip = plcf->body_set_len->elts; |
978 } | 1138 } |
979 | 1139 |
980 u = r->upstream; | 1140 u = r->upstream; |
981 | 1141 |
982 if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { | 1142 if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { |
1143 | |
1144 #if (NGX_HTTP_CACHE) | |
1145 | |
1146 if (r->cache) { | |
1147 r->http_version = NGX_HTTP_VERSION_9; | |
1148 u->headers_in.status_n = NGX_HTTP_OK; | |
1149 return NGX_OK; | |
1150 } | |
1151 | |
1152 #endif | |
1153 | |
983 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 1154 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
984 "upstream sent no valid HTTP/1.0 header"); | 1155 "upstream sent no valid HTTP/1.0 header"); |
985 | 1156 |
986 #if 0 | 1157 #if 0 |
987 if (u->accel) { | 1158 if (u->accel) { |
994 u->state->status = NGX_HTTP_OK; | 1165 u->state->status = NGX_HTTP_OK; |
995 | 1166 |
996 return NGX_OK; | 1167 return NGX_OK; |
997 } | 1168 } |
998 | 1169 |
1170 if (u->state) { | |
1171 u->state->status = ctx->status; | |
1172 } | |
1173 | |
999 u->headers_in.status_n = ctx->status; | 1174 u->headers_in.status_n = ctx->status; |
1000 u->state->status = ctx->status; | |
1001 | 1175 |
1002 u->headers_in.status_line.len = ctx->status_end - ctx->status_start; | 1176 u->headers_in.status_line.len = ctx->status_end - ctx->status_start; |
1003 u->headers_in.status_line.data = ngx_pnalloc(r->pool, | 1177 u->headers_in.status_line.data = ngx_pnalloc(r->pool, |
1004 u->headers_in.status_line.len); | 1178 u->headers_in.status_line.len); |
1005 if (u->headers_in.status_line.data == NULL) { | 1179 if (u->headers_in.status_line.data == NULL) { |
1636 /* | 1810 /* |
1637 * set by ngx_pcalloc(): | 1811 * set by ngx_pcalloc(): |
1638 * | 1812 * |
1639 * conf->upstream.bufs.num = 0; | 1813 * conf->upstream.bufs.num = 0; |
1640 * conf->upstream.next_upstream = 0; | 1814 * conf->upstream.next_upstream = 0; |
1815 * conf->upstream.use_stale_cache = 0; | |
1641 * conf->upstream.temp_path = NULL; | 1816 * conf->upstream.temp_path = NULL; |
1642 * conf->upstream.hide_headers_hash = { NULL, 0 }; | 1817 * conf->upstream.hide_headers_hash = { NULL, 0 }; |
1643 * conf->upstream.uri = { 0, NULL }; | 1818 * conf->upstream.uri = { 0, NULL }; |
1644 * conf->upstream.location = NULL; | 1819 * conf->upstream.location = NULL; |
1645 * conf->upstream.store_lengths = NULL; | 1820 * conf->upstream.store_lengths = NULL; |
1673 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; | 1848 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; |
1674 | 1849 |
1675 conf->upstream.pass_request_headers = NGX_CONF_UNSET; | 1850 conf->upstream.pass_request_headers = NGX_CONF_UNSET; |
1676 conf->upstream.pass_request_body = NGX_CONF_UNSET; | 1851 conf->upstream.pass_request_body = NGX_CONF_UNSET; |
1677 | 1852 |
1853 #if (NGX_HTTP_CACHE) | |
1854 conf->upstream.cache = NGX_CONF_UNSET_PTR; | |
1855 conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; | |
1856 conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; | |
1857 #endif | |
1858 | |
1678 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; | 1859 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; |
1679 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; | 1860 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; |
1680 | 1861 |
1681 conf->upstream.intercept_errors = NGX_CONF_UNSET; | 1862 conf->upstream.intercept_errors = NGX_CONF_UNSET; |
1682 #if (NGX_HTTP_SSL) | 1863 #if (NGX_HTTP_SSL) |
1700 ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | 1881 ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
1701 { | 1882 { |
1702 ngx_http_proxy_loc_conf_t *prev = parent; | 1883 ngx_http_proxy_loc_conf_t *prev = parent; |
1703 ngx_http_proxy_loc_conf_t *conf = child; | 1884 ngx_http_proxy_loc_conf_t *conf = child; |
1704 | 1885 |
1705 u_char *p; | 1886 size_t size; |
1706 size_t size; | 1887 ngx_keyval_t *s; |
1707 uintptr_t *code; | 1888 ngx_hash_init_t hash; |
1708 ngx_uint_t i; | 1889 ngx_http_proxy_redirect_t *pr; |
1709 ngx_keyval_t *src, *s, *h; | 1890 ngx_http_script_compile_t sc; |
1710 ngx_hash_key_t *hk; | |
1711 ngx_hash_init_t hash; | |
1712 ngx_http_proxy_redirect_t *pr; | |
1713 ngx_http_script_compile_t sc; | |
1714 ngx_http_script_copy_code_t *copy; | |
1715 | 1891 |
1716 if (conf->upstream.store != 0) { | 1892 if (conf->upstream.store != 0) { |
1717 ngx_conf_merge_value(conf->upstream.store, | 1893 ngx_conf_merge_value(conf->upstream.store, |
1718 prev->upstream.store, 0); | 1894 prev->upstream.store, 0); |
1719 | 1895 |
1848 if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { | 2024 if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { |
1849 conf->upstream.next_upstream = NGX_CONF_BITMASK_SET | 2025 conf->upstream.next_upstream = NGX_CONF_BITMASK_SET |
1850 |NGX_HTTP_UPSTREAM_FT_OFF; | 2026 |NGX_HTTP_UPSTREAM_FT_OFF; |
1851 } | 2027 } |
1852 | 2028 |
1853 ngx_conf_merge_path_value(conf->upstream.temp_path, | 2029 if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path, |
1854 prev->upstream.temp_path, | 2030 prev->upstream.temp_path, |
1855 NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0, | 2031 &ngx_http_proxy_temp_path) |
1856 ngx_garbage_collector_temp_handler, cf); | 2032 != NGX_OK) |
2033 { | |
2034 return NGX_CONF_ERROR; | |
2035 } | |
2036 | |
2037 | |
2038 #if (NGX_HTTP_CACHE) | |
2039 | |
2040 ngx_conf_merge_ptr_value(conf->upstream.cache, | |
2041 prev->upstream.cache, NULL); | |
2042 | |
2043 if (conf->upstream.cache && conf->upstream.cache->data == NULL) { | |
2044 ngx_shm_zone_t *shm_zone; | |
2045 | |
2046 shm_zone = conf->upstream.cache; | |
2047 | |
2048 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2049 "\"proxy_cache\" zone \"%V\" is unknown", | |
2050 &shm_zone->name); | |
2051 | |
2052 return NGX_CONF_ERROR; | |
2053 } | |
2054 | |
2055 ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, | |
2056 prev->upstream.cache_min_uses, 1); | |
2057 | |
2058 ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, | |
2059 prev->upstream.cache_use_stale, | |
2060 (NGX_CONF_BITMASK_SET | |
2061 |NGX_HTTP_UPSTREAM_FT_OFF)); | |
2062 | |
2063 if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) { | |
2064 conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET | |
2065 |NGX_HTTP_UPSTREAM_FT_OFF; | |
2066 } | |
2067 | |
2068 ngx_conf_merge_ptr_value(conf->upstream.cache_valid, | |
2069 prev->upstream.cache_valid, NULL); | |
2070 | |
2071 if (conf->upstream.cache_valid == NULL) { | |
2072 conf->upstream.cache = NULL; | |
2073 } | |
2074 | |
2075 #endif | |
1857 | 2076 |
1858 if (conf->method.len == 0) { | 2077 if (conf->method.len == 0) { |
1859 conf->method = prev->method; | 2078 conf->method = prev->method; |
1860 | 2079 |
1861 } else { | 2080 } else { |
1982 s->key.data = (u_char *) "Content-Length"; | 2201 s->key.data = (u_char *) "Content-Length"; |
1983 s->value.len = sizeof("$proxy_internal_body_length") - 1; | 2202 s->value.len = sizeof("$proxy_internal_body_length") - 1; |
1984 s->value.data = (u_char *) "$proxy_internal_body_length"; | 2203 s->value.data = (u_char *) "$proxy_internal_body_length"; |
1985 } | 2204 } |
1986 | 2205 |
2206 if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { | |
2207 return NGX_CONF_ERROR; | |
2208 } | |
2209 | |
2210 return NGX_CONF_OK; | |
2211 } | |
2212 | |
2213 | |
2214 static ngx_int_t | |
2215 ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf, | |
2216 ngx_http_proxy_loc_conf_t *prev) | |
2217 { | |
2218 u_char *p; | |
2219 size_t size; | |
2220 uintptr_t *code; | |
2221 ngx_uint_t i; | |
2222 ngx_keyval_t *src, *s, *h; | |
2223 ngx_hash_key_t *hk; | |
2224 ngx_hash_init_t hash; | |
2225 ngx_http_script_compile_t sc; | |
2226 ngx_http_script_copy_code_t *copy; | |
1987 | 2227 |
1988 if (conf->headers_source == NULL) { | 2228 if (conf->headers_source == NULL) { |
1989 conf->flushes = prev->flushes; | 2229 conf->flushes = prev->flushes; |
1990 conf->headers_set_len = prev->headers_set_len; | 2230 conf->headers_set_len = prev->headers_set_len; |
1991 conf->headers_set = prev->headers_set; | 2231 conf->headers_set = prev->headers_set; |
1992 conf->headers_set_hash = prev->headers_set_hash; | 2232 conf->headers_set_hash = prev->headers_set_hash; |
1993 conf->headers_source = prev->headers_source; | 2233 conf->headers_source = prev->headers_source; |
1994 } | 2234 } |
1995 | 2235 |
1996 if (conf->headers_set_hash.buckets) { | 2236 if (conf->headers_set_hash.buckets) { |
1997 return NGX_CONF_OK; | 2237 return NGX_OK; |
1998 } | 2238 } |
1999 | 2239 |
2000 | 2240 |
2001 conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t)); | 2241 conf->headers_names = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t)); |
2002 if (conf->headers_names == NULL) { | 2242 if (conf->headers_names == NULL) { |
2003 return NGX_CONF_ERROR; | 2243 return NGX_ERROR; |
2004 } | 2244 } |
2005 | 2245 |
2006 if (conf->headers_source == NULL) { | 2246 if (conf->headers_source == NULL) { |
2007 conf->headers_source = ngx_array_create(cf->pool, 4, | 2247 conf->headers_source = ngx_array_create(cf->pool, 4, |
2008 sizeof(ngx_keyval_t)); | 2248 sizeof(ngx_keyval_t)); |
2009 if (conf->headers_source == NULL) { | 2249 if (conf->headers_source == NULL) { |
2010 return NGX_CONF_ERROR; | 2250 return NGX_ERROR; |
2011 } | 2251 } |
2012 } | 2252 } |
2013 | 2253 |
2014 conf->headers_set_len = ngx_array_create(cf->pool, 64, 1); | 2254 conf->headers_set_len = ngx_array_create(cf->pool, 64, 1); |
2015 if (conf->headers_set_len == NULL) { | 2255 if (conf->headers_set_len == NULL) { |
2016 return NGX_CONF_ERROR; | 2256 return NGX_ERROR; |
2017 } | 2257 } |
2018 | 2258 |
2019 conf->headers_set = ngx_array_create(cf->pool, 512, 1); | 2259 conf->headers_set = ngx_array_create(cf->pool, 512, 1); |
2020 if (conf->headers_set == NULL) { | 2260 if (conf->headers_set == NULL) { |
2021 return NGX_CONF_ERROR; | 2261 return NGX_ERROR; |
2022 } | 2262 } |
2023 | 2263 |
2024 | 2264 |
2025 src = conf->headers_source->elts; | 2265 src = conf->headers_source->elts; |
2026 | 2266 |
2032 } | 2272 } |
2033 } | 2273 } |
2034 | 2274 |
2035 s = ngx_array_push(conf->headers_source); | 2275 s = ngx_array_push(conf->headers_source); |
2036 if (s == NULL) { | 2276 if (s == NULL) { |
2037 return NGX_CONF_ERROR; | 2277 return NGX_ERROR; |
2038 } | 2278 } |
2039 | 2279 |
2040 *s = *h; | 2280 *s = *h; |
2041 | 2281 |
2042 src = conf->headers_source->elts; | 2282 src = conf->headers_source->elts; |
2050 src = conf->headers_source->elts; | 2290 src = conf->headers_source->elts; |
2051 for (i = 0; i < conf->headers_source->nelts; i++) { | 2291 for (i = 0; i < conf->headers_source->nelts; i++) { |
2052 | 2292 |
2053 hk = ngx_array_push(conf->headers_names); | 2293 hk = ngx_array_push(conf->headers_names); |
2054 if (hk == NULL) { | 2294 if (hk == NULL) { |
2055 return NGX_CONF_ERROR; | 2295 return NGX_ERROR; |
2056 } | 2296 } |
2057 | 2297 |
2058 hk->key = src[i].key; | 2298 hk->key = src[i].key; |
2059 hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len); | 2299 hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len); |
2060 hk->value = (void *) 1; | 2300 hk->value = (void *) 1; |
2065 | 2305 |
2066 if (ngx_http_script_variables_count(&src[i].value) == 0) { | 2306 if (ngx_http_script_variables_count(&src[i].value) == 0) { |
2067 copy = ngx_array_push_n(conf->headers_set_len, | 2307 copy = ngx_array_push_n(conf->headers_set_len, |
2068 sizeof(ngx_http_script_copy_code_t)); | 2308 sizeof(ngx_http_script_copy_code_t)); |
2069 if (copy == NULL) { | 2309 if (copy == NULL) { |
2070 return NGX_CONF_ERROR; | 2310 return NGX_ERROR; |
2071 } | 2311 } |
2072 | 2312 |
2073 copy->code = (ngx_http_script_code_pt) | 2313 copy->code = (ngx_http_script_code_pt) |
2074 ngx_http_script_copy_len_code; | 2314 ngx_http_script_copy_len_code; |
2075 copy->len = src[i].key.len + sizeof(": ") - 1 | 2315 copy->len = src[i].key.len + sizeof(": ") - 1 |
2082 + sizeof(uintptr_t) - 1) | 2322 + sizeof(uintptr_t) - 1) |
2083 & ~(sizeof(uintptr_t) - 1); | 2323 & ~(sizeof(uintptr_t) - 1); |
2084 | 2324 |
2085 copy = ngx_array_push_n(conf->headers_set, size); | 2325 copy = ngx_array_push_n(conf->headers_set, size); |
2086 if (copy == NULL) { | 2326 if (copy == NULL) { |
2087 return NGX_CONF_ERROR; | 2327 return NGX_ERROR; |
2088 } | 2328 } |
2089 | 2329 |
2090 copy->code = ngx_http_script_copy_code; | 2330 copy->code = ngx_http_script_copy_code; |
2091 copy->len = src[i].key.len + sizeof(": ") - 1 | 2331 copy->len = src[i].key.len + sizeof(": ") - 1 |
2092 + src[i].value.len + sizeof(CRLF) - 1; | 2332 + src[i].value.len + sizeof(CRLF) - 1; |
2100 | 2340 |
2101 } else { | 2341 } else { |
2102 copy = ngx_array_push_n(conf->headers_set_len, | 2342 copy = ngx_array_push_n(conf->headers_set_len, |
2103 sizeof(ngx_http_script_copy_code_t)); | 2343 sizeof(ngx_http_script_copy_code_t)); |
2104 if (copy == NULL) { | 2344 if (copy == NULL) { |
2105 return NGX_CONF_ERROR; | 2345 return NGX_ERROR; |
2106 } | 2346 } |
2107 | 2347 |
2108 copy->code = (ngx_http_script_code_pt) | 2348 copy->code = (ngx_http_script_code_pt) |
2109 ngx_http_script_copy_len_code; | 2349 ngx_http_script_copy_len_code; |
2110 copy->len = src[i].key.len + sizeof(": ") - 1; | 2350 copy->len = src[i].key.len + sizeof(": ") - 1; |
2114 + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) | 2354 + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) |
2115 & ~(sizeof(uintptr_t) - 1); | 2355 & ~(sizeof(uintptr_t) - 1); |
2116 | 2356 |
2117 copy = ngx_array_push_n(conf->headers_set, size); | 2357 copy = ngx_array_push_n(conf->headers_set, size); |
2118 if (copy == NULL) { | 2358 if (copy == NULL) { |
2119 return NGX_CONF_ERROR; | 2359 return NGX_ERROR; |
2120 } | 2360 } |
2121 | 2361 |
2122 copy->code = ngx_http_script_copy_code; | 2362 copy->code = ngx_http_script_copy_code; |
2123 copy->len = src[i].key.len + sizeof(": ") - 1; | 2363 copy->len = src[i].key.len + sizeof(": ") - 1; |
2124 | 2364 |
2134 sc.flushes = &conf->flushes; | 2374 sc.flushes = &conf->flushes; |
2135 sc.lengths = &conf->headers_set_len; | 2375 sc.lengths = &conf->headers_set_len; |
2136 sc.values = &conf->headers_set; | 2376 sc.values = &conf->headers_set; |
2137 | 2377 |
2138 if (ngx_http_script_compile(&sc) != NGX_OK) { | 2378 if (ngx_http_script_compile(&sc) != NGX_OK) { |
2139 return NGX_CONF_ERROR; | 2379 return NGX_ERROR; |
2140 } | 2380 } |
2141 | 2381 |
2142 | 2382 |
2143 copy = ngx_array_push_n(conf->headers_set_len, | 2383 copy = ngx_array_push_n(conf->headers_set_len, |
2144 sizeof(ngx_http_script_copy_code_t)); | 2384 sizeof(ngx_http_script_copy_code_t)); |
2145 if (copy == NULL) { | 2385 if (copy == NULL) { |
2146 return NGX_CONF_ERROR; | 2386 return NGX_ERROR; |
2147 } | 2387 } |
2148 | 2388 |
2149 copy->code = (ngx_http_script_code_pt) | 2389 copy->code = (ngx_http_script_code_pt) |
2150 ngx_http_script_copy_len_code; | 2390 ngx_http_script_copy_len_code; |
2151 copy->len = sizeof(CRLF) - 1; | 2391 copy->len = sizeof(CRLF) - 1; |
2155 + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) | 2395 + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) |
2156 & ~(sizeof(uintptr_t) - 1); | 2396 & ~(sizeof(uintptr_t) - 1); |
2157 | 2397 |
2158 copy = ngx_array_push_n(conf->headers_set, size); | 2398 copy = ngx_array_push_n(conf->headers_set, size); |
2159 if (copy == NULL) { | 2399 if (copy == NULL) { |
2160 return NGX_CONF_ERROR; | 2400 return NGX_ERROR; |
2161 } | 2401 } |
2162 | 2402 |
2163 copy->code = ngx_http_script_copy_code; | 2403 copy->code = ngx_http_script_copy_code; |
2164 copy->len = sizeof(CRLF) - 1; | 2404 copy->len = sizeof(CRLF) - 1; |
2165 | 2405 |
2167 *p++ = CR; *p = LF; | 2407 *p++ = CR; *p = LF; |
2168 } | 2408 } |
2169 | 2409 |
2170 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); | 2410 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); |
2171 if (code == NULL) { | 2411 if (code == NULL) { |
2172 return NGX_CONF_ERROR; | 2412 return NGX_ERROR; |
2173 } | 2413 } |
2174 | 2414 |
2175 *code = (uintptr_t) NULL; | 2415 *code = (uintptr_t) NULL; |
2176 | 2416 |
2177 code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t)); | 2417 code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t)); |
2178 if (code == NULL) { | 2418 if (code == NULL) { |
2179 return NGX_CONF_ERROR; | 2419 return NGX_ERROR; |
2180 } | 2420 } |
2181 | 2421 |
2182 *code = (uintptr_t) NULL; | 2422 *code = (uintptr_t) NULL; |
2183 } | 2423 } |
2184 | 2424 |
2185 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); | 2425 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); |
2186 if (code == NULL) { | 2426 if (code == NULL) { |
2187 return NGX_CONF_ERROR; | 2427 return NGX_ERROR; |
2188 } | 2428 } |
2189 | 2429 |
2190 *code = (uintptr_t) NULL; | 2430 *code = (uintptr_t) NULL; |
2191 | 2431 |
2192 | 2432 |
2200 | 2440 |
2201 if (ngx_hash_init(&hash, conf->headers_names->elts, | 2441 if (ngx_hash_init(&hash, conf->headers_names->elts, |
2202 conf->headers_names->nelts) | 2442 conf->headers_names->nelts) |
2203 != NGX_OK) | 2443 != NGX_OK) |
2204 { | 2444 { |
2205 return NGX_CONF_ERROR; | 2445 return NGX_ERROR; |
2206 } | 2446 } |
2207 | 2447 |
2208 return NGX_CONF_OK; | 2448 return NGX_OK; |
2209 } | 2449 } |
2210 | 2450 |
2211 | 2451 |
2212 static char * | 2452 static char * |
2213 ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2453 ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
2296 plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); | 2536 plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
2297 if (plcf->upstream.upstream == NULL) { | 2537 if (plcf->upstream.upstream == NULL) { |
2298 return NGX_CONF_ERROR; | 2538 return NGX_CONF_ERROR; |
2299 } | 2539 } |
2300 | 2540 |
2301 if (ngx_http_proxy_set_vars(cf->pool, &u, &plcf->vars) != NGX_OK) { | |
2302 return NGX_CONF_ERROR; | |
2303 } | |
2304 | |
2305 plcf->vars.schema.len = add; | 2541 plcf->vars.schema.len = add; |
2306 plcf->vars.schema.data = url->data; | 2542 plcf->vars.schema.data = url->data; |
2543 plcf->vars.key_start = plcf->vars.schema; | |
2544 | |
2545 ngx_http_proxy_set_vars(&u, &plcf->vars); | |
2546 | |
2547 clcf->handler = ngx_http_proxy_handler; | |
2548 | |
2307 plcf->location = clcf->name; | 2549 plcf->location = clcf->name; |
2308 | |
2309 clcf->handler = ngx_http_proxy_handler; | |
2310 | 2550 |
2311 if (clcf->named | 2551 if (clcf->named |
2312 #if (NGX_PCRE) | 2552 #if (NGX_PCRE) |
2313 || clcf->regex | 2553 || clcf->regex |
2314 #endif | 2554 #endif |
2471 | 2711 |
2472 return NGX_CONF_OK; | 2712 return NGX_CONF_OK; |
2473 } | 2713 } |
2474 | 2714 |
2475 | 2715 |
2716 #if (NGX_HTTP_CACHE) | |
2717 | |
2718 static char * | |
2719 ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
2720 { | |
2721 ngx_http_proxy_loc_conf_t *plcf = conf; | |
2722 | |
2723 ngx_str_t *value; | |
2724 | |
2725 value = cf->args->elts; | |
2726 | |
2727 if (plcf->upstream.cache != NGX_CONF_UNSET_PTR) { | |
2728 return "is duplicate"; | |
2729 } | |
2730 | |
2731 if (ngx_strcmp(value[1].data, "off") == 0) { | |
2732 plcf->upstream.cache = NULL; | |
2733 return NGX_CONF_OK; | |
2734 } | |
2735 | |
2736 plcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0, | |
2737 &ngx_http_proxy_module); | |
2738 if (plcf->upstream.cache == NULL) { | |
2739 return NGX_CONF_ERROR; | |
2740 } | |
2741 | |
2742 return NGX_CONF_OK; | |
2743 } | |
2744 | |
2745 #endif | |
2746 | |
2747 | |
2476 static char * | 2748 static char * |
2477 ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) | 2749 ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) |
2478 { | 2750 { |
2479 #if (NGX_FREEBSD) | 2751 #if (NGX_FREEBSD) |
2480 ssize_t *np = data; | 2752 ssize_t *np = data; |
2561 } | 2833 } |
2562 | 2834 |
2563 #endif | 2835 #endif |
2564 | 2836 |
2565 | 2837 |
2566 static ngx_int_t | 2838 static void |
2567 ngx_http_proxy_set_vars(ngx_pool_t *pool, ngx_url_t *u, | 2839 ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v) |
2568 ngx_http_proxy_vars_t *v) | |
2569 { | 2840 { |
2570 if (u->family != AF_UNIX) { | 2841 if (u->family != AF_UNIX) { |
2842 | |
2571 if (u->no_port || u->port == u->default_port) { | 2843 if (u->no_port || u->port == u->default_port) { |
2844 | |
2572 v->host_header = u->host; | 2845 v->host_header = u->host; |
2573 | 2846 |
2574 if (u->default_port == 80) { | 2847 if (u->default_port == 80) { |
2575 v->port.len = sizeof("80") - 1; | 2848 v->port.len = sizeof("80") - 1; |
2576 v->port.data = (u_char *) "80"; | 2849 v->port.data = (u_char *) "80"; |
2583 } else { | 2856 } else { |
2584 v->host_header.len = u->host.len + 1 + u->port_text.len; | 2857 v->host_header.len = u->host.len + 1 + u->port_text.len; |
2585 v->host_header.data = u->host.data; | 2858 v->host_header.data = u->host.data; |
2586 v->port = u->port_text; | 2859 v->port = u->port_text; |
2587 } | 2860 } |
2861 | |
2862 v->key_start.len += v->host_header.len; | |
2588 | 2863 |
2589 } else { | 2864 } else { |
2590 v->host_header.len = sizeof("localhost") - 1; | 2865 v->host_header.len = sizeof("localhost") - 1; |
2591 v->host_header.data = (u_char *) "localhost"; | 2866 v->host_header.data = (u_char *) "localhost"; |
2592 v->port.len = 0; | 2867 v->port.len = 0; |
2593 v->port.data = (u_char *) ""; | 2868 v->port.data = (u_char *) ""; |
2869 v->key_start.len += sizeof("unix:") - 1 + u->host.len + 1; | |
2594 } | 2870 } |
2595 | 2871 |
2596 v->uri = u->uri; | 2872 v->uri = u->uri; |
2597 | 2873 } |
2598 return NGX_OK; | |
2599 } |