Mercurial > hg > nginx-vendor-1-0
comparison src/http/ngx_http_upstream.c @ 200:d2ae1c9f1fd3 NGINX_0_3_47
nginx 0.3.47
*) Feature: the "upstream" directive.
*) Change: now the "\" escape symbol in the "\"" and "\'" pairs in the
SSI command is always removed.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 23 May 2006 00:00:00 +0400 |
parents | e6da4931e0e0 |
children | ca5f86d94316 |
comparison
equal
deleted
inserted
replaced
199:869664706c09 | 200:d2ae1c9f1fd3 |
---|---|
83 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, | 83 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, |
84 ngx_http_variable_value_t *v, uintptr_t data); | 84 ngx_http_variable_value_t *v, uintptr_t data); |
85 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, | 85 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, |
86 ngx_http_variable_value_t *v, uintptr_t data); | 86 ngx_http_variable_value_t *v, uintptr_t data); |
87 | 87 |
88 static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); | |
89 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, | |
90 void *conf); | |
91 | |
88 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); | 92 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); |
89 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); | 93 static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); |
90 | 94 |
91 #if (NGX_HTTP_SSL) | 95 #if (NGX_HTTP_SSL) |
92 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, | 96 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, |
93 ngx_http_upstream_t *u, ngx_connection_t *c); | 97 ngx_http_upstream_t *u, ngx_connection_t *c); |
94 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); | 98 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); |
204 | 208 |
205 { ngx_null_string, NULL, 0, NULL, 0, 0 } | 209 { ngx_null_string, NULL, 0, NULL, 0, 0 } |
206 }; | 210 }; |
207 | 211 |
208 | 212 |
209 ngx_http_module_t ngx_http_upstream_module_ctx = { | 213 static ngx_command_t ngx_http_upstream_commands[] = { |
214 | |
215 { ngx_string("upstream"), | |
216 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, | |
217 ngx_http_upstream, | |
218 0, | |
219 0, | |
220 NULL }, | |
221 | |
222 { ngx_string("server"), | |
223 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, | |
224 ngx_http_upstream_server, | |
225 NGX_HTTP_SRV_CONF_OFFSET, | |
226 0, | |
227 NULL }, | |
228 | |
229 ngx_null_command | |
230 }; | |
231 | |
232 | |
233 static ngx_http_module_t ngx_http_upstream_module_ctx = { | |
210 ngx_http_upstream_add_variables, /* preconfiguration */ | 234 ngx_http_upstream_add_variables, /* preconfiguration */ |
211 NULL, /* postconfiguration */ | 235 NULL, /* postconfiguration */ |
212 | 236 |
213 ngx_http_upstream_create_main_conf, /* create main configuration */ | 237 ngx_http_upstream_create_main_conf, /* create main configuration */ |
214 ngx_http_core_init_main_conf, /* init main configuration */ | 238 ngx_http_upstream_init_main_conf, /* init main configuration */ |
215 | 239 |
216 NULL, /* create server configuration */ | 240 NULL, /* create server configuration */ |
217 NULL, /* merge server configuration */ | 241 NULL, /* merge server configuration */ |
218 | 242 |
219 NULL, /* create location configuration */ | 243 NULL, /* create location configuration */ |
222 | 246 |
223 | 247 |
224 ngx_module_t ngx_http_upstream_module = { | 248 ngx_module_t ngx_http_upstream_module = { |
225 NGX_MODULE_V1, | 249 NGX_MODULE_V1, |
226 &ngx_http_upstream_module_ctx, /* module context */ | 250 &ngx_http_upstream_module_ctx, /* module context */ |
227 NULL, /* module directives */ | 251 ngx_http_upstream_commands, /* module directives */ |
228 NGX_HTTP_MODULE, /* module type */ | 252 NGX_HTTP_MODULE, /* module type */ |
229 NULL, /* init master */ | 253 NULL, /* init master */ |
230 NULL, /* init module */ | 254 NULL, /* init module */ |
231 NULL, /* init process */ | 255 NULL, /* init process */ |
232 NULL, /* init thread */ | 256 NULL, /* init thread */ |
865 ngx_http_upstream_ssl_init_connection(r, u, c); | 889 ngx_http_upstream_ssl_init_connection(r, u, c); |
866 return; | 890 return; |
867 } | 891 } |
868 | 892 |
869 #endif | 893 #endif |
894 | |
895 if (u->header_sent) { | |
896 wev->handler = ngx_http_upstream_dummy_handler; | |
897 | |
898 (void) ngx_handle_write_event(wev, 0); | |
899 | |
900 return; | |
901 } | |
870 | 902 |
871 ngx_http_upstream_send_request(r, u); | 903 ngx_http_upstream_send_request(r, u); |
872 } | 904 } |
873 | 905 |
874 | 906 |
2545 | 2577 |
2546 return NGX_OK; | 2578 return NGX_OK; |
2547 } | 2579 } |
2548 | 2580 |
2549 | 2581 |
2582 static char * | |
2583 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | |
2584 { | |
2585 char *rv; | |
2586 void *mconf; | |
2587 ngx_str_t *value; | |
2588 ngx_url_t u; | |
2589 ngx_uint_t i, j, m, n; | |
2590 ngx_conf_t pcf; | |
2591 ngx_peers_t **peers; | |
2592 ngx_http_module_t *module; | |
2593 ngx_http_conf_ctx_t *ctx; | |
2594 ngx_http_upstream_srv_conf_t *uscf; | |
2595 | |
2596 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); | |
2597 if (ctx == NULL) { | |
2598 return NGX_CONF_ERROR; | |
2599 } | |
2600 | |
2601 ngx_memzero(&u, sizeof(ngx_url_t)); | |
2602 | |
2603 value = cf->args->elts; | |
2604 u.host = value[1]; | |
2605 | |
2606 uscf = ngx_http_upstream_add(cf, &u); | |
2607 if (uscf == NULL) { | |
2608 return NGX_CONF_ERROR; | |
2609 } | |
2610 | |
2611 /* the upstream{}'s srv_conf */ | |
2612 | |
2613 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
2614 if (ctx->srv_conf == NULL) { | |
2615 return NGX_CONF_ERROR; | |
2616 } | |
2617 | |
2618 ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf; | |
2619 | |
2620 | |
2621 /* the upstream{}'s loc_conf */ | |
2622 | |
2623 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
2624 if (ctx->loc_conf == NULL) { | |
2625 return NGX_CONF_ERROR; | |
2626 } | |
2627 | |
2628 for (m = 0; ngx_modules[m]; m++) { | |
2629 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | |
2630 continue; | |
2631 } | |
2632 | |
2633 module = ngx_modules[m]->ctx; | |
2634 | |
2635 if (module->create_loc_conf) { | |
2636 mconf = module->create_loc_conf(cf); | |
2637 if (mconf == NULL) { | |
2638 return NGX_CONF_ERROR; | |
2639 } | |
2640 | |
2641 ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf; | |
2642 } | |
2643 } | |
2644 | |
2645 | |
2646 /* parse inside upstream{} */ | |
2647 | |
2648 pcf = *cf; | |
2649 cf->ctx = ctx; | |
2650 cf->cmd_type = NGX_HTTP_UPS_CONF; | |
2651 | |
2652 rv = ngx_conf_parse(cf, NULL); | |
2653 | |
2654 *cf = pcf; | |
2655 | |
2656 if (rv != NGX_CONF_OK) { | |
2657 return rv; | |
2658 } | |
2659 | |
2660 if (uscf->servers == NULL) { | |
2661 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2662 "no servers are inside upstream"); | |
2663 return NGX_CONF_ERROR; | |
2664 } | |
2665 | |
2666 peers = uscf->servers->elts; | |
2667 | |
2668 if (uscf->servers->nelts == 1) { | |
2669 uscf->peers = peers[0]; | |
2670 } | |
2671 | |
2672 n = 0; | |
2673 | |
2674 for (i = 0; i < uscf->servers->nelts; i++) { | |
2675 n += peers[i]->number; | |
2676 } | |
2677 | |
2678 uscf->peers = ngx_pcalloc(cf->pool, | |
2679 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (n - 1)); | |
2680 if (uscf->peers == NULL) { | |
2681 return NGX_CONF_ERROR; | |
2682 } | |
2683 | |
2684 uscf->peers->number = n; | |
2685 uscf->peers->weight = 1; | |
2686 | |
2687 n = 0; | |
2688 | |
2689 for (i = 0; i < uscf->servers->nelts; i++) { | |
2690 for (j = 0; j < peers[i]->number; j++) { | |
2691 uscf->peers->peer[n++] = peers[i]->peer[j]; | |
2692 } | |
2693 } | |
2694 | |
2695 return rv; | |
2696 } | |
2697 | |
2698 | |
2699 static char * | |
2700 ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
2701 { | |
2702 ngx_http_upstream_srv_conf_t *uscf = conf; | |
2703 | |
2704 ngx_str_t *value; | |
2705 ngx_url_t u; | |
2706 ngx_peers_t **peers; | |
2707 | |
2708 if (uscf->servers == NULL) { | |
2709 uscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_peers_t *)); | |
2710 if (uscf->servers == NULL) { | |
2711 return NGX_CONF_ERROR; | |
2712 } | |
2713 } | |
2714 | |
2715 peers = ngx_array_push(uscf->servers); | |
2716 if (peers == NULL) { | |
2717 return NGX_CONF_ERROR; | |
2718 } | |
2719 | |
2720 value = cf->args->elts; | |
2721 | |
2722 ngx_memzero(&u, sizeof(ngx_url_t)); | |
2723 | |
2724 u.url = value[1]; | |
2725 u.default_portn = 80; | |
2726 | |
2727 if (ngx_parse_url(cf, &u) != NGX_OK) { | |
2728 if (u.err) { | |
2729 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2730 "%s in upstream \"%V\"", u.err, &u.url); | |
2731 } | |
2732 | |
2733 return NGX_CONF_ERROR; | |
2734 } | |
2735 | |
2736 *peers = u.peers; | |
2737 | |
2738 return NGX_CONF_OK; | |
2739 } | |
2740 | |
2741 | |
2742 ngx_http_upstream_srv_conf_t * | |
2743 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u) | |
2744 { | |
2745 ngx_uint_t i; | |
2746 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | |
2747 ngx_http_upstream_main_conf_t *umcf; | |
2748 | |
2749 if (u->upstream) { | |
2750 if (ngx_parse_url(cf, u) != NGX_OK) { | |
2751 if (u->err) { | |
2752 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2753 "%s in upstream \"%V\"", u->err, &u->url); | |
2754 } | |
2755 | |
2756 return NULL; | |
2757 } | |
2758 | |
2759 if (u->peers) { | |
2760 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); | |
2761 if (uscf == NULL) { | |
2762 return NULL; | |
2763 } | |
2764 | |
2765 uscf->peers = u->peers; | |
2766 | |
2767 return uscf; | |
2768 } | |
2769 } | |
2770 | |
2771 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); | |
2772 | |
2773 uscfp = umcf->upstreams.elts; | |
2774 | |
2775 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
2776 if (uscfp[i]->host.len != u->host.len) { | |
2777 continue; | |
2778 } | |
2779 | |
2780 if (ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) | |
2781 == 0) | |
2782 { | |
2783 return uscfp[i]; | |
2784 } | |
2785 } | |
2786 | |
2787 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); | |
2788 if (uscf == NULL) { | |
2789 return NULL; | |
2790 } | |
2791 | |
2792 uscf->host = u->host; | |
2793 uscf->file_name = cf->conf_file->file.name; | |
2794 uscf->line = cf->conf_file->line; | |
2795 uscf->port = u->default_portn; | |
2796 | |
2797 uscfp = ngx_array_push(&umcf->upstreams); | |
2798 if (uscfp == NULL) { | |
2799 return NULL; | |
2800 } | |
2801 | |
2802 *uscfp = uscf; | |
2803 | |
2804 return uscf; | |
2805 } | |
2806 | |
2807 | |
2550 static void * | 2808 static void * |
2551 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) | 2809 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) |
2552 { | 2810 { |
2553 ngx_http_upstream_main_conf_t *umcf; | 2811 ngx_http_upstream_main_conf_t *umcf; |
2554 | 2812 |
2555 umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t)); | 2813 umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t)); |
2556 if (umcf == NULL) { | 2814 if (umcf == NULL) { |
2557 return NULL; | 2815 return NULL; |
2558 } | 2816 } |
2559 | 2817 |
2818 if (ngx_array_init(&umcf->upstreams, cf->pool, 4, | |
2819 sizeof(ngx_http_upstream_srv_conf_t *)) | |
2820 != NGX_OK) | |
2821 { | |
2822 return NGX_CONF_ERROR; | |
2823 } | |
2824 | |
2560 return umcf; | 2825 return umcf; |
2561 } | 2826 } |
2562 | 2827 |
2563 | 2828 |
2564 static char * | 2829 static char * |
2565 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) | 2830 ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf) |
2566 { | 2831 { |
2567 ngx_http_upstream_main_conf_t *umcf = conf; | 2832 ngx_http_upstream_main_conf_t *umcf = conf; |
2568 | 2833 |
2569 ngx_array_t headers_in; | 2834 ngx_uint_t i; |
2570 ngx_hash_key_t *hk; | 2835 ngx_array_t headers_in; |
2571 ngx_hash_init_t hash; | 2836 ngx_hash_key_t *hk; |
2572 ngx_http_upstream_header_t *header; | 2837 ngx_hash_init_t hash; |
2838 ngx_http_upstream_header_t *header; | |
2839 ngx_http_upstream_srv_conf_t **uscfp; | |
2840 | |
2841 uscfp = umcf->upstreams.elts; | |
2842 | |
2843 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
2844 if (uscfp[i]->peers) { | |
2845 continue; | |
2846 } | |
2847 | |
2848 uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host, | |
2849 uscfp[i]->port); | |
2850 | |
2851 if (uscfp[i]->peers == NULL) { | |
2852 return NGX_CONF_ERROR; | |
2853 } | |
2854 | |
2855 if (uscfp[i]->peers == NGX_CONF_ERROR) { | |
2856 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
2857 "upstream host \"%V\" is not found in %s:%ui", | |
2858 &uscfp[i]->host, uscfp[i]->file_name.data, | |
2859 uscfp[i]->line); | |
2860 return NGX_CONF_ERROR; | |
2861 } | |
2862 } | |
2573 | 2863 |
2574 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) | 2864 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) |
2575 != NGX_OK) | 2865 != NGX_OK) |
2576 { | 2866 { |
2577 return NGX_CONF_ERROR; | 2867 return NGX_CONF_ERROR; |