Mercurial > hg > nginx
annotate src/stream/ngx_stream_upstream.c @ 7906:058a67435e83
Upstream: fixed timeouts with gRPC, SSL and select (ticket #2229).
With SSL it is possible that an established connection is ready for
reading after the handshake. Further, events might be already disabled
in case of level-triggered event methods. If this happens and
ngx_http_upstream_send_request() blocks waiting for some data from
the upstream, such as flow control in case of gRPC, the connection
will time out due to no read events on the upstream connection.
Fix is to explicitly check the c->read->ready flag if sending request
blocks and post a read event if it is set.
Note that while it is possible to modify ngx_ssl_handshake() to keep
read events active, this won't completely resolve the issue, since
there can be data already received during the SSL handshake
(see 573bd30e46b4).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 20 Aug 2021 03:53:56 +0300 |
parents | 860d3907da1c |
children |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_stream.h> | |
11 | |
12 | |
6675
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
13 static ngx_int_t ngx_stream_upstream_add_variables(ngx_conf_t *cf); |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
14 static ngx_int_t ngx_stream_upstream_addr_variable(ngx_stream_session_t *s, |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
15 ngx_stream_variable_value_t *v, uintptr_t data); |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
16 static ngx_int_t ngx_stream_upstream_response_time_variable( |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
17 ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data); |
6676
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
18 static ngx_int_t ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
19 ngx_stream_variable_value_t *v, uintptr_t data); |
6675
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
20 |
6115 | 21 static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, |
22 void *dummy); | |
23 static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, | |
24 void *conf); | |
25 static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf); | |
26 static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf); | |
27 | |
28 | |
29 static ngx_command_t ngx_stream_upstream_commands[] = { | |
30 | |
31 { ngx_string("upstream"), | |
32 NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, | |
33 ngx_stream_upstream, | |
34 0, | |
35 0, | |
36 NULL }, | |
37 | |
38 { ngx_string("server"), | |
39 NGX_STREAM_UPS_CONF|NGX_CONF_1MORE, | |
40 ngx_stream_upstream_server, | |
41 NGX_STREAM_SRV_CONF_OFFSET, | |
42 0, | |
43 NULL }, | |
44 | |
45 ngx_null_command | |
46 }; | |
47 | |
48 | |
49 static ngx_stream_module_t ngx_stream_upstream_module_ctx = { | |
6675
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
50 ngx_stream_upstream_add_variables, /* preconfiguration */ |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6115
diff
changeset
|
51 NULL, /* postconfiguration */ |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6115
diff
changeset
|
52 |
6115 | 53 ngx_stream_upstream_create_main_conf, /* create main configuration */ |
54 ngx_stream_upstream_init_main_conf, /* init main configuration */ | |
55 | |
56 NULL, /* create server configuration */ | |
6629 | 57 NULL /* merge server configuration */ |
6115 | 58 }; |
59 | |
60 | |
61 ngx_module_t ngx_stream_upstream_module = { | |
62 NGX_MODULE_V1, | |
63 &ngx_stream_upstream_module_ctx, /* module context */ | |
64 ngx_stream_upstream_commands, /* module directives */ | |
65 NGX_STREAM_MODULE, /* module type */ | |
66 NULL, /* init master */ | |
67 NULL, /* init module */ | |
68 NULL, /* init process */ | |
69 NULL, /* init thread */ | |
70 NULL, /* exit thread */ | |
71 NULL, /* exit process */ | |
72 NULL, /* exit master */ | |
73 NGX_MODULE_V1_PADDING | |
74 }; | |
75 | |
76 | |
6675
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
77 static ngx_stream_variable_t ngx_stream_upstream_vars[] = { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
78 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
79 { ngx_string("upstream_addr"), NULL, |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
80 ngx_stream_upstream_addr_variable, 0, |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
81 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
82 |
6676
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
83 { ngx_string("upstream_bytes_sent"), NULL, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
84 ngx_stream_upstream_bytes_variable, 0, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
85 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
86 |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
87 { ngx_string("upstream_connect_time"), NULL, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
88 ngx_stream_upstream_response_time_variable, 2, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
89 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
90 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
91 { ngx_string("upstream_first_byte_time"), NULL, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
92 ngx_stream_upstream_response_time_variable, 1, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
93 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
94 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
95 { ngx_string("upstream_session_time"), NULL, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
96 ngx_stream_upstream_response_time_variable, 0, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
97 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
98 |
6676
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
99 { ngx_string("upstream_bytes_received"), NULL, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
100 ngx_stream_upstream_bytes_variable, 1, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
101 NGX_STREAM_VAR_NOCACHEABLE, 0 }, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
102 |
7077
2a288909abc6
Variables: macros for null variables.
Ruslan Ermilov <ru@nginx.com>
parents:
6705
diff
changeset
|
103 ngx_stream_null_variable |
6675
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
104 }; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
105 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
106 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
107 static ngx_int_t |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
108 ngx_stream_upstream_add_variables(ngx_conf_t *cf) |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
109 { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
110 ngx_stream_variable_t *var, *v; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
111 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
112 for (v = ngx_stream_upstream_vars; v->name.len; v++) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
113 var = ngx_stream_add_variable(cf, &v->name, v->flags); |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
114 if (var == NULL) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
115 return NGX_ERROR; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
116 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
117 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
118 var->get_handler = v->get_handler; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
119 var->data = v->data; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
120 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
121 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
122 return NGX_OK; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
123 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
124 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
125 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
126 static ngx_int_t |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
127 ngx_stream_upstream_addr_variable(ngx_stream_session_t *s, |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
128 ngx_stream_variable_value_t *v, uintptr_t data) |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
129 { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
130 u_char *p; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
131 size_t len; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
132 ngx_uint_t i; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
133 ngx_stream_upstream_state_t *state; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
134 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
135 v->valid = 1; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
136 v->no_cacheable = 0; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
137 v->not_found = 0; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
138 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
139 if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
140 v->not_found = 1; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
141 return NGX_OK; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
142 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
143 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
144 len = 0; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
145 state = s->upstream_states->elts; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
146 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
147 for (i = 0; i < s->upstream_states->nelts; i++) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
148 if (state[i].peer) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
149 len += state[i].peer->len; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
150 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
151 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
152 len += 2; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
153 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
154 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
155 p = ngx_pnalloc(s->connection->pool, len); |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
156 if (p == NULL) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
157 return NGX_ERROR; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
158 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
159 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
160 v->data = p; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
161 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
162 i = 0; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
163 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
164 for ( ;; ) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
165 if (state[i].peer) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
166 p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len); |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
167 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
168 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
169 if (++i == s->upstream_states->nelts) { |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
170 break; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
171 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
172 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
173 *p++ = ','; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
174 *p++ = ' '; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
175 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
176 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
177 v->len = p - v->data; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
178 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
179 return NGX_OK; |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
180 } |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
181 |
ab9b4fd8c5b7
Stream: the $upstream_addr variable.
Vladimir Homutov <vl@nginx.com>
parents:
6629
diff
changeset
|
182 |
6676
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
183 static ngx_int_t |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
184 ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s, |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
185 ngx_stream_variable_value_t *v, uintptr_t data) |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
186 { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
187 u_char *p; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
188 size_t len; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
189 ngx_uint_t i; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
190 ngx_stream_upstream_state_t *state; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
191 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
192 v->valid = 1; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
193 v->no_cacheable = 0; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
194 v->not_found = 0; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
195 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
196 if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
197 v->not_found = 1; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
198 return NGX_OK; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
199 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
200 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
201 len = s->upstream_states->nelts * (NGX_OFF_T_LEN + 2); |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
202 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
203 p = ngx_pnalloc(s->connection->pool, len); |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
204 if (p == NULL) { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
205 return NGX_ERROR; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
206 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
207 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
208 v->data = p; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
209 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
210 i = 0; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
211 state = s->upstream_states->elts; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
212 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
213 for ( ;; ) { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
214 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
215 if (data == 1) { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
216 p = ngx_sprintf(p, "%O", state[i].bytes_received); |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
217 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
218 } else { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
219 p = ngx_sprintf(p, "%O", state[i].bytes_sent); |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
220 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
221 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
222 if (++i == s->upstream_states->nelts) { |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
223 break; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
224 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
225 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
226 *p++ = ','; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
227 *p++ = ' '; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
228 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
229 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
230 v->len = p - v->data; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
231 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
232 return NGX_OK; |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
233 } |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
234 |
df3a7c029dec
Stream: $upstream_bytes_sent and $upstream_bytes_received.
Vladimir Homutov <vl@nginx.com>
parents:
6675
diff
changeset
|
235 |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
236 static ngx_int_t |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
237 ngx_stream_upstream_response_time_variable(ngx_stream_session_t *s, |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
238 ngx_stream_variable_value_t *v, uintptr_t data) |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
239 { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
240 u_char *p; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
241 size_t len; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
242 ngx_uint_t i; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
243 ngx_msec_int_t ms; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
244 ngx_stream_upstream_state_t *state; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
245 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
246 v->valid = 1; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
247 v->no_cacheable = 0; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
248 v->not_found = 0; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
249 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
250 if (s->upstream_states == NULL || s->upstream_states->nelts == 0) { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
251 v->not_found = 1; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
252 return NGX_OK; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
253 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
254 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
255 len = s->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2); |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
256 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
257 p = ngx_pnalloc(s->connection->pool, len); |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
258 if (p == NULL) { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
259 return NGX_ERROR; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
260 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
261 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
262 v->data = p; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
263 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
264 i = 0; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
265 state = s->upstream_states->elts; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
266 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
267 for ( ;; ) { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
268 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
269 if (data == 1) { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
270 ms = state[i].first_byte_time; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
271 |
7397
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
272 } else if (data == 2) { |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
273 ms = state[i].connect_time; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
274 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
275 } else { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
276 ms = state[i].response_time; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
277 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
278 |
7397
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
279 if (ms != -1) { |
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
280 ms = ngx_max(ms, 0); |
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
281 p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000); |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
282 |
7397
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
283 } else { |
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
284 *p++ = '-'; |
860d3907da1c
Upstream: revised upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
7077
diff
changeset
|
285 } |
6677
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
286 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
287 if (++i == s->upstream_states->nelts) { |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
288 break; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
289 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
290 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
291 *p++ = ','; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
292 *p++ = ' '; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
293 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
294 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
295 v->len = p - v->data; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
296 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
297 return NGX_OK; |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
298 } |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
299 |
c02290241cbe
Stream: upstream response time variables.
Vladimir Homutov <vl@nginx.com>
parents:
6676
diff
changeset
|
300 |
6115 | 301 static char * |
302 ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | |
303 { | |
304 char *rv; | |
305 void *mconf; | |
306 ngx_str_t *value; | |
307 ngx_url_t u; | |
308 ngx_uint_t m; | |
309 ngx_conf_t pcf; | |
310 ngx_stream_module_t *module; | |
311 ngx_stream_conf_ctx_t *ctx, *stream_ctx; | |
312 ngx_stream_upstream_srv_conf_t *uscf; | |
313 | |
314 ngx_memzero(&u, sizeof(ngx_url_t)); | |
315 | |
316 value = cf->args->elts; | |
317 u.host = value[1]; | |
318 u.no_resolve = 1; | |
319 u.no_port = 1; | |
320 | |
321 uscf = ngx_stream_upstream_add(cf, &u, NGX_STREAM_UPSTREAM_CREATE | |
322 |NGX_STREAM_UPSTREAM_WEIGHT | |
6705 | 323 |NGX_STREAM_UPSTREAM_MAX_CONNS |
6115 | 324 |NGX_STREAM_UPSTREAM_MAX_FAILS |
325 |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT | |
326 |NGX_STREAM_UPSTREAM_DOWN | |
327 |NGX_STREAM_UPSTREAM_BACKUP); | |
328 if (uscf == NULL) { | |
329 return NGX_CONF_ERROR; | |
330 } | |
331 | |
332 | |
333 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); | |
334 if (ctx == NULL) { | |
335 return NGX_CONF_ERROR; | |
336 } | |
337 | |
338 stream_ctx = cf->ctx; | |
339 ctx->main_conf = stream_ctx->main_conf; | |
340 | |
341 /* the upstream{}'s srv_conf */ | |
342 | |
343 ctx->srv_conf = ngx_pcalloc(cf->pool, | |
344 sizeof(void *) * ngx_stream_max_module); | |
345 if (ctx->srv_conf == NULL) { | |
346 return NGX_CONF_ERROR; | |
347 } | |
348 | |
349 ctx->srv_conf[ngx_stream_upstream_module.ctx_index] = uscf; | |
350 | |
351 uscf->srv_conf = ctx->srv_conf; | |
352 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6174
diff
changeset
|
353 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6174
diff
changeset
|
354 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 355 continue; |
356 } | |
357 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6174
diff
changeset
|
358 module = cf->cycle->modules[m]->ctx; |
6115 | 359 |
360 if (module->create_srv_conf) { | |
361 mconf = module->create_srv_conf(cf); | |
362 if (mconf == NULL) { | |
363 return NGX_CONF_ERROR; | |
364 } | |
365 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6174
diff
changeset
|
366 ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf; |
6115 | 367 } |
368 } | |
369 | |
370 uscf->servers = ngx_array_create(cf->pool, 4, | |
371 sizeof(ngx_stream_upstream_server_t)); | |
372 if (uscf->servers == NULL) { | |
373 return NGX_CONF_ERROR; | |
374 } | |
375 | |
376 | |
377 /* parse inside upstream{} */ | |
378 | |
379 pcf = *cf; | |
380 cf->ctx = ctx; | |
381 cf->cmd_type = NGX_STREAM_UPS_CONF; | |
382 | |
383 rv = ngx_conf_parse(cf, NULL); | |
384 | |
385 *cf = pcf; | |
386 | |
387 if (rv != NGX_CONF_OK) { | |
388 return rv; | |
389 } | |
390 | |
391 if (uscf->servers->nelts == 0) { | |
392 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
393 "no servers are inside upstream"); | |
394 return NGX_CONF_ERROR; | |
395 } | |
396 | |
397 return rv; | |
398 } | |
399 | |
400 | |
401 static char * | |
402 ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
403 { | |
404 ngx_stream_upstream_srv_conf_t *uscf = conf; | |
405 | |
406 time_t fail_timeout; | |
407 ngx_str_t *value, s; | |
408 ngx_url_t u; | |
6705 | 409 ngx_int_t weight, max_conns, max_fails; |
6115 | 410 ngx_uint_t i; |
411 ngx_stream_upstream_server_t *us; | |
412 | |
413 us = ngx_array_push(uscf->servers); | |
414 if (us == NULL) { | |
415 return NGX_CONF_ERROR; | |
416 } | |
417 | |
418 ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); | |
419 | |
420 value = cf->args->elts; | |
421 | |
422 weight = 1; | |
6705 | 423 max_conns = 0; |
6115 | 424 max_fails = 1; |
425 fail_timeout = 10; | |
426 | |
427 for (i = 2; i < cf->args->nelts; i++) { | |
428 | |
429 if (ngx_strncmp(value[i].data, "weight=", 7) == 0) { | |
430 | |
431 if (!(uscf->flags & NGX_STREAM_UPSTREAM_WEIGHT)) { | |
432 goto not_supported; | |
433 } | |
434 | |
435 weight = ngx_atoi(&value[i].data[7], value[i].len - 7); | |
436 | |
437 if (weight == NGX_ERROR || weight == 0) { | |
438 goto invalid; | |
439 } | |
440 | |
441 continue; | |
442 } | |
443 | |
6705 | 444 if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) { |
445 | |
446 if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_CONNS)) { | |
447 goto not_supported; | |
448 } | |
449 | |
450 max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10); | |
451 | |
452 if (max_conns == NGX_ERROR) { | |
453 goto invalid; | |
454 } | |
455 | |
456 continue; | |
457 } | |
458 | |
6115 | 459 if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { |
460 | |
461 if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) { | |
462 goto not_supported; | |
463 } | |
464 | |
465 max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10); | |
466 | |
467 if (max_fails == NGX_ERROR) { | |
468 goto invalid; | |
469 } | |
470 | |
471 continue; | |
472 } | |
473 | |
474 if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) { | |
475 | |
476 if (!(uscf->flags & NGX_STREAM_UPSTREAM_FAIL_TIMEOUT)) { | |
477 goto not_supported; | |
478 } | |
479 | |
480 s.len = value[i].len - 13; | |
481 s.data = &value[i].data[13]; | |
482 | |
483 fail_timeout = ngx_parse_time(&s, 1); | |
484 | |
485 if (fail_timeout == (time_t) NGX_ERROR) { | |
486 goto invalid; | |
487 } | |
488 | |
489 continue; | |
490 } | |
491 | |
492 if (ngx_strcmp(value[i].data, "backup") == 0) { | |
493 | |
494 if (!(uscf->flags & NGX_STREAM_UPSTREAM_BACKUP)) { | |
495 goto not_supported; | |
496 } | |
497 | |
498 us->backup = 1; | |
499 | |
500 continue; | |
501 } | |
502 | |
503 if (ngx_strcmp(value[i].data, "down") == 0) { | |
504 | |
505 if (!(uscf->flags & NGX_STREAM_UPSTREAM_DOWN)) { | |
506 goto not_supported; | |
507 } | |
508 | |
509 us->down = 1; | |
510 | |
511 continue; | |
512 } | |
513 | |
514 goto invalid; | |
515 } | |
516 | |
517 ngx_memzero(&u, sizeof(ngx_url_t)); | |
518 | |
519 u.url = value[1]; | |
520 | |
521 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { | |
522 if (u.err) { | |
523 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
524 "%s in upstream \"%V\"", u.err, &u.url); | |
525 } | |
526 | |
527 return NGX_CONF_ERROR; | |
528 } | |
529 | |
530 if (u.no_port) { | |
531 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
532 "no port in upstream \"%V\"", &u.url); | |
533 return NGX_CONF_ERROR; | |
534 } | |
535 | |
536 us->name = u.url; | |
537 us->addrs = u.addrs; | |
538 us->naddrs = u.naddrs; | |
539 us->weight = weight; | |
6705 | 540 us->max_conns = max_conns; |
6115 | 541 us->max_fails = max_fails; |
542 us->fail_timeout = fail_timeout; | |
543 | |
544 return NGX_CONF_OK; | |
545 | |
546 invalid: | |
547 | |
548 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
549 "invalid parameter \"%V\"", &value[i]); | |
550 | |
551 return NGX_CONF_ERROR; | |
552 | |
553 not_supported: | |
554 | |
555 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
556 "balancing method does not support parameter \"%V\"", | |
557 &value[i]); | |
558 | |
559 return NGX_CONF_ERROR; | |
560 } | |
561 | |
562 | |
563 ngx_stream_upstream_srv_conf_t * | |
564 ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) | |
565 { | |
566 ngx_uint_t i; | |
567 ngx_stream_upstream_server_t *us; | |
568 ngx_stream_upstream_srv_conf_t *uscf, **uscfp; | |
569 ngx_stream_upstream_main_conf_t *umcf; | |
570 | |
571 if (!(flags & NGX_STREAM_UPSTREAM_CREATE)) { | |
572 | |
573 if (ngx_parse_url(cf->pool, u) != NGX_OK) { | |
574 if (u->err) { | |
575 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
576 "%s in upstream \"%V\"", u->err, &u->url); | |
577 } | |
578 | |
579 return NULL; | |
580 } | |
581 } | |
582 | |
583 umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); | |
584 | |
585 uscfp = umcf->upstreams.elts; | |
586 | |
587 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
588 | |
589 if (uscfp[i]->host.len != u->host.len | |
590 || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) | |
591 != 0) | |
592 { | |
593 continue; | |
594 } | |
595 | |
596 if ((flags & NGX_STREAM_UPSTREAM_CREATE) | |
597 && (uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE)) | |
598 { | |
599 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
600 "duplicate upstream \"%V\"", &u->host); | |
601 return NULL; | |
602 } | |
603 | |
604 if ((uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE) && !u->no_port) { | |
6699
9cf2dce316e5
Fixed log levels of configuration parsing errors.
Valentin Bartenev <vbart@nginx.com>
parents:
6677
diff
changeset
|
605 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
6115 | 606 "upstream \"%V\" may not have port %d", |
607 &u->host, u->port); | |
608 return NULL; | |
609 } | |
610 | |
611 if ((flags & NGX_STREAM_UPSTREAM_CREATE) && !uscfp[i]->no_port) { | |
6699
9cf2dce316e5
Fixed log levels of configuration parsing errors.
Valentin Bartenev <vbart@nginx.com>
parents:
6677
diff
changeset
|
612 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
6115 | 613 "upstream \"%V\" may not have port %d in %s:%ui", |
614 &u->host, uscfp[i]->port, | |
615 uscfp[i]->file_name, uscfp[i]->line); | |
616 return NULL; | |
617 } | |
618 | |
619 if (uscfp[i]->port != u->port) { | |
620 continue; | |
621 } | |
622 | |
623 if (flags & NGX_STREAM_UPSTREAM_CREATE) { | |
624 uscfp[i]->flags = flags; | |
625 } | |
626 | |
627 return uscfp[i]; | |
628 } | |
629 | |
630 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_srv_conf_t)); | |
631 if (uscf == NULL) { | |
632 return NULL; | |
633 } | |
634 | |
635 uscf->flags = flags; | |
636 uscf->host = u->host; | |
637 uscf->file_name = cf->conf_file->file.name.data; | |
638 uscf->line = cf->conf_file->line; | |
639 uscf->port = u->port; | |
640 uscf->no_port = u->no_port; | |
641 | |
6459
78fc2dce69e7
Stream: detect port absence in proxy_pass with IP literal.
Roman Arutyunyan <arut@nginx.com>
parents:
6379
diff
changeset
|
642 if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { |
6115 | 643 uscf->servers = ngx_array_create(cf->pool, 1, |
644 sizeof(ngx_stream_upstream_server_t)); | |
645 if (uscf->servers == NULL) { | |
646 return NULL; | |
647 } | |
648 | |
649 us = ngx_array_push(uscf->servers); | |
650 if (us == NULL) { | |
651 return NULL; | |
652 } | |
653 | |
654 ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); | |
655 | |
656 us->addrs = u->addrs; | |
657 us->naddrs = 1; | |
658 } | |
659 | |
660 uscfp = ngx_array_push(&umcf->upstreams); | |
661 if (uscfp == NULL) { | |
662 return NULL; | |
663 } | |
664 | |
665 *uscfp = uscf; | |
666 | |
667 return uscf; | |
668 } | |
669 | |
670 | |
671 static void * | |
672 ngx_stream_upstream_create_main_conf(ngx_conf_t *cf) | |
673 { | |
674 ngx_stream_upstream_main_conf_t *umcf; | |
675 | |
676 umcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_main_conf_t)); | |
677 if (umcf == NULL) { | |
678 return NULL; | |
679 } | |
680 | |
681 if (ngx_array_init(&umcf->upstreams, cf->pool, 4, | |
682 sizeof(ngx_stream_upstream_srv_conf_t *)) | |
683 != NGX_OK) | |
684 { | |
685 return NULL; | |
686 } | |
687 | |
688 return umcf; | |
689 } | |
690 | |
691 | |
692 static char * | |
693 ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf) | |
694 { | |
695 ngx_stream_upstream_main_conf_t *umcf = conf; | |
696 | |
697 ngx_uint_t i; | |
698 ngx_stream_upstream_init_pt init; | |
699 ngx_stream_upstream_srv_conf_t **uscfp; | |
700 | |
701 uscfp = umcf->upstreams.elts; | |
702 | |
703 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
704 | |
705 init = uscfp[i]->peer.init_upstream | |
706 ? uscfp[i]->peer.init_upstream | |
707 : ngx_stream_upstream_init_round_robin; | |
708 | |
709 if (init(cf, uscfp[i]) != NGX_OK) { | |
710 return NGX_CONF_ERROR; | |
711 } | |
712 } | |
713 | |
714 return NGX_CONF_OK; | |
715 } |