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;