Mercurial > hg > nginx
annotate src/http/ngx_http_upstream.c @ 9230:e14debe728b0 radix_with_skip
Closed the radix_with_skip branch.
The radix_with_skip branch is an archive of an experiment did in 2008,
and it is no longer relevant. It is now closed to avoid cluttering of
the branches list. If needed, closed branches still can be seen with
"hg branches --closed".
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 23 Mar 2024 04:30:45 +0300 |
parents | 64854406b1f9 |
children | 87b8c44906b5 |
rev | line source |
---|---|
479 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
1658 | 12 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); |
509 | 13 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
14 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); | |
15 static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, | |
16 ngx_event_t *ev); | |
479 | 17 static void ngx_http_upstream_connect(ngx_http_request_t *r, |
487 | 18 ngx_http_upstream_t *u); |
509 | 19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, |
487 | 20 ngx_http_upstream_t *u); |
479 | 21 static void ngx_http_upstream_send_request(ngx_http_request_t *r, |
487 | 22 ngx_http_upstream_t *u); |
479 | 23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); |
24 static void ngx_http_upstream_process_header(ngx_event_t *rev); | |
2268
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
25 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
26 ngx_http_upstream_t *u); |
2267
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
27 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
28 ngx_http_upstream_t *u); |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
29 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); |
777
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
30 static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); |
479 | 31 static void ngx_http_upstream_send_response(ngx_http_request_t *r, |
487 | 32 ngx_http_upstream_t *u); |
581 | 33 static void |
34 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); | |
35 static void ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev); | |
36 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data); | |
37 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, | |
38 ssize_t bytes); | |
509 | 39 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); |
479 | 40 static void ngx_http_upstream_process_body(ngx_event_t *ev); |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
41 static void ngx_http_upstream_store(ngx_http_request_t *r, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
42 ngx_http_upstream_t *u); |
479 | 43 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); |
44 static void ngx_http_upstream_next(ngx_http_request_t *r, | |
487 | 45 ngx_http_upstream_t *u, ngx_uint_t ft_type); |
569 | 46 static void ngx_http_upstream_cleanup(void *data); |
479 | 47 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
487 | 48 ngx_http_upstream_t *u, ngx_int_t rc); |
479 | 49 |
509 | 50 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, |
51 ngx_table_elt_t *h, ngx_uint_t offset); | |
52 static ngx_int_t | |
53 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | |
54 ngx_table_elt_t *h, ngx_uint_t offset); | |
55 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, | |
56 ngx_table_elt_t *h, ngx_uint_t offset); | |
527 | 57 static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, |
58 ngx_table_elt_t *h, ngx_uint_t offset); | |
649 | 59 static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, |
509 | 60 ngx_table_elt_t *h, ngx_uint_t offset); |
657 | 61 static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r, |
62 ngx_table_elt_t *h, ngx_uint_t offset); | |
649 | 63 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, |
509 | 64 ngx_table_elt_t *h, ngx_uint_t offset); |
65 static ngx_int_t | |
66 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, | |
67 ngx_table_elt_t *h, ngx_uint_t offset); | |
68 static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r, | |
69 ngx_table_elt_t *h, ngx_uint_t offset); | |
70 static ngx_int_t ngx_http_upstream_copy_content_length(ngx_http_request_t *r, | |
71 ngx_table_elt_t *h, ngx_uint_t offset); | |
72 static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r, | |
73 ngx_table_elt_t *h, ngx_uint_t offset); | |
74 static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, | |
75 ngx_table_elt_t *h, ngx_uint_t offset); | |
76 #if (NGX_HTTP_GZIP) | |
77 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, | |
78 ngx_table_elt_t *h, ngx_uint_t offset); | |
79 #endif | |
80 | |
573 | 81 static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf); |
1181 | 82 static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r, |
83 ngx_http_variable_value_t *v, uintptr_t data); | |
573 | 84 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, |
85 ngx_http_variable_value_t *v, uintptr_t data); | |
86 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, | |
87 ngx_http_variable_value_t *v, uintptr_t data); | |
88 | |
651 | 89 static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); |
90 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, | |
91 void *conf); | |
92 | |
509 | 93 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); |
651 | 94 static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); |
509 | 95 |
577 | 96 #if (NGX_HTTP_SSL) |
591 | 97 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *, |
98 ngx_http_upstream_t *u, ngx_connection_t *c); | |
577 | 99 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c); |
100 #endif | |
101 | |
509 | 102 |
103 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { | |
104 | |
105 { ngx_string("Status"), | |
106 ngx_http_upstream_process_header_line, | |
107 offsetof(ngx_http_upstream_headers_in_t, status), | |
649 | 108 ngx_http_upstream_copy_header_line, 0, 0 }, |
509 | 109 |
110 { ngx_string("Content-Type"), | |
111 ngx_http_upstream_process_header_line, | |
112 offsetof(ngx_http_upstream_headers_in_t, content_type), | |
673 | 113 ngx_http_upstream_copy_content_type, 0, 1 }, |
509 | 114 |
115 { ngx_string("Content-Length"), | |
116 ngx_http_upstream_process_header_line, | |
117 offsetof(ngx_http_upstream_headers_in_t, content_length), | |
515 | 118 ngx_http_upstream_copy_content_length, 0, 0 }, |
509 | 119 |
120 { ngx_string("Date"), | |
121 ngx_http_upstream_process_header_line, | |
122 offsetof(ngx_http_upstream_headers_in_t, date), | |
649 | 123 ngx_http_upstream_copy_header_line, |
124 offsetof(ngx_http_headers_out_t, date), 0 }, | |
509 | 125 |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
126 { ngx_string("Last-Modified"), |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
127 ngx_http_upstream_process_header_line, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
128 offsetof(ngx_http_upstream_headers_in_t, last_modified), |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
129 ngx_http_upstream_copy_header_line, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
130 offsetof(ngx_http_headers_out_t, last_modified), 0 }, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
131 |
509 | 132 { ngx_string("Server"), |
133 ngx_http_upstream_process_header_line, | |
134 offsetof(ngx_http_upstream_headers_in_t, server), | |
649 | 135 ngx_http_upstream_copy_header_line, |
136 offsetof(ngx_http_headers_out_t, server), 0 }, | |
509 | 137 |
529 | 138 { ngx_string("WWW-Authenticate"), |
139 ngx_http_upstream_process_header_line, | |
140 offsetof(ngx_http_upstream_headers_in_t, www_authenticate), | |
141 ngx_http_upstream_copy_header_line, 0, 0 }, | |
142 | |
509 | 143 { ngx_string("Location"), |
2140
dce5ddef5af9
if upstream sent a location header without status use 302
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
144 ngx_http_upstream_process_header_line, |
dce5ddef5af9
if upstream sent a location header without status use 302
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
145 offsetof(ngx_http_upstream_headers_in_t, location), |
515 | 146 ngx_http_upstream_rewrite_location, 0, 0 }, |
509 | 147 |
148 { ngx_string("Refresh"), | |
149 ngx_http_upstream_ignore_header_line, 0, | |
515 | 150 ngx_http_upstream_rewrite_refresh, 0, 0 }, |
151 | |
152 { ngx_string("Set-Cookie"), | |
153 ngx_http_upstream_ignore_header_line, 0, | |
531 | 154 ngx_http_upstream_copy_header_line, 0, 1 }, |
155 | |
156 { ngx_string("Content-Disposition"), | |
157 ngx_http_upstream_ignore_header_line, 0, | |
158 ngx_http_upstream_copy_header_line, 0, 1 }, | |
509 | 159 |
160 { ngx_string("Cache-Control"), | |
161 ngx_http_upstream_process_multi_header_lines, | |
162 offsetof(ngx_http_upstream_headers_in_t, cache_control), | |
163 ngx_http_upstream_copy_multi_header_lines, | |
515 | 164 offsetof(ngx_http_headers_out_t, cache_control), 1 }, |
509 | 165 |
573 | 166 { ngx_string("Expires"), |
167 ngx_http_upstream_process_header_line, | |
168 offsetof(ngx_http_upstream_headers_in_t, expires), | |
169 ngx_http_upstream_copy_header_line, | |
170 offsetof(ngx_http_headers_out_t, expires), 1 }, | |
171 | |
577 | 172 { ngx_string("Accept-Ranges"), |
173 ngx_http_upstream_process_header_line, | |
174 offsetof(ngx_http_upstream_headers_in_t, accept_ranges), | |
175 ngx_http_upstream_copy_header_line, | |
176 offsetof(ngx_http_headers_out_t, accept_ranges), 1 }, | |
177 | |
509 | 178 { ngx_string("Connection"), |
179 ngx_http_upstream_ignore_header_line, 0, | |
515 | 180 ngx_http_upstream_ignore_header_line, 0, 0 }, |
509 | 181 |
641 | 182 { ngx_string("Keep-Alive"), |
183 ngx_http_upstream_ignore_header_line, 0, | |
184 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
185 | |
509 | 186 { ngx_string("X-Powered-By"), |
187 ngx_http_upstream_ignore_header_line, 0, | |
649 | 188 ngx_http_upstream_copy_header_line, 0, 0 }, |
509 | 189 |
190 { ngx_string("X-Accel-Expires"), | |
191 ngx_http_upstream_process_header_line, | |
192 offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), | |
649 | 193 ngx_http_upstream_copy_header_line, 0, 0 }, |
515 | 194 |
195 { ngx_string("X-Accel-Redirect"), | |
196 ngx_http_upstream_process_header_line, | |
197 offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), | |
198 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
509 | 199 |
527 | 200 { ngx_string("X-Accel-Limit-Rate"), |
201 ngx_http_upstream_process_limit_rate, 0, | |
202 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
203 | |
649 | 204 { ngx_string("X-Accel-Buffering"), |
205 ngx_http_upstream_process_buffering, 0, | |
206 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
207 | |
657 | 208 { ngx_string("X-Accel-Charset"), |
209 ngx_http_upstream_process_charset, 0, | |
210 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
211 | |
509 | 212 #if (NGX_HTTP_GZIP) |
213 { ngx_string("Content-Encoding"), | |
214 ngx_http_upstream_process_header_line, | |
215 offsetof(ngx_http_upstream_headers_in_t, content_encoding), | |
515 | 216 ngx_http_upstream_copy_content_encoding, 0, 0 }, |
509 | 217 #endif |
218 | |
515 | 219 { ngx_null_string, NULL, 0, NULL, 0, 0 } |
509 | 220 }; |
479 | 221 |
222 | |
651 | 223 static ngx_command_t ngx_http_upstream_commands[] = { |
224 | |
225 { ngx_string("upstream"), | |
226 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, | |
227 ngx_http_upstream, | |
228 0, | |
229 0, | |
230 NULL }, | |
231 | |
232 { ngx_string("server"), | |
884 | 233 NGX_HTTP_UPS_CONF|NGX_CONF_1MORE, |
651 | 234 ngx_http_upstream_server, |
235 NGX_HTTP_SRV_CONF_OFFSET, | |
236 0, | |
237 NULL }, | |
238 | |
239 ngx_null_command | |
240 }; | |
241 | |
242 | |
243 static ngx_http_module_t ngx_http_upstream_module_ctx = { | |
573 | 244 ngx_http_upstream_add_variables, /* preconfiguration */ |
509 | 245 NULL, /* postconfiguration */ |
246 | |
247 ngx_http_upstream_create_main_conf, /* create main configuration */ | |
651 | 248 ngx_http_upstream_init_main_conf, /* init main configuration */ |
479 | 249 |
250 NULL, /* create server configuration */ | |
251 NULL, /* merge server configuration */ | |
252 | |
253 NULL, /* create location configuration */ | |
254 NULL /* merge location configuration */ | |
255 }; | |
577 | 256 |
479 | 257 |
258 ngx_module_t ngx_http_upstream_module = { | |
509 | 259 NGX_MODULE_V1, |
479 | 260 &ngx_http_upstream_module_ctx, /* module context */ |
651 | 261 ngx_http_upstream_commands, /* module directives */ |
479 | 262 NGX_HTTP_MODULE, /* module type */ |
541 | 263 NULL, /* init master */ |
479 | 264 NULL, /* init module */ |
541 | 265 NULL, /* init process */ |
266 NULL, /* init thread */ | |
267 NULL, /* exit thread */ | |
268 NULL, /* exit process */ | |
269 NULL, /* exit master */ | |
270 NGX_MODULE_V1_PADDING | |
479 | 271 }; |
272 | |
273 | |
573 | 274 static ngx_http_variable_t ngx_http_upstream_vars[] = { |
275 | |
1181 | 276 { ngx_string("upstream_addr"), NULL, |
277 ngx_http_upstream_addr_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, | |
278 | |
637 | 279 { ngx_string("upstream_status"), NULL, |
583 | 280 ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
573 | 281 |
637 | 282 { ngx_string("upstream_response_time"), NULL, |
583 | 283 ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
573 | 284 |
637 | 285 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
573 | 286 }; |
287 | |
288 | |
2268
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
289 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
290 { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 }, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
291 { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 }, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
292 { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 }, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
293 { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 }, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
294 { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 }, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
295 { 0, 0 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
296 }; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
297 |
487 | 298 void |
299 ngx_http_upstream_init(ngx_http_request_t *r) | |
479 | 300 { |
1658 | 301 ngx_str_t *host; |
302 ngx_uint_t i; | |
303 ngx_connection_t *c; | |
304 ngx_resolver_ctx_t *ctx, temp; | |
305 ngx_http_cleanup_t *cln; | |
306 ngx_http_upstream_t *u; | |
307 ngx_http_core_loc_conf_t *clcf; | |
308 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | |
309 ngx_http_upstream_main_conf_t *umcf; | |
479 | 310 |
311 c = r->connection; | |
312 | |
313 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
314 "http init upstream, client timer: %d", c->read->timer_set); | |
315 | |
316 if (c->read->timer_set) { | |
317 ngx_del_timer(c->read); | |
318 } | |
319 | |
629 | 320 u = r->upstream; |
321 | |
322 if (!r->post_action && !u->conf->ignore_client_abort) { | |
615 | 323 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; |
324 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; | |
325 } | |
577 | 326 |
479 | 327 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { |
328 | |
329 if (!c->write->active) { | |
531 | 330 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) |
331 == NGX_ERROR) | |
479 | 332 { |
333 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
334 return; | |
335 } | |
336 } | |
337 } | |
338 | |
537 | 339 if (r->request_body) { |
340 u->request_bufs = r->request_body->bufs; | |
341 } | |
509 | 342 |
537 | 343 if (u->create_request(r) != NGX_OK) { |
479 | 344 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
345 return; | |
346 } | |
347 | |
509 | 348 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
479 | 349 |
350 u->output.pool = r->pool; | |
351 u->output.bufs.num = 1; | |
509 | 352 u->output.bufs.size = clcf->client_body_buffer_size; |
479 | 353 u->output.output_filter = ngx_chain_writer; |
354 u->output.filter_ctx = &u->writer; | |
355 | |
356 u->writer.pool = r->pool; | |
357 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
358 if (r->upstream_states == NULL) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
359 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
360 r->upstream_states = ngx_array_create(r->pool, 1, |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
361 sizeof(ngx_http_upstream_state_t)); |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
362 if (r->upstream_states == NULL) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
363 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
364 return; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
365 } |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
366 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
367 } else { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
368 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
369 u->state = ngx_array_push(r->upstream_states); |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
370 if (u->state == NULL) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
371 ngx_http_upstream_finalize_request(r, u, |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
372 NGX_HTTP_INTERNAL_SERVER_ERROR); |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
373 return; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
374 } |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
375 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
376 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); |
479 | 377 } |
378 | |
593 | 379 cln = ngx_http_cleanup_add(r, 0); |
569 | 380 if (cln == NULL) { |
381 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
382 return; | |
383 } | |
384 | |
385 cln->handler = ngx_http_upstream_cleanup; | |
386 cln->data = r; | |
387 u->cleanup = &cln->handler; | |
388 | |
1295
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
389 u->store = (u->conf->store || u->conf->store_lengths); |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
390 |
1658 | 391 if (u->resolved == NULL) { |
392 | |
393 uscf = u->conf->upstream; | |
394 | |
395 } else { | |
396 | |
1705 | 397 host = &u->resolved->host; |
1658 | 398 |
399 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | |
400 | |
401 uscfp = umcf->upstreams.elts; | |
402 | |
403 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
404 | |
405 uscf = uscfp[i]; | |
406 | |
407 if (uscf->host.len == host->len | |
2285 | 408 && ((uscf->port == 0 && u->resolved->no_port) |
1912 | 409 || uscf->port == u->resolved->port) |
1658 | 410 && ngx_memcmp(uscf->host.data, host->data, host->len) == 0) |
411 { | |
412 goto found; | |
413 } | |
414 } | |
415 | |
416 temp.name = *host; | |
417 | |
418 ctx = ngx_resolve_start(clcf->resolver, &temp); | |
419 if (ctx == NULL) { | |
420 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
421 return; | |
422 } | |
423 | |
1683
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
424 if (ctx == NGX_NO_RESOLVER) { |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
425 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
426 "no resolver defined to resolve %V", host); |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
427 |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
428 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
429 return; |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
430 } |
1e0b028055ec
allow to use IP addresses without defined resolver
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
431 |
1658 | 432 ctx->name = *host; |
433 ctx->type = NGX_RESOLVE_A; | |
434 ctx->handler = ngx_http_upstream_resolve_handler; | |
435 ctx->data = r; | |
436 ctx->timeout = clcf->resolver_timeout; | |
437 | |
1959
4f16186f5603
quick resolving handles u->resolved->ctx by itself
Igor Sysoev <igor@sysoev.ru>
parents:
1958
diff
changeset
|
438 u->resolved->ctx = ctx; |
4f16186f5603
quick resolving handles u->resolved->ctx by itself
Igor Sysoev <igor@sysoev.ru>
parents:
1958
diff
changeset
|
439 |
1658 | 440 if (ngx_resolve_name(ctx) != NGX_OK) { |
1959
4f16186f5603
quick resolving handles u->resolved->ctx by itself
Igor Sysoev <igor@sysoev.ru>
parents:
1958
diff
changeset
|
441 u->resolved->ctx = NULL; |
1658 | 442 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
443 return; | |
444 } | |
445 | |
446 return; | |
447 } | |
448 | |
449 found: | |
450 | |
451 if (uscf->peer.init(r, uscf) != NGX_OK) { | |
452 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
453 return; | |
454 } | |
455 | |
479 | 456 ngx_http_upstream_connect(r, u); |
457 } | |
458 | |
459 | |
487 | 460 static void |
1658 | 461 ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) |
462 { | |
463 ngx_http_request_t *r; | |
464 ngx_http_upstream_resolved_t *ur; | |
465 | |
466 r = ctx->data; | |
467 | |
468 r->upstream->resolved->ctx = NULL; | |
469 | |
470 if (ctx->state) { | |
471 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
472 "%V could not be resolved (%i: %s)", | |
473 &ctx->name, ctx->state, | |
474 ngx_resolver_strerror(ctx->state)); | |
475 | |
476 ngx_resolve_name_done(ctx); | |
477 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); | |
478 return; | |
479 } | |
480 | |
481 ur = r->upstream->resolved; | |
482 ur->naddrs = ctx->naddrs; | |
483 ur->addrs = ctx->addrs; | |
484 | |
485 #if (NGX_DEBUG) | |
486 { | |
487 in_addr_t addr; | |
488 ngx_uint_t i; | |
489 | |
490 for (i = 0; i < ctx->naddrs; i++) { | |
491 addr = ntohl(ur->addrs[i]); | |
492 | |
493 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
494 "name was resolved to %ud.%ud.%ud.%ud", | |
495 (addr >> 24) & 0xff, (addr >> 16) & 0xff, | |
496 (addr >> 8) & 0xff, addr & 0xff); | |
497 } | |
498 } | |
499 #endif | |
500 | |
501 if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) { | |
502 ngx_resolve_name_done(ctx); | |
503 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
504 return; | |
505 } | |
506 | |
507 ngx_resolve_name_done(ctx); | |
508 | |
509 ngx_http_upstream_connect(r, r->upstream); | |
510 } | |
511 | |
512 | |
513 static void | |
509 | 514 ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r) |
515 { | |
516 ngx_http_upstream_check_broken_connection(r, r->connection->read); | |
517 } | |
518 | |
519 | |
520 static void | |
521 ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r) | |
522 { | |
523 ngx_http_upstream_check_broken_connection(r, r->connection->write); | |
524 } | |
525 | |
526 | |
527 static void | |
528 ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, | |
529 ngx_event_t *ev) | |
479 | 530 { |
531 int n; | |
532 char buf[1]; | |
577 | 533 ngx_err_t err; |
479 | 534 ngx_connection_t *c; |
535 ngx_http_upstream_t *u; | |
536 | |
527 | 537 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0, |
538 "http upstream check client, write event:%d, \"%V\"", | |
539 ev->write, &r->uri); | |
479 | 540 |
509 | 541 c = r->connection; |
483 | 542 u = r->upstream; |
543 | |
583 | 544 if (c->error) { |
527 | 545 ngx_http_upstream_finalize_request(r, u, |
546 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
547 return; | |
548 } | |
549 | |
483 | 550 if (u->peer.connection == NULL) { |
551 return; | |
552 } | |
553 | |
479 | 554 #if (NGX_HAVE_KQUEUE) |
555 | |
556 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { | |
557 | |
558 if (!ev->pending_eof) { | |
559 return; | |
560 } | |
561 | |
562 ev->eof = 1; | |
583 | 563 c->error = 1; |
479 | 564 |
565 if (ev->kq_errno) { | |
566 ev->error = 1; | |
567 } | |
568 | |
1565 | 569 if (!u->cacheable && !u->store && u->peer.connection) { |
479 | 570 ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, |
527 | 571 "kevent() reported that client closed prematurely " |
572 "connection, so upstream connection is closed too"); | |
479 | 573 ngx_http_upstream_finalize_request(r, u, |
574 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
575 return; | |
576 } | |
577 | |
578 ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, | |
579 "kevent() reported that client closed " | |
580 "prematurely connection"); | |
581 | |
582 if (u->peer.connection == NULL) { | |
583 ngx_http_upstream_finalize_request(r, u, | |
584 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
585 return; | |
586 } | |
587 | |
588 return; | |
589 } | |
590 | |
591 #endif | |
592 | |
593 n = recv(c->fd, buf, 1, MSG_PEEK); | |
594 | |
595 err = ngx_socket_errno; | |
596 | |
1109 | 597 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, err, |
598 "http upstream recv(): %d", n); | |
599 | |
479 | 600 /* |
601 * we do not need to disable the write event because | |
602 * that event has NGX_USE_CLEAR_EVENT type | |
603 */ | |
604 | |
605 if (ev->write && (n >= 0 || err == NGX_EAGAIN)) { | |
606 return; | |
607 } | |
608 | |
609 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) { | |
610 if (ngx_del_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) { | |
611 ngx_http_upstream_finalize_request(r, u, | |
612 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
613 return; | |
614 } | |
615 } | |
616 | |
617 if (n > 0) { | |
618 return; | |
619 } | |
620 | |
621 if (n == -1) { | |
622 if (err == NGX_EAGAIN) { | |
623 return; | |
624 } | |
625 | |
626 ev->error = 1; | |
627 | |
483 | 628 } else { /* n == 0 */ |
479 | 629 err = 0; |
630 } | |
631 | |
529 | 632 ev->eof = 1; |
583 | 633 c->error = 1; |
529 | 634 |
1565 | 635 if (!u->cacheable && !u->store && u->peer.connection) { |
479 | 636 ngx_log_error(NGX_LOG_INFO, ev->log, err, |
637 "client closed prematurely connection, " | |
638 "so upstream connection is closed too"); | |
639 ngx_http_upstream_finalize_request(r, u, | |
640 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
641 return; | |
642 } | |
643 | |
644 ngx_log_error(NGX_LOG_INFO, ev->log, err, | |
645 "client closed prematurely connection"); | |
646 | |
647 if (u->peer.connection == NULL) { | |
648 ngx_http_upstream_finalize_request(r, u, | |
649 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
650 return; | |
651 } | |
652 } | |
653 | |
654 | |
487 | 655 static void |
656 ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) | |
479 | 657 { |
591 | 658 ngx_int_t rc; |
665 | 659 ngx_time_t *tp; |
591 | 660 ngx_connection_t *c; |
479 | 661 |
483 | 662 r->connection->log->action = "connecting to upstream"; |
479 | 663 |
664 r->connection->single_connection = 0; | |
665 | |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
666 if (u->state && u->state->response_sec) { |
665 | 667 tp = ngx_timeofday(); |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
668 u->state->response_sec = tp->sec - u->state->response_sec; |
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
669 u->state->response_msec = tp->msec - u->state->response_msec; |
665 | 670 } |
671 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
672 u->state = ngx_array_push(r->upstream_states); |
665 | 673 if (u->state == NULL) { |
674 ngx_http_upstream_finalize_request(r, u, | |
675 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
676 return; | |
677 } | |
678 | |
679 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); | |
680 | |
681 tp = ngx_timeofday(); | |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
682 u->state->response_sec = tp->sec; |
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
683 u->state->response_msec = tp->msec; |
665 | 684 |
479 | 685 rc = ngx_event_connect_peer(&u->peer); |
686 | |
687 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
688 "http upstream connect: %i", rc); | |
689 | |
690 if (rc == NGX_ERROR) { | |
691 ngx_http_upstream_finalize_request(r, u, | |
692 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
693 return; | |
694 } | |
695 | |
1707
f3188f6eae1f
$upstream_addr did not contain last address, the bug was introduced in r1659
Igor Sysoev <igor@sysoev.ru>
parents:
1706
diff
changeset
|
696 u->state->peer = u->peer.name; |
f3188f6eae1f
$upstream_addr did not contain last address, the bug was introduced in r1659
Igor Sysoev <igor@sysoev.ru>
parents:
1706
diff
changeset
|
697 |
543 | 698 if (rc == NGX_BUSY) { |
699 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); | |
1378 | 700 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); |
701 return; | |
543 | 702 } |
703 | |
1378 | 704 if (rc == NGX_DECLINED) { |
479 | 705 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
706 return; | |
707 } | |
708 | |
577 | 709 /* rc == NGX_OK || rc == NGX_AGAIN */ |
710 | |
479 | 711 c = u->peer.connection; |
712 | |
713 c->data = r; | |
591 | 714 |
509 | 715 c->write->handler = ngx_http_upstream_send_request_handler; |
716 c->read->handler = ngx_http_upstream_process_header; | |
479 | 717 |
1397
6c25a49e548a
upstream sendfile bit was overridden by r->connection->sendfile
Igor Sysoev <igor@sysoev.ru>
parents:
1378
diff
changeset
|
718 c->sendfile &= r->connection->sendfile; |
1958 | 719 u->output.sendfile = c->sendfile; |
479 | 720 |
721 c->pool = r->pool; | |
722 c->read->log = c->write->log = c->log = r->connection->log; | |
723 | |
724 /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */ | |
725 | |
726 u->writer.out = NULL; | |
727 u->writer.last = &u->writer.out; | |
728 u->writer.connection = c; | |
729 u->writer.limit = 0; | |
730 | |
731 if (u->request_sent) { | |
509 | 732 if (ngx_http_upstream_reinit(r, u) != NGX_OK) { |
733 ngx_http_upstream_finalize_request(r, u, | |
734 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
735 return; | |
736 } | |
479 | 737 } |
738 | |
1064
7c84c877f2d7
fix segfault when client_body_in_file_only is on, the body is not passed
Igor Sysoev <igor@sysoev.ru>
parents:
1063
diff
changeset
|
739 if (r->request_body |
7c84c877f2d7
fix segfault when client_body_in_file_only is on, the body is not passed
Igor Sysoev <igor@sysoev.ru>
parents:
1063
diff
changeset
|
740 && r->request_body->buf |
7c84c877f2d7
fix segfault when client_body_in_file_only is on, the body is not passed
Igor Sysoev <igor@sysoev.ru>
parents:
1063
diff
changeset
|
741 && r->request_body->temp_file |
7c84c877f2d7
fix segfault when client_body_in_file_only is on, the body is not passed
Igor Sysoev <igor@sysoev.ru>
parents:
1063
diff
changeset
|
742 && r == r->main) |
7c84c877f2d7
fix segfault when client_body_in_file_only is on, the body is not passed
Igor Sysoev <igor@sysoev.ru>
parents:
1063
diff
changeset
|
743 { |
573 | 744 /* |
745 * the r->request_body->buf can be reused for one request only, | |
746 * the subrequests should allocate their own temporay bufs | |
747 */ | |
748 | |
749 u->output.free = ngx_alloc_chain_link(r->pool); | |
750 if (u->output.free == NULL) { | |
751 ngx_http_upstream_finalize_request(r, u, | |
752 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
753 return; | |
479 | 754 } |
573 | 755 |
756 u->output.free->buf = r->request_body->buf; | |
757 u->output.free->next = NULL; | |
758 u->output.allocated = 1; | |
759 | |
760 r->request_body->buf->pos = r->request_body->buf->start; | |
761 r->request_body->buf->last = r->request_body->buf->start; | |
762 r->request_body->buf->tag = u->output.tag; | |
479 | 763 } |
764 | |
765 u->request_sent = 0; | |
766 | |
767 if (rc == NGX_AGAIN) { | |
768 ngx_add_timer(c->write, u->conf->connect_timeout); | |
769 return; | |
770 } | |
771 | |
577 | 772 #if (NGX_HTTP_SSL) |
773 | |
1658 | 774 if (u->ssl && c->ssl == NULL) { |
591 | 775 ngx_http_upstream_ssl_init_connection(r, u, c); |
577 | 776 return; |
777 } | |
778 | |
779 #endif | |
780 | |
479 | 781 ngx_http_upstream_send_request(r, u); |
782 } | |
783 | |
784 | |
577 | 785 #if (NGX_HTTP_SSL) |
786 | |
787 static void | |
591 | 788 ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, |
789 ngx_http_upstream_t *u, ngx_connection_t *c) | |
790 { | |
884 | 791 ngx_int_t rc; |
591 | 792 |
793 if (ngx_ssl_create_connection(u->conf->ssl, c, | |
794 NGX_SSL_BUFFER|NGX_SSL_CLIENT) | |
795 == NGX_ERROR) | |
796 { | |
797 ngx_http_upstream_finalize_request(r, u, | |
798 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
799 return; | |
800 } | |
801 | |
802 c->sendfile = 0; | |
619 | 803 u->output.sendfile = 0; |
591 | 804 |
2184 | 805 if (u->conf->ssl_session_reuse) { |
806 if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) { | |
807 ngx_http_upstream_finalize_request(r, u, | |
808 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
809 return; | |
810 } | |
591 | 811 } |
812 | |
641 | 813 r->connection->log->action = "SSL handshaking to upstream"; |
814 | |
591 | 815 rc = ngx_ssl_handshake(c); |
816 | |
817 if (rc == NGX_AGAIN) { | |
818 c->ssl->handler = ngx_http_upstream_ssl_handshake; | |
819 return; | |
820 } | |
821 | |
822 ngx_http_upstream_ssl_handshake(c); | |
823 } | |
824 | |
825 | |
826 static void | |
577 | 827 ngx_http_upstream_ssl_handshake(ngx_connection_t *c) |
828 { | |
829 ngx_http_request_t *r; | |
830 ngx_http_upstream_t *u; | |
831 | |
832 r = c->data; | |
833 u = r->upstream; | |
834 | |
835 if (c->ssl->handshaked) { | |
836 | |
2184 | 837 if (u->conf->ssl_session_reuse) { |
838 u->peer.save_session(&u->peer, u->peer.data); | |
839 } | |
884 | 840 |
577 | 841 c->write->handler = ngx_http_upstream_send_request_handler; |
842 c->read->handler = ngx_http_upstream_process_header; | |
843 | |
844 ngx_http_upstream_send_request(r, u); | |
845 | |
846 return; | |
847 } | |
848 | |
849 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | |
850 | |
851 } | |
852 | |
853 #endif | |
854 | |
855 | |
509 | 856 static ngx_int_t |
487 | 857 ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u) |
479 | 858 { |
859 ngx_chain_t *cl; | |
860 | |
509 | 861 if (u->reinit_request(r) != NGX_OK) { |
862 return NGX_ERROR; | |
863 } | |
864 | |
1705 | 865 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); |
866 | |
867 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, | |
591 | 868 sizeof(ngx_table_elt_t)) |
869 != NGX_OK) | |
509 | 870 { |
871 return NGX_ERROR; | |
479 | 872 } |
873 | |
874 /* reinit the request chain */ | |
577 | 875 |
509 | 876 for (cl = u->request_bufs; cl; cl = cl->next) { |
479 | 877 cl->buf->pos = cl->buf->start; |
878 cl->buf->file_pos = 0; | |
879 } | |
880 | |
509 | 881 /* reinit the subrequest's ngx_output_chain() context */ |
882 | |
573 | 883 if (r->request_body && r->request_body->temp_file |
597 | 884 && r != r->main && u->output.buf) |
573 | 885 { |
886 u->output.free = ngx_alloc_chain_link(r->pool); | |
887 if (u->output.free == NULL) { | |
888 return NGX_ERROR; | |
509 | 889 } |
573 | 890 |
891 u->output.free->buf = u->output.buf; | |
892 u->output.free->next = NULL; | |
893 | |
894 u->output.buf->pos = u->output.buf->start; | |
895 u->output.buf->last = u->output.buf->start; | |
509 | 896 } |
479 | 897 |
898 u->output.buf = NULL; | |
899 u->output.in = NULL; | |
900 u->output.busy = NULL; | |
577 | 901 |
581 | 902 /* reinit u->buffer */ |
577 | 903 |
479 | 904 #if 0 |
905 if (u->cache) { | |
581 | 906 u->buffer.pos = u->buffer.start + u->cache->ctx.header_size; |
907 u->buffer.last = u->buffer.pos; | |
479 | 908 |
909 } else { | |
581 | 910 u->buffer.pos = u->buffer.start; |
911 u->buffer.last = u->buffer.start; | |
479 | 912 } |
913 #else | |
509 | 914 |
581 | 915 u->buffer.pos = u->buffer.start; |
916 u->buffer.last = u->buffer.start; | |
509 | 917 |
479 | 918 #endif |
919 | |
509 | 920 return NGX_OK; |
479 | 921 } |
922 | |
923 | |
487 | 924 static void |
925 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) | |
479 | 926 { |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
927 ngx_int_t rc; |
483 | 928 ngx_connection_t *c; |
577 | 929 |
479 | 930 c = u->peer.connection; |
931 | |
932 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
933 "http upstream send request"); | |
934 | |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
935 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { |
1166 | 936 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
937 return; |
479 | 938 } |
939 | |
483 | 940 c->log->action = "sending request to upstream"; |
479 | 941 |
509 | 942 rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs); |
479 | 943 |
944 u->request_sent = 1; | |
945 | |
946 if (rc == NGX_ERROR) { | |
947 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | |
948 return; | |
949 } | |
950 | |
951 if (c->write->timer_set) { | |
952 ngx_del_timer(c->write); | |
953 } | |
954 | |
955 if (rc == NGX_AGAIN) { | |
956 ngx_add_timer(c->write, u->conf->send_timeout); | |
957 | |
958 if (ngx_handle_write_event(c->write, u->conf->send_lowat) == NGX_ERROR) | |
959 { | |
960 ngx_http_upstream_finalize_request(r, u, | |
961 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
962 return; | |
963 } | |
964 | |
965 return; | |
966 } | |
967 | |
968 /* rc == NGX_OK */ | |
969 | |
970 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { | |
971 if (ngx_tcp_push(c->fd) == NGX_ERROR) { | |
972 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, | |
973 ngx_tcp_push_n " failed"); | |
974 ngx_http_upstream_finalize_request(r, u, | |
975 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
577 | 976 return; |
479 | 977 } |
978 | |
979 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; | |
980 } | |
577 | 981 |
479 | 982 ngx_add_timer(c->read, u->conf->read_timeout); |
983 | |
984 #if 1 | |
985 if (c->read->ready) { | |
577 | 986 |
479 | 987 /* post aio operation */ |
988 | |
989 /* | |
990 * TODO comment | |
991 * although we can post aio operation just in the end | |
992 * of ngx_http_upstream_connect() CHECK IT !!! | |
993 * it's better to do here because we postpone header buffer allocation | |
994 */ | |
995 | |
996 ngx_http_upstream_process_header(c->read); | |
997 return; | |
998 } | |
999 #endif | |
1000 | |
509 | 1001 c->write->handler = ngx_http_upstream_dummy_handler; |
479 | 1002 |
509 | 1003 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
479 | 1004 ngx_http_upstream_finalize_request(r, u, |
1005 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1006 return; | |
1007 } | |
1008 } | |
1009 | |
1010 | |
487 | 1011 static void |
1012 ngx_http_upstream_send_request_handler(ngx_event_t *wev) | |
479 | 1013 { |
1014 ngx_connection_t *c; | |
1015 ngx_http_request_t *r; | |
1016 ngx_http_upstream_t *u; | |
1017 | |
1018 c = wev->data; | |
1019 r = c->data; | |
1020 u = r->upstream; | |
1021 | |
1022 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | |
1023 "http upstream send request handler"); | |
1024 | |
1025 if (wev->timedout) { | |
1026 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | |
1027 return; | |
1028 } | |
1029 | |
591 | 1030 #if (NGX_HTTP_SSL) |
1031 | |
1658 | 1032 if (u->ssl && c->ssl == NULL) { |
591 | 1033 ngx_http_upstream_ssl_init_connection(r, u, c); |
1034 return; | |
1035 } | |
1036 | |
1037 #endif | |
1038 | |
651 | 1039 if (u->header_sent) { |
1040 wev->handler = ngx_http_upstream_dummy_handler; | |
1041 | |
1042 (void) ngx_handle_write_event(wev, 0); | |
1043 | |
1044 return; | |
1045 } | |
1046 | |
479 | 1047 ngx_http_upstream_send_request(r, u); |
1048 } | |
1049 | |
1050 | |
487 | 1051 static void |
1052 ngx_http_upstream_process_header(ngx_event_t *rev) | |
479 | 1053 { |
515 | 1054 ssize_t n; |
1055 ngx_int_t rc; | |
573 | 1056 ngx_str_t *uri, args; |
649 | 1057 ngx_uint_t i, flags; |
515 | 1058 ngx_list_part_t *part; |
1059 ngx_table_elt_t *h; | |
1060 ngx_connection_t *c; | |
1061 ngx_http_request_t *r; | |
1062 ngx_http_upstream_t *u; | |
1063 ngx_http_upstream_header_t *hh; | |
1064 ngx_http_upstream_main_conf_t *umcf; | |
479 | 1065 |
1066 c = rev->data; | |
1067 r = c->data; | |
1068 u = r->upstream; | |
1069 | |
1070 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
483 | 1071 "http upstream process header"); |
479 | 1072 |
483 | 1073 c->log->action = "reading response header from upstream"; |
479 | 1074 |
1075 if (rev->timedout) { | |
1076 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | |
1077 return; | |
1078 } | |
577 | 1079 |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1080 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { |
1166 | 1081 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1082 return; |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1083 } |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1084 |
581 | 1085 if (u->buffer.start == NULL) { |
1086 u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size); | |
1087 if (u->buffer.start == NULL) { | |
479 | 1088 ngx_http_upstream_finalize_request(r, u, |
1089 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1090 return; | |
1091 } | |
1092 | |
581 | 1093 u->buffer.pos = u->buffer.start; |
1094 u->buffer.last = u->buffer.start; | |
1095 u->buffer.end = u->buffer.start + u->conf->buffer_size; | |
1096 u->buffer.temporary = 1; | |
1097 | |
1098 u->buffer.tag = u->output.tag; | |
479 | 1099 |
1705 | 1100 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, |
581 | 1101 sizeof(ngx_table_elt_t)) |
1102 != NGX_OK) | |
509 | 1103 { |
1104 ngx_http_upstream_finalize_request(r, u, | |
1105 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1106 return; | |
1107 } | |
1108 | |
479 | 1109 #if 0 |
1110 if (u->cache) { | |
581 | 1111 u->buffer.pos += u->cache->ctx.header_size; |
1112 u->buffer.last = u->buffer.pos; | |
479 | 1113 } |
1114 #endif | |
1115 } | |
1116 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1117 for ( ;; ) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1118 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1119 n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last); |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1120 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1121 if (n == NGX_AGAIN) { |
479 | 1122 #if 0 |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1123 ngx_add_timer(rev, u->read_timeout); |
479 | 1124 #endif |
1125 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1126 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1127 ngx_http_upstream_finalize_request(r, u, |
479 | 1128 NGX_HTTP_INTERNAL_SERVER_ERROR); |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1129 return; |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1130 } |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1131 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1132 return; |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1133 } |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1134 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1135 if (n == 0) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1136 ngx_log_error(NGX_LOG_ERR, rev->log, 0, |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1137 "upstream prematurely closed connection"); |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1138 } |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1139 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1140 if (n == NGX_ERROR || n == 0) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1141 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
479 | 1142 return; |
1143 } | |
1144 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1145 u->buffer.last += n; |
479 | 1146 |
1147 #if 0 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1148 u->valid_header_in = 0; |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1149 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1150 u->peer.cached = 0; |
479 | 1151 #endif |
1152 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1153 rc = u->process_header(r); |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1154 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1155 if (rc == NGX_AGAIN) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1156 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1157 if (u->buffer.pos == u->buffer.end) { |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1158 ngx_log_error(NGX_LOG_ERR, rev->log, 0, |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1159 "upstream sent too big header"); |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1160 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1161 ngx_http_upstream_next(r, u, |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1162 NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1163 return; |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1164 } |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1165 |
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1166 continue; |
479 | 1167 } |
1168 | |
2360
64854406b1f9
read and process upstream header in cycle,
Igor Sysoev <igor@sysoev.ru>
parents:
2308
diff
changeset
|
1169 break; |
479 | 1170 } |
1171 | |
1172 if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) { | |
1173 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); | |
1174 return; | |
1175 } | |
1176 | |
1699
976db8c6fb64
return NGX_ERROR instead of NGX_HTTP_INTERNAL_SERVER_ERROR in u->parse_header()
Igor Sysoev <igor@sysoev.ru>
parents:
1693
diff
changeset
|
1177 if (rc == NGX_ERROR) { |
479 | 1178 ngx_http_upstream_finalize_request(r, u, |
1179 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1180 return; | |
1181 } | |
1182 | |
1183 /* rc == NGX_OK */ | |
1184 | |
2268
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1185 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1186 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1187 if (r->subrequest_in_memory) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1188 u->buffer.last = u->buffer.pos; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1189 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1190 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1191 if (ngx_http_upstream_test_next(r, u) == NGX_OK) { |
509 | 1192 return; |
1193 } | |
1194 | |
2267
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1195 if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1196 return; |
487 | 1197 } |
1198 } | |
1199 | |
681 | 1200 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
1201 | |
1705 | 1202 if (u->headers_in.x_accel_redirect) { |
757
a138c4e6031f
not do ngx_http_upstream_finalize_request() twice
Igor Sysoev <igor@sysoev.ru>
parents:
756
diff
changeset
|
1203 |
515 | 1204 ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); |
1205 | |
1705 | 1206 part = &u->headers_in.headers.part; |
515 | 1207 h = part->elts; |
1208 | |
1209 for (i = 0; /* void */; i++) { | |
1210 | |
1211 if (i >= part->nelts) { | |
1212 if (part->next == NULL) { | |
1213 break; | |
1214 } | |
577 | 1215 |
515 | 1216 part = part->next; |
1217 h = part->elts; | |
1218 i = 0; | |
1219 } | |
1220 | |
649 | 1221 hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, |
1222 h[i].lowcase_key, h[i].key.len); | |
1223 | |
1224 if (hh && hh->redirect) { | |
1225 if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { | |
787
b310630d129e
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
1226 ngx_http_finalize_request(r, |
757
a138c4e6031f
not do ngx_http_upstream_finalize_request() twice
Igor Sysoev <igor@sysoev.ru>
parents:
756
diff
changeset
|
1227 NGX_HTTP_INTERNAL_SERVER_ERROR); |
515 | 1228 return; |
1229 } | |
1230 } | |
1231 } | |
1232 | |
1705 | 1233 uri = &u->headers_in.x_accel_redirect->value; |
573 | 1234 args.len = 0; |
1235 args.data = NULL; | |
1236 flags = 0; | |
1237 | |
1238 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { | |
757
a138c4e6031f
not do ngx_http_upstream_finalize_request() twice
Igor Sysoev <igor@sysoev.ru>
parents:
756
diff
changeset
|
1239 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); |
573 | 1240 return; |
1241 } | |
1242 | |
1243 if (flags & NGX_HTTP_ZERO_IN_URI) { | |
1244 r->zero_in_uri = 1; | |
1245 } | |
1246 | |
653 | 1247 if (r->method != NGX_HTTP_HEAD) { |
1248 r->method = NGX_HTTP_GET; | |
1249 } | |
1250 | |
2183
4a5bfd728a12
disable original URI usage in proxy_pass after X-Accel-Redirect
Igor Sysoev <igor@sysoev.ru>
parents:
2140
diff
changeset
|
1251 r->valid_unparsed_uri = 0; |
4a5bfd728a12
disable original URI usage in proxy_pass after X-Accel-Redirect
Igor Sysoev <igor@sysoev.ru>
parents:
2140
diff
changeset
|
1252 |
573 | 1253 ngx_http_internal_redirect(r, uri, &args); |
515 | 1254 return; |
1255 } | |
1256 | |
1705 | 1257 part = &u->headers_in.headers.part; |
509 | 1258 h = part->elts; |
1259 | |
1260 for (i = 0; /* void */; i++) { | |
479 | 1261 |
509 | 1262 if (i >= part->nelts) { |
1263 if (part->next == NULL) { | |
1264 break; | |
1265 } | |
577 | 1266 |
509 | 1267 part = part->next; |
1268 h = part->elts; | |
1269 i = 0; | |
1270 } | |
1271 | |
649 | 1272 if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash, |
1273 h[i].lowcase_key, h[i].key.len)) | |
509 | 1274 { |
649 | 1275 continue; |
1276 } | |
1277 | |
1278 hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, | |
1279 h[i].lowcase_key, h[i].key.len); | |
1280 | |
1281 if (hh) { | |
1282 if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { | |
509 | 1283 ngx_http_upstream_finalize_request(r, u, |
1284 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1285 return; | |
1286 } | |
1287 | |
1288 continue; | |
1289 } | |
1290 | |
1291 if (ngx_http_upstream_copy_header_line(r, &h[i], 0) != NGX_OK) { | |
1292 ngx_http_upstream_finalize_request(r, u, | |
1293 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1294 return; | |
1295 } | |
1296 } | |
1297 | |
649 | 1298 if (r->headers_out.server && r->headers_out.server->value.data == NULL) { |
1299 r->headers_out.server->hash = 0; | |
1300 } | |
1301 | |
1302 if (r->headers_out.date && r->headers_out.date->value.data == NULL) { | |
1303 r->headers_out.date->hash = 0; | |
1304 } | |
1305 | |
529 | 1306 r->headers_out.status = u->headers_in.status_n; |
1307 r->headers_out.status_line = u->headers_in.status_line; | |
1308 | |
1885
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
1309 u->headers_in.content_length_n = r->headers_out.content_length_n; |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
1310 |
581 | 1311 if (r->headers_out.content_length_n != -1) { |
1312 u->length = (size_t) r->headers_out.content_length_n; | |
1313 | |
1314 } else { | |
1315 u->length = NGX_MAX_SIZE_T_VALUE; | |
1316 } | |
1317 | |
777
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1318 if (!r->subrequest_in_memory) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1319 ngx_http_upstream_send_response(r, u); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1320 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1321 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1322 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1323 /* subrequest content in memory */ |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1324 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1325 if (u->input_filter == NULL) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1326 u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1327 u->input_filter = ngx_http_upstream_non_buffered_filter; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1328 u->input_filter_ctx = r; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1329 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1330 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1331 if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1332 ngx_http_upstream_finalize_request(r, u, |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1333 NGX_HTTP_INTERNAL_SERVER_ERROR); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1334 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1335 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1336 |
2308
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1337 n = u->buffer.last - u->buffer.pos; |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1338 |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1339 if (n) { |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1340 u->buffer.last -= n; |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1341 |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1342 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { |
777
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1343 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1344 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1345 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1346 |
2308
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1347 if (u->length == 0) { |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1348 ngx_http_upstream_finalize_request(r, u, 0); |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1349 return; |
3f98400e31e9
memcached response was stored in variable with END
Igor Sysoev <igor@sysoev.ru>
parents:
2285
diff
changeset
|
1350 } |
777
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1351 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1352 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1353 rev->handler = ngx_http_upstream_process_body_in_memory; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1354 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1355 ngx_http_upstream_process_body_in_memory(rev); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1356 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1357 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1358 |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1359 static ngx_int_t |
2268
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1360 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1361 { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1362 ngx_uint_t status; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1363 ngx_http_upstream_next_t *un; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1364 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1365 if (!(u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_STATUS)) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1366 return NGX_DECLINED; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1367 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1368 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1369 status = u->headers_in.status_n; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1370 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1371 for (un = ngx_http_upstream_next_errors; un->status; un++) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1372 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1373 if (status != un->status) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1374 continue; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1375 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1376 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1377 if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1378 ngx_http_upstream_next(r, u, un->mask); |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1379 return NGX_OK; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1380 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1381 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1382 if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1383 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND); |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1384 return NGX_OK; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1385 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1386 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1387 #if (NGX_HTTP_CACHE) |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1388 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1389 if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & un->mask)) { |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1390 ngx_http_upstream_finalize_request(r, u, |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1391 ngx_http_send_cached_response(r)); |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1392 return NGX_OK; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1393 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1394 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1395 #endif |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1396 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1397 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1398 return NGX_DECLINED; |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1399 } |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1400 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1401 |
33556140681a
*) ngx_http_upstream_test_next()
Igor Sysoev <igor@sysoev.ru>
parents:
2267
diff
changeset
|
1402 static ngx_int_t |
2267
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1403 ngx_http_upstream_intercept_errors(ngx_http_request_t *r, |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1404 ngx_http_upstream_t *u) |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1405 { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1406 ngx_int_t status; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1407 ngx_uint_t i; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1408 ngx_table_elt_t *h; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1409 ngx_http_err_page_t *err_page; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1410 ngx_http_core_loc_conf_t *clcf; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1411 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1412 if (!u->conf->intercept_errors) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1413 return NGX_DECLINED; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1414 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1415 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1416 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1417 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1418 if (clcf->error_pages == NULL) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1419 return NGX_DECLINED; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1420 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1421 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1422 status = u->headers_in.status_n; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1423 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1424 err_page = clcf->error_pages->elts; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1425 for (i = 0; i < clcf->error_pages->nelts; i++) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1426 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1427 if (err_page[i].status == status) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1428 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1429 if (status == NGX_HTTP_UNAUTHORIZED) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1430 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1431 h = ngx_list_push(&r->headers_out.headers); |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1432 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1433 if (h == NULL) { |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1434 ngx_http_upstream_finalize_request(r, u, |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1435 NGX_HTTP_INTERNAL_SERVER_ERROR); |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1436 return NGX_OK; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1437 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1438 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1439 *h = *u->headers_in.www_authenticate; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1440 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1441 r->headers_out.www_authenticate = h; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1442 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1443 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1444 ngx_http_upstream_finalize_request(r, u, status); |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1445 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1446 return NGX_OK; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1447 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1448 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1449 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1450 return NGX_DECLINED; |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1451 } |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1452 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1453 |
920be89a3d2d
ngx_http_upstream_intercept_errors()
Igor Sysoev <igor@sysoev.ru>
parents:
2244
diff
changeset
|
1454 static ngx_int_t |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1455 ngx_http_upstream_test_connect(ngx_connection_t *c) |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1456 { |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1457 int err; |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1458 socklen_t len; |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1459 |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1460 #if (NGX_HAVE_KQUEUE) |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1461 |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1462 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { |
1166 | 1463 if (c->write->pending_eof) { |
1469
0a269c464eaf
connection error should be logged with "connecting to upstream" action,
Igor Sysoev <igor@sysoev.ru>
parents:
1468
diff
changeset
|
1464 c->log->action = "connecting to upstream"; |
1166 | 1465 (void) ngx_connection_error(c, c->write->kq_errno, |
1466 "kevent() reported that connect() failed"); | |
1467 return NGX_ERROR; | |
1468 } | |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1469 |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1470 } else |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1471 #endif |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1472 { |
1166 | 1473 err = 0; |
1474 len = sizeof(int); | |
1475 | |
1476 /* | |
1477 * BSDs and Linux return 0 and set a pending error in err | |
1478 * Solaris returns -1 and sets errno | |
1479 */ | |
1480 | |
1481 if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) | |
1482 == -1) | |
1483 { | |
1484 err = ngx_errno; | |
1485 } | |
1486 | |
1487 if (err) { | |
1469
0a269c464eaf
connection error should be logged with "connecting to upstream" action,
Igor Sysoev <igor@sysoev.ru>
parents:
1468
diff
changeset
|
1488 c->log->action = "connecting to upstream"; |
1166 | 1489 (void) ngx_connection_error(c, err, "connect() failed"); |
1490 return NGX_ERROR; | |
1491 } | |
1153
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1492 } |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1493 |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1494 return NGX_OK; |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1495 } |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1496 |
c843f3df3b85
separate ngx_http_upstream_test_connect() and
Igor Sysoev <igor@sysoev.ru>
parents:
1143
diff
changeset
|
1497 |
777
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1498 static void |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1499 ngx_http_upstream_process_body_in_memory(ngx_event_t *rev) |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1500 { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1501 size_t size; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1502 ssize_t n; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1503 ngx_buf_t *b; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1504 ngx_connection_t *c; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1505 ngx_http_request_t *r; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1506 ngx_http_upstream_t *u; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1507 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1508 c = rev->data; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1509 r = c->data; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1510 u = r->upstream; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1511 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1512 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1513 "http upstream process body on memory"); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1514 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1515 if (rev->timedout) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1516 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1517 ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1518 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1519 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1520 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1521 b = &u->buffer; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1522 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1523 for ( ;; ) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1524 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1525 size = b->end - b->last; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1526 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1527 if (size == 0) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1528 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1529 "upstream buffer is too small to read repsonse"); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1530 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1531 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1532 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1533 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1534 n = c->recv(c, b->last, size); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1535 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1536 if (n == NGX_AGAIN) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1537 break; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1538 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1539 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1540 if (n == 0 || n == NGX_ERROR) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1541 ngx_http_upstream_finalize_request(r, u, n); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1542 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1543 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1544 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1545 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1546 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1547 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1548 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1549 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1550 if (!rev->ready) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1551 break; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1552 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1553 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1554 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1555 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1556 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1557 return; |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1558 } |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1559 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1560 if (rev->active) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1561 ngx_add_timer(rev, u->conf->read_timeout); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1562 |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1563 } else if (rev->timer_set) { |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1564 ngx_del_timer(rev); |
4ab852b691f5
<!--#include virtual=... set=... -->
Igor Sysoev <igor@sysoev.ru>
parents:
757
diff
changeset
|
1565 } |
681 | 1566 } |
1567 | |
1568 | |
1569 static void | |
1570 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) | |
1571 { | |
1572 int tcp_nodelay; | |
1573 ssize_t size; | |
1574 ngx_int_t rc; | |
1575 ngx_event_pipe_t *p; | |
1576 ngx_connection_t *c; | |
1577 ngx_pool_cleanup_t *cl; | |
1578 ngx_pool_cleanup_file_t *clf; | |
1579 ngx_http_core_loc_conf_t *clcf; | |
1580 | |
509 | 1581 rc = ngx_http_send_header(r); |
479 | 1582 |
1031
bf1785dfb75f
allow the upstream modules to send a header only
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
1583 if (rc == NGX_ERROR || rc > NGX_OK || r->post_action || r->header_only) { |
485 | 1584 ngx_http_upstream_finalize_request(r, u, rc); |
479 | 1585 return; |
1586 } | |
1587 | |
1588 u->header_sent = 1; | |
1589 | |
573 | 1590 if (r->request_body && r->request_body->temp_file) { |
563 | 1591 for (cl = r->pool->cleanup; cl; cl = cl->next) { |
1592 if (cl->handler == ngx_pool_cleanup_file) { | |
1593 clf = cl->data; | |
1594 | |
1595 if (clf->fd == r->request_body->temp_file->file.fd) { | |
1596 cl->handler(clf); | |
1597 cl->handler = NULL; | |
659 | 1598 r->request_body->temp_file->file.fd = NGX_INVALID_FILE; |
563 | 1599 break; |
1600 } | |
1601 } | |
1602 } | |
1603 } | |
1604 | |
583 | 1605 c = r->connection; |
1606 | |
581 | 1607 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1608 | |
649 | 1609 if (!u->buffering) { |
581 | 1610 |
1611 if (u->input_filter == NULL) { | |
1612 u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; | |
1613 u->input_filter = ngx_http_upstream_non_buffered_filter; | |
1614 u->input_filter_ctx = r; | |
1615 } | |
1616 | |
1617 u->peer.connection->read->handler = | |
1618 ngx_http_upstream_process_non_buffered_body; | |
1619 r->write_event_handler = | |
1620 ngx_http_upstream_process_non_buffered_downstream; | |
1621 | |
1622 r->limit_rate = 0; | |
1623 | |
1624 if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { | |
1625 ngx_http_upstream_finalize_request(r, u, 0); | |
1626 return; | |
1627 } | |
1628 | |
583 | 1629 if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { |
1630 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); | |
1631 | |
1632 tcp_nodelay = 1; | |
1633 | |
1634 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, | |
1635 (const void *) &tcp_nodelay, sizeof(int)) == -1) | |
1636 { | |
1637 ngx_connection_error(c, ngx_socket_errno, | |
1638 "setsockopt(TCP_NODELAY) failed"); | |
1639 ngx_http_upstream_finalize_request(r, u, 0); | |
1640 return; | |
1641 } | |
1642 | |
1643 c->tcp_nodelay = NGX_TCP_NODELAY_SET; | |
1644 } | |
1645 | |
581 | 1646 size = u->buffer.last - u->buffer.pos; |
1647 | |
1648 if (size) { | |
1649 u->buffer.last = u->buffer.pos; | |
1650 | |
1651 if (u->input_filter(u->input_filter_ctx, size) == NGX_ERROR) { | |
1652 ngx_http_upstream_finalize_request(r, u, 0); | |
1653 return; | |
1654 } | |
1655 | |
583 | 1656 ngx_http_upstream_process_non_buffered_body(c->write); |
581 | 1657 |
1658 } else { | |
1659 u->buffer.pos = u->buffer.start; | |
1660 u->buffer.last = u->buffer.start; | |
1661 | |
1662 if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { | |
1663 ngx_http_upstream_finalize_request(r, u, 0); | |
1664 return; | |
1665 } | |
1468
491e5059ea19
read EOF of header only responses in non-buffered proxying
Igor Sysoev <igor@sysoev.ru>
parents:
1397
diff
changeset
|
1666 |
491e5059ea19
read EOF of header only responses in non-buffered proxying
Igor Sysoev <igor@sysoev.ru>
parents:
1397
diff
changeset
|
1667 if (u->peer.connection->read->ready) { |
491e5059ea19
read EOF of header only responses in non-buffered proxying
Igor Sysoev <igor@sysoev.ru>
parents:
1397
diff
changeset
|
1668 ngx_http_upstream_process_non_buffered_body( |
491e5059ea19
read EOF of header only responses in non-buffered proxying
Igor Sysoev <igor@sysoev.ru>
parents:
1397
diff
changeset
|
1669 u->peer.connection->read); |
491e5059ea19
read EOF of header only responses in non-buffered proxying
Igor Sysoev <igor@sysoev.ru>
parents:
1397
diff
changeset
|
1670 } |
581 | 1671 } |
1672 | |
1673 return; | |
1674 } | |
1675 | |
479 | 1676 /* TODO: preallocate event_pipe bufs, look "Content-Length" */ |
1677 | |
1678 #if 0 | |
1679 | |
1680 if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) { | |
1681 if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) { | |
583 | 1682 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, |
479 | 1683 ngx_close_file_n " \"%s\" failed", |
1684 u->cache->ctx.file.name.data); | |
1685 } | |
1686 } | |
1687 | |
1565 | 1688 if (u->cacheable) { |
581 | 1689 header = (ngx_http_cache_header_t *) u->buffer->start; |
479 | 1690 |
1691 header->expires = u->cache->ctx.expires; | |
1692 header->last_modified = u->cache->ctx.last_modified; | |
1693 header->date = u->cache->ctx.date; | |
1694 header->length = r->headers_out.content_length_n; | |
1695 u->cache->ctx.length = r->headers_out.content_length_n; | |
1696 | |
1697 header->key_len = u->cache->ctx.key0.len; | |
1698 ngx_memcpy(&header->key, u->cache->ctx.key0.data, header->key_len); | |
1699 header->key[header->key_len] = LF; | |
1700 } | |
1701 | |
1702 #endif | |
1703 | |
581 | 1704 p = u->pipe; |
479 | 1705 |
1706 p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter; | |
1707 p->output_ctx = r; | |
1708 p->tag = u->output.tag; | |
577 | 1709 p->bufs = u->conf->bufs; |
479 | 1710 p->busy_size = u->conf->busy_buffers_size; |
1711 p->upstream = u->peer.connection; | |
583 | 1712 p->downstream = c; |
479 | 1713 p->pool = r->pool; |
583 | 1714 p->log = c->log; |
577 | 1715 |
1565 | 1716 p->cacheable = u->cacheable || u->store; |
479 | 1717 |
501 | 1718 p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); |
1719 if (p->temp_file == NULL) { | |
479 | 1720 ngx_http_upstream_finalize_request(r, u, 0); |
1721 return; | |
1722 } | |
1723 | |
1724 p->temp_file->file.fd = NGX_INVALID_FILE; | |
583 | 1725 p->temp_file->file.log = c->log; |
479 | 1726 p->temp_file->path = u->conf->temp_path; |
1727 p->temp_file->pool = r->pool; | |
577 | 1728 |
1565 | 1729 if (u->cacheable || u->store) { |
479 | 1730 p->temp_file->persistent = 1; |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
1731 |
479 | 1732 } else { |
667 | 1733 p->temp_file->log_level = NGX_LOG_WARN; |
479 | 1734 p->temp_file->warn = "an upstream response is buffered " |
1735 "to a temporary file"; | |
1736 } | |
1737 | |
1738 p->max_temp_file_size = u->conf->max_temp_file_size; | |
1739 p->temp_file_write_size = u->conf->temp_file_write_size; | |
1740 | |
501 | 1741 p->preread_bufs = ngx_alloc_chain_link(r->pool); |
1742 if (p->preread_bufs == NULL) { | |
479 | 1743 ngx_http_upstream_finalize_request(r, u, 0); |
1744 return; | |
1745 } | |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
1746 |
581 | 1747 p->preread_bufs->buf = &u->buffer; |
479 | 1748 p->preread_bufs->next = NULL; |
581 | 1749 u->buffer.recycled = 1; |
1750 | |
1751 p->preread_size = u->buffer.last - u->buffer.pos; | |
479 | 1752 |
1565 | 1753 if (u->cacheable) { |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
1754 |
479 | 1755 p->buf_to_file = ngx_calloc_buf(r->pool); |
1756 if (p->buf_to_file == NULL) { | |
1757 ngx_http_upstream_finalize_request(r, u, 0); | |
1758 return; | |
1759 } | |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
1760 |
581 | 1761 p->buf_to_file->pos = u->buffer.start; |
1762 p->buf_to_file->last = u->buffer.pos; | |
479 | 1763 p->buf_to_file->temporary = 1; |
1764 } | |
1765 | |
1766 if (ngx_event_flags & NGX_USE_AIO_EVENT) { | |
1767 /* the posted aio operation may currupt a shadow buffer */ | |
1768 p->single_buf = 1; | |
1769 } | |
1770 | |
1771 /* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */ | |
1772 p->free_bufs = 1; | |
1773 | |
1774 /* | |
581 | 1775 * event_pipe would do u->buffer.last += p->preread_size |
479 | 1776 * as though these bytes were read |
1777 */ | |
581 | 1778 u->buffer.last = u->buffer.pos; |
479 | 1779 |
1780 if (u->conf->cyclic_temp_file) { | |
1781 | |
1782 /* | |
1783 * we need to disable the use of sendfile() if we use cyclic temp file | |
1784 * because the writing a new data may interfere with sendfile() | |
1785 * that uses the same kernel file pages (at least on FreeBSD) | |
1786 */ | |
1787 | |
1788 p->cyclic_temp_file = 1; | |
583 | 1789 c->sendfile = 0; |
479 | 1790 |
1791 } else { | |
1792 p->cyclic_temp_file = 0; | |
1793 } | |
1794 | |
1795 p->read_timeout = u->conf->read_timeout; | |
1796 p->send_timeout = clcf->send_timeout; | |
1797 p->send_lowat = clcf->send_lowat; | |
1798 | |
509 | 1799 u->peer.connection->read->handler = ngx_http_upstream_process_body; |
1800 r->write_event_handler = ngx_http_upstream_process_downstream; | |
479 | 1801 |
1802 ngx_http_upstream_process_body(u->peer.connection->read); | |
1803 } | |
1804 | |
1805 | |
487 | 1806 static void |
581 | 1807 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) |
1808 { | |
1809 ngx_http_upstream_process_non_buffered_body(r->connection->write); | |
1810 } | |
1811 | |
1812 | |
1813 static void | |
1814 ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) | |
1815 { | |
1816 size_t size; | |
1817 ssize_t n; | |
1818 ngx_buf_t *b; | |
583 | 1819 ngx_int_t rc; |
581 | 1820 ngx_uint_t do_write; |
884 | 1821 ngx_connection_t *c, *downstream, *upstream; |
581 | 1822 ngx_http_request_t *r; |
1823 ngx_http_upstream_t *u; | |
1824 ngx_http_core_loc_conf_t *clcf; | |
1825 | |
1826 c = ev->data; | |
756
d904b5cb3bba
fix building introduced by previous commit
Igor Sysoev <igor@sysoev.ru>
parents:
755
diff
changeset
|
1827 r = c->data; |
d904b5cb3bba
fix building introduced by previous commit
Igor Sysoev <igor@sysoev.ru>
parents:
755
diff
changeset
|
1828 u = r->upstream; |
581 | 1829 |
1830 if (ev->write) { | |
1831 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1832 "http upstream process non buffered downstream"); | |
1833 c->log->action = "sending to client"; | |
1834 | |
1835 } else { | |
1836 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1837 "http upstream process non buffered upstream"); | |
1838 c->log->action = "reading upstream"; | |
1839 } | |
1840 | |
1841 if (ev->timedout) { | |
1842 if (ev->write) { | |
1843 c->timedout = 1; | |
611 | 1844 ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out"); |
1845 | |
581 | 1846 } else { |
611 | 1847 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
581 | 1848 } |
755
63b9dc652c3d
finalize nonbuffered request on timeout
Igor Sysoev <igor@sysoev.ru>
parents:
751
diff
changeset
|
1849 |
63b9dc652c3d
finalize nonbuffered request on timeout
Igor Sysoev <igor@sysoev.ru>
parents:
751
diff
changeset
|
1850 ngx_http_upstream_finalize_request(r, u, 0); |
63b9dc652c3d
finalize nonbuffered request on timeout
Igor Sysoev <igor@sysoev.ru>
parents:
751
diff
changeset
|
1851 return; |
581 | 1852 } |
1853 | |
884 | 1854 downstream = r->connection; |
1855 upstream = u->peer.connection; | |
581 | 1856 |
1857 b = &u->buffer; | |
1858 | |
1859 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1860 | |
657 | 1861 do_write = ev->write || u->length == 0; |
581 | 1862 |
1863 for ( ;; ) { | |
1864 | |
1865 if (do_write) { | |
1866 | |
1867 if (u->out_bufs || u->busy_bufs) { | |
583 | 1868 rc = ngx_http_output_filter(r, u->out_bufs); |
1869 | |
884 | 1870 if (downstream->destroyed) { |
583 | 1871 return; |
1872 } | |
1873 | |
1874 if (rc == NGX_ERROR) { | |
581 | 1875 ngx_http_upstream_finalize_request(r, u, 0); |
1876 return; | |
1877 } | |
1878 | |
1879 ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs, | |
1880 &u->out_bufs, u->output.tag); | |
1881 } | |
1882 | |
1883 if (u->busy_bufs == NULL) { | |
1884 | |
1885 if (u->length == 0 | |
884 | 1886 || upstream->read->eof |
1887 || upstream->read->error) | |
581 | 1888 { |
1889 ngx_http_upstream_finalize_request(r, u, 0); | |
1890 return; | |
1891 } | |
1892 | |
1893 b->pos = b->start; | |
1894 b->last = b->start; | |
1895 } | |
1896 } | |
1897 | |
1898 size = b->end - b->last; | |
1899 | |
1900 if (size > u->length) { | |
1901 size = u->length; | |
1902 } | |
1903 | |
884 | 1904 if (size && upstream->read->ready) { |
1905 | |
1906 n = upstream->recv(upstream, b->last, size); | |
581 | 1907 |
1908 if (n == NGX_AGAIN) { | |
1909 break; | |
1910 } | |
1911 | |
1912 if (n > 0) { | |
1913 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { | |
1914 ngx_http_upstream_finalize_request(r, u, 0); | |
1915 return; | |
1916 } | |
1917 } | |
1918 | |
1919 do_write = 1; | |
1920 | |
1921 continue; | |
1922 } | |
1923 | |
1924 break; | |
1925 } | |
1926 | |
884 | 1927 if (downstream->data == r) { |
1928 if (ngx_handle_write_event(downstream->write, clcf->send_lowat) | |
583 | 1929 == NGX_ERROR) |
1930 { | |
1931 ngx_http_upstream_finalize_request(r, u, 0); | |
1932 return; | |
1933 } | |
581 | 1934 } |
1935 | |
1063
e2a6ecc5a3ae
a non-active client connection must not closed after send timeout
Igor Sysoev <igor@sysoev.ru>
parents:
1031
diff
changeset
|
1936 if (downstream->write->active && !downstream->write->ready) { |
884 | 1937 ngx_add_timer(downstream->write, clcf->send_timeout); |
1938 | |
1939 } else if (downstream->write->timer_set) { | |
1940 ngx_del_timer(downstream->write); | |
581 | 1941 } |
1942 | |
884 | 1943 if (ngx_handle_read_event(upstream->read, 0) == NGX_ERROR) { |
581 | 1944 ngx_http_upstream_finalize_request(r, u, 0); |
1945 return; | |
1946 } | |
1947 | |
1063
e2a6ecc5a3ae
a non-active client connection must not closed after send timeout
Igor Sysoev <igor@sysoev.ru>
parents:
1031
diff
changeset
|
1948 if (upstream->read->active && !upstream->read->ready) { |
884 | 1949 ngx_add_timer(upstream->read, u->conf->read_timeout); |
1950 | |
1951 } else if (upstream->read->timer_set) { | |
1952 ngx_del_timer(upstream->read); | |
581 | 1953 } |
1954 } | |
1955 | |
1956 | |
1957 static ngx_int_t | |
1958 ngx_http_upstream_non_buffered_filter_init(void *data) | |
1959 { | |
1960 return NGX_OK; | |
1961 } | |
1962 | |
1963 | |
1964 static ngx_int_t | |
1965 ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes) | |
1966 { | |
1967 ngx_http_request_t *r = data; | |
1968 | |
1969 ngx_buf_t *b; | |
1970 ngx_chain_t *cl, **ll; | |
1971 ngx_http_upstream_t *u; | |
1972 | |
1973 u = r->upstream; | |
1974 | |
1975 for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { | |
1976 ll = &cl->next; | |
1977 } | |
1978 | |
1979 cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs); | |
1980 if (cl == NULL) { | |
1981 return NGX_ERROR; | |
1982 } | |
1983 | |
1984 *ll = cl; | |
1985 | |
1986 cl->buf->flush = 1; | |
1987 cl->buf->memory = 1; | |
1988 | |
1989 b = &u->buffer; | |
1990 | |
1991 cl->buf->pos = b->last; | |
1992 b->last += bytes; | |
1993 cl->buf->last = b->last; | |
1908
f2953601ed3c
fix memory leak in long-lived non buffered connections
Igor Sysoev <igor@sysoev.ru>
parents:
1902
diff
changeset
|
1994 cl->buf->tag = u->output.tag; |
581 | 1995 |
1996 if (u->length == NGX_MAX_SIZE_T_VALUE) { | |
1997 return NGX_OK; | |
1998 } | |
1999 | |
2000 u->length -= bytes; | |
2001 | |
2002 return NGX_OK; | |
2003 } | |
2004 | |
2005 | |
2006 static void | |
509 | 2007 ngx_http_upstream_process_downstream(ngx_http_request_t *r) |
2008 { | |
2009 ngx_http_upstream_process_body(r->connection->write); | |
2010 } | |
2011 | |
2012 | |
2013 static void | |
487 | 2014 ngx_http_upstream_process_body(ngx_event_t *ev) |
479 | 2015 { |
1885
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2016 ngx_temp_file_t *tf; |
509 | 2017 ngx_event_pipe_t *p; |
583 | 2018 ngx_connection_t *c, *downstream; |
1098 | 2019 ngx_http_log_ctx_t *ctx; |
479 | 2020 ngx_http_request_t *r; |
2021 ngx_http_upstream_t *u; | |
2022 | |
2023 c = ev->data; | |
2024 r = c->data; | |
2025 u = r->upstream; | |
583 | 2026 downstream = r->connection; |
479 | 2027 |
2028 if (ev->write) { | |
483 | 2029 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2030 "http upstream process downstream"); | |
2031 c->log->action = "sending to client"; | |
577 | 2032 |
479 | 2033 } else { |
483 | 2034 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2035 "http upstream process upstream"); | |
2036 c->log->action = "reading upstream"; | |
1098 | 2037 |
2038 ctx = c->log->data; | |
2039 ctx->current_request = r; | |
479 | 2040 } |
577 | 2041 |
581 | 2042 p = u->pipe; |
479 | 2043 |
2044 if (ev->timedout) { | |
2045 if (ev->write) { | |
527 | 2046 if (ev->delayed) { |
2047 | |
2048 ev->timedout = 0; | |
2049 ev->delayed = 0; | |
2050 | |
2051 if (!ev->ready) { | |
2052 ngx_add_timer(ev, p->send_timeout); | |
2053 | |
2054 if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR) | |
2055 { | |
2056 ngx_http_upstream_finalize_request(r, u, 0); | |
2057 return; | |
2058 } | |
2059 | |
2060 return; | |
2061 } | |
2062 | |
2063 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { | |
583 | 2064 |
2065 if (downstream->destroyed) { | |
2066 return; | |
2067 } | |
2068 | |
527 | 2069 ngx_http_upstream_finalize_request(r, u, 0); |
2070 return; | |
2071 } | |
2072 | |
2073 } else { | |
2074 p->downstream_error = 1; | |
577 | 2075 c->timedout = 1; |
611 | 2076 ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out"); |
527 | 2077 } |
479 | 2078 |
2079 } else { | |
577 | 2080 p->upstream_error = 1; |
611 | 2081 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); |
479 | 2082 } |
2083 | |
2084 } else { | |
527 | 2085 if (ev->write && ev->delayed) { |
2086 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
2087 "http downstream delayed"); | |
2088 | |
2089 if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR) { | |
2090 return; | |
2091 } | |
2092 | |
2093 return; | |
2094 } | |
2095 | |
479 | 2096 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { |
583 | 2097 |
2098 if (downstream->destroyed) { | |
2099 return; | |
2100 } | |
2101 | |
479 | 2102 ngx_http_upstream_finalize_request(r, u, 0); |
2103 return; | |
2104 } | |
2105 } | |
577 | 2106 |
479 | 2107 if (u->peer.connection) { |
2108 | |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2109 if (u->store) { |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2110 |
1885
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2111 tf = u->pipe->temp_file; |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2112 |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2113 if (p->upstream_eof |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2114 && u->headers_in.status_n == NGX_HTTP_OK |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2115 && (u->headers_in.content_length_n == -1 |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2116 || (u->headers_in.content_length_n == tf->offset))) |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2117 { |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2118 ngx_http_upstream_store(r, u); |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2119 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2120 } else if ((p->upstream_error |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2121 || (p->upstream_eof |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2122 && u->headers_in.status_n != NGX_HTTP_OK)) |
1885
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2123 && tf->file.fd != NGX_INVALID_FILE) |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2124 { |
1885
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2125 if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) { |
e5897822515f
test response length in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1777
diff
changeset
|
2126 |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2127 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2128 ngx_delete_file_n " \"%s\" failed", |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2129 u->pipe->temp_file->file.name.data); |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2130 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2131 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2132 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2133 |
479 | 2134 #if (NGX_HTTP_FILE_CACHE) |
2135 | |
1565 | 2136 if (p->upstream_done && u->cacheable) { |
479 | 2137 if (ngx_http_cache_update(r) == NGX_ERROR) { |
2138 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); | |
2139 ngx_http_upstream_finalize_request(r, u, 0); | |
2140 return; | |
2141 } | |
2142 | |
1565 | 2143 } else if (p->upstream_eof && u->cacheable) { |
479 | 2144 |
2145 /* TODO: check length & update cache */ | |
2146 | |
2147 if (ngx_http_cache_update(r) == NGX_ERROR) { | |
2148 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); | |
2149 ngx_http_upstream_finalize_request(r, u, 0); | |
2150 return; | |
2151 } | |
2152 } | |
2153 | |
2154 #endif | |
2155 | |
2156 if (p->upstream_done || p->upstream_eof || p->upstream_error) { | |
483 | 2157 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2158 "http upstream exit: %p", p->out); | |
479 | 2159 #if 0 |
2160 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); | |
2161 #endif | |
2162 ngx_http_upstream_finalize_request(r, u, 0); | |
2163 return; | |
2164 } | |
2165 } | |
2166 | |
2167 if (p->downstream_error) { | |
483 | 2168 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2169 "http upstream downstream error"); | |
479 | 2170 |
1565 | 2171 if (!u->cacheable && u->peer.connection) { |
479 | 2172 ngx_http_upstream_finalize_request(r, u, 0); |
2173 } | |
2174 } | |
2175 } | |
2176 | |
2177 | |
487 | 2178 static void |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2179 ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u) |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2180 { |
1947
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2181 size_t root; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2182 time_t lm; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2183 ngx_str_t path; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2184 ngx_temp_file_t *tf; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2185 ngx_ext_rename_file_t ext; |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2186 |
1777 | 2187 tf = u->pipe->temp_file; |
2188 | |
2189 if (tf->file.fd == NGX_INVALID_FILE) { | |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2190 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2191 /* create file for empty 200 response */ |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2192 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2193 tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2194 if (tf == NULL) { |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2195 return; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2196 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2197 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2198 tf->file.fd = NGX_INVALID_FILE; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2199 tf->file.log = r->connection->log; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2200 tf->path = u->conf->temp_path; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2201 tf->pool = r->pool; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2202 tf->persistent = 1; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2203 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2204 if (ngx_create_temp_file(&tf->file, tf->path, tf->pool, |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2205 tf->persistent, tf->clean, tf->access) |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2206 != NGX_OK) |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2207 { |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2208 return; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2209 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2210 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2211 u->pipe->temp_file = tf; |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2212 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2213 |
1947
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2214 ext.access = u->conf->store_access; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2215 ext.time = -1; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2216 ext.create_path = 1; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2217 ext.delete_file = 1; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2218 ext.log = r->connection->log; |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2219 |
1705 | 2220 if (u->headers_in.last_modified) { |
2221 | |
1947
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2222 lm = ngx_http_parse_time(u->headers_in.last_modified->value.data, |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2223 u->headers_in.last_modified->value.len); |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2224 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2225 if (lm != NGX_ERROR) { |
1947
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2226 ext.time = lm; |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2227 ext.fd = tf->file.fd; |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2228 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2229 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2230 |
1295
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2231 if (u->conf->store_lengths == NULL) { |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2232 |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2233 ngx_http_map_uri_to_path(r, &path, &root, 0); |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2234 |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2235 } else { |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2236 if (ngx_http_script_run(r, &path, u->conf->store_lengths->elts, 0, |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2237 u->conf->store_values->elts) |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2238 == NULL) |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2239 { |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2240 return; |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2241 } |
5383f5232364
proxy_store and fastcgi_store were changed,
Igor Sysoev <igor@sysoev.ru>
parents:
1291
diff
changeset
|
2242 } |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2243 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2244 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1947
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2245 "upstream stores \"%s\" to \"%s\"", |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2246 tf->file.name.data, path.data); |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2247 |
94b03bbd328e
use ngx_ext_rename_file() in proxy/fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1916
diff
changeset
|
2248 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); |
1291
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2249 } |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2250 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2251 |
13a4ce6e7f1e
proxy_store and fastcgi_store
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
2252 static void |
487 | 2253 ngx_http_upstream_dummy_handler(ngx_event_t *wev) |
479 | 2254 { |
2255 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, | |
2256 "http upstream dummy handler"); | |
2257 } | |
2258 | |
2259 | |
487 | 2260 static void |
2261 ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, | |
2262 ngx_uint_t ft_type) | |
479 | 2263 { |
884 | 2264 ngx_uint_t status, state; |
479 | 2265 |
2266 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
884 | 2267 "http next upstream, %xi", ft_type); |
479 | 2268 |
2269 #if 0 | |
2270 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); | |
2271 #endif | |
2272 | |
525 | 2273 if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) { |
884 | 2274 state = NGX_PEER_NEXT; |
525 | 2275 } else { |
884 | 2276 state = NGX_PEER_FAILED; |
479 | 2277 } |
525 | 2278 |
1378 | 2279 if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) { |
2280 u->peer.free(&u->peer, u->peer.data, state); | |
2281 } | |
525 | 2282 |
479 | 2283 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { |
2284 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, | |
2285 "upstream timed out"); | |
2286 } | |
577 | 2287 |
479 | 2288 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { |
2289 status = 0; | |
2290 | |
2291 } else { | |
2292 switch(ft_type) { | |
2293 | |
2294 case NGX_HTTP_UPSTREAM_FT_TIMEOUT: | |
2295 status = NGX_HTTP_GATEWAY_TIME_OUT; | |
2296 break; | |
2297 | |
2298 case NGX_HTTP_UPSTREAM_FT_HTTP_500: | |
2299 status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
2300 break; | |
2301 | |
2302 case NGX_HTTP_UPSTREAM_FT_HTTP_404: | |
2303 status = NGX_HTTP_NOT_FOUND; | |
2304 break; | |
2305 | |
2306 /* | |
2307 * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING | |
2308 * never reach here | |
2309 */ | |
2310 | |
2311 default: | |
2312 status = NGX_HTTP_BAD_GATEWAY; | |
2313 } | |
2314 } | |
2315 | |
583 | 2316 if (r->connection->error) { |
479 | 2317 ngx_http_upstream_finalize_request(r, u, |
2318 NGX_HTTP_CLIENT_CLOSED_REQUEST); | |
2319 return; | |
2320 } | |
2321 | |
2322 if (status) { | |
2323 u->state->status = status; | |
2324 | |
525 | 2325 if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) { |
479 | 2326 |
2327 #if (NGX_HTTP_CACHE) | |
2328 | |
2329 if (u->stale && (u->conf->use_stale & ft_type)) { | |
2330 ngx_http_upstream_finalize_request(r, u, | |
525 | 2331 ngx_http_send_cached_response(r)); |
479 | 2332 return; |
2333 } | |
2334 | |
2335 #endif | |
2336 | |
2337 ngx_http_upstream_finalize_request(r, u, status); | |
2338 return; | |
2339 } | |
2340 } | |
2341 | |
2342 if (u->peer.connection) { | |
2343 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2344 "close http upstream connection: %d", | |
2345 u->peer.connection->fd); | |
577 | 2346 #if (NGX_HTTP_SSL) |
884 | 2347 |
577 | 2348 if (u->peer.connection->ssl) { |
884 | 2349 u->peer.connection->ssl->no_wait_shutdown = 1; |
2350 u->peer.connection->ssl->no_send_shutdown = 1; | |
2351 | |
2352 (void) ngx_ssl_shutdown(u->peer.connection); | |
577 | 2353 } |
2354 #endif | |
884 | 2355 |
479 | 2356 ngx_close_connection(u->peer.connection); |
2357 } | |
2358 | |
2359 #if 0 | |
2360 if (u->conf->busy_lock && !u->busy_locked) { | |
2361 ngx_http_upstream_busy_lock(p); | |
2362 return; | |
2363 } | |
2364 #endif | |
2365 | |
2366 ngx_http_upstream_connect(r, u); | |
2367 } | |
2368 | |
2369 | |
487 | 2370 static void |
569 | 2371 ngx_http_upstream_cleanup(void *data) |
2372 { | |
2373 ngx_http_request_t *r = data; | |
2374 | |
1705 | 2375 ngx_http_upstream_t *u; |
2376 | |
569 | 2377 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2378 "cleanup http upstream request: \"%V\"", &r->uri); | |
2379 | |
1705 | 2380 u = r->upstream; |
2381 | |
2382 if (u->resolved && u->resolved->ctx) { | |
2383 ngx_resolve_name_done(u->resolved->ctx); | |
1658 | 2384 } |
2385 | |
1705 | 2386 ngx_http_upstream_finalize_request(r, u, NGX_DONE); |
569 | 2387 } |
2388 | |
2389 | |
2390 static void | |
487 | 2391 ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
2392 ngx_http_upstream_t *u, ngx_int_t rc) | |
479 | 2393 { |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
2394 ngx_time_t *tp; |
563 | 2395 |
483 | 2396 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2397 "finalize http upstream request: %i", rc); | |
479 | 2398 |
569 | 2399 *u->cleanup = NULL; |
2400 | |
1658 | 2401 if (u->state && u->state->response_sec) { |
563 | 2402 tp = ngx_timeofday(); |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
2403 u->state->response_sec = tp->sec - u->state->response_sec; |
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
2404 u->state->response_msec = tp->msec - u->state->response_msec; |
563 | 2405 } |
2406 | |
479 | 2407 u->finalize_request(r, rc); |
2408 | |
1658 | 2409 if (u->peer.free) { |
2410 u->peer.free(&u->peer, u->peer.data, 0); | |
2411 } | |
884 | 2412 |
479 | 2413 if (u->peer.connection) { |
884 | 2414 |
577 | 2415 #if (NGX_HTTP_SSL) |
2416 | |
2417 /* TODO: do not shutdown persistent connection */ | |
2418 | |
2419 if (u->peer.connection->ssl) { | |
884 | 2420 |
2421 /* | |
2422 * We send the "close notify" shutdown alert to the upstream only | |
2423 * and do not wait its "close notify" shutdown alert. | |
2424 * It is acceptable according to the TLS standard. | |
2425 */ | |
2426 | |
2427 u->peer.connection->ssl->no_wait_shutdown = 1; | |
2428 | |
2429 (void) ngx_ssl_shutdown(u->peer.connection); | |
577 | 2430 } |
2431 #endif | |
884 | 2432 |
2433 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2434 "close http upstream connection: %d", | |
2435 u->peer.connection->fd); | |
2436 | |
479 | 2437 ngx_close_connection(u->peer.connection); |
2438 } | |
2439 | |
483 | 2440 u->peer.connection = NULL; |
2441 | |
563 | 2442 if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) |
479 | 2443 { |
2444 rc = 0; | |
2445 } | |
2446 | |
581 | 2447 if (u->pipe && u->pipe->temp_file) { |
479 | 2448 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2449 "http upstream temp fd: %d", | |
581 | 2450 u->pipe->temp_file->file.fd); |
479 | 2451 } |
2452 | |
2453 #if 0 | |
2454 if (u->cache) { | |
2455 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
483 | 2456 "http upstream cache fd: %d", |
479 | 2457 u->cache->ctx.file.fd); |
2458 } | |
2459 #endif | |
2460 | |
515 | 2461 if (rc == NGX_DECLINED) { |
2462 return; | |
2463 } | |
2464 | |
483 | 2465 r->connection->log->action = "sending to client"; |
2466 | |
1259
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2467 if (rc == 0) { |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2468 if (r == r->main) { |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2469 if (!r->post_action) { |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2470 rc = ngx_http_send_special(r, NGX_HTTP_LAST); |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2471 } |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2472 |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2473 } else { |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2474 if (r->out) { |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2475 rc = NGX_AGAIN; |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2476 } |
05b5236c2ff5
if subrequest response was buffered in file, then subrequest was finalized
Igor Sysoev <igor@sysoev.ru>
parents:
1245
diff
changeset
|
2477 } |
479 | 2478 } |
2479 | |
2480 ngx_http_finalize_request(r, rc); | |
2481 } | |
2482 | |
2483 | |
509 | 2484 static ngx_int_t |
2485 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2486 ngx_uint_t offset) | |
577 | 2487 { |
509 | 2488 ngx_table_elt_t **ph; |
577 | 2489 |
509 | 2490 ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset); |
2491 | |
2492 if (*ph == NULL) { | |
2493 *ph = h; | |
2494 } | |
2495 | |
2496 return NGX_OK; | |
2497 } | |
2498 | |
2499 | |
2500 static ngx_int_t | |
2501 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | |
2502 ngx_table_elt_t *h, ngx_uint_t offset) | |
2503 { | |
2504 ngx_array_t *pa; | |
2505 ngx_table_elt_t **ph; | |
2506 | |
2507 pa = (ngx_array_t *) ((char *) &r->upstream->headers_in + offset); | |
2508 | |
2509 if (pa->elts == NULL) { | |
2510 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) | |
2511 { | |
2512 return NGX_ERROR; | |
2513 } | |
2514 } | |
2515 | |
2516 ph = ngx_array_push(pa); | |
2517 if (ph == NULL) { | |
2518 return NGX_ERROR; | |
2519 } | |
2520 | |
2521 *ph = h; | |
2522 | |
2523 return NGX_OK; | |
2524 } | |
2525 | |
2526 | |
2527 static ngx_int_t | |
2528 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2529 ngx_uint_t offset) | |
2530 { | |
2531 return NGX_OK; | |
2532 } | |
2533 | |
2534 | |
2535 static ngx_int_t | |
527 | 2536 ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, |
2537 ngx_uint_t offset) | |
577 | 2538 { |
527 | 2539 ngx_int_t n; |
2540 | |
2541 r->upstream->headers_in.x_accel_limit_rate = h; | |
2542 | |
2543 n = ngx_atoi(h->value.data, h->value.len); | |
2544 | |
2545 if (n != NGX_ERROR) { | |
2546 r->limit_rate = (size_t) n; | |
2547 } | |
2548 | |
2549 return NGX_OK; | |
2550 } | |
2551 | |
2552 | |
2553 static ngx_int_t | |
649 | 2554 ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h, |
2555 ngx_uint_t offset) | |
2556 { | |
2557 u_char c0, c1, c2; | |
2558 | |
2559 if (r->upstream->conf->change_buffering) { | |
2560 | |
2561 if (h->value.len == 2) { | |
2562 c0 = ngx_tolower(h->value.data[0]); | |
2563 c1 = ngx_tolower(h->value.data[1]); | |
2564 | |
2565 if (c0 == 'n' && c1 == 'o') { | |
2566 r->upstream->buffering = 0; | |
2567 } | |
2568 | |
2569 } else if (h->value.len == 3) { | |
2570 c0 = ngx_tolower(h->value.data[0]); | |
2571 c1 = ngx_tolower(h->value.data[1]); | |
2572 c2 = ngx_tolower(h->value.data[2]); | |
2573 | |
2574 if (c0 == 'y' && c1 == 'e' && c2 == 's') { | |
2575 r->upstream->buffering = 1; | |
2576 } | |
2577 } | |
2578 } | |
2579 | |
2580 return NGX_OK; | |
2581 } | |
2582 | |
2583 | |
2584 static ngx_int_t | |
657 | 2585 ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h, |
2586 ngx_uint_t offset) | |
2587 { | |
2588 r->headers_out.override_charset = &h->value; | |
2589 | |
2590 return NGX_OK; | |
2591 } | |
2592 | |
2593 | |
2594 static ngx_int_t | |
509 | 2595 ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
2596 ngx_uint_t offset) | |
2597 { | |
573 | 2598 ngx_table_elt_t *ho, **ph; |
509 | 2599 |
2600 ho = ngx_list_push(&r->headers_out.headers); | |
2601 if (ho == NULL) { | |
2602 return NGX_ERROR; | |
2603 } | |
2604 | |
2605 *ho = *h; | |
2606 | |
573 | 2607 if (offset) { |
2608 ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset); | |
2609 *ph = ho; | |
2610 } | |
2611 | |
509 | 2612 return NGX_OK; |
2613 } | |
2614 | |
2615 | |
2616 static ngx_int_t | |
2617 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, | |
2618 ngx_table_elt_t *h, ngx_uint_t offset) | |
2619 { | |
2620 ngx_array_t *pa; | |
2621 ngx_table_elt_t *ho, **ph; | |
2622 | |
2623 pa = (ngx_array_t *) ((char *) &r->headers_out + offset); | |
2624 | |
2625 if (pa->elts == NULL) { | |
2626 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) | |
2627 { | |
2628 return NGX_ERROR; | |
2629 } | |
2630 } | |
2631 | |
2632 ph = ngx_array_push(pa); | |
2633 if (ph == NULL) { | |
2634 return NGX_ERROR; | |
2635 } | |
2636 | |
2637 ho = ngx_list_push(&r->headers_out.headers); | |
2638 if (ho == NULL) { | |
2639 return NGX_ERROR; | |
2640 } | |
2641 | |
2642 *ho = *h; | |
2643 *ph = ho; | |
2644 | |
2645 return NGX_OK; | |
2646 } | |
2647 | |
2648 | |
2649 static ngx_int_t | |
2650 ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2651 ngx_uint_t offset) | |
2652 { | |
657 | 2653 u_char *p, *last; |
2654 | |
2655 r->headers_out.content_type_len = h->value.len; | |
509 | 2656 r->headers_out.content_type = h->value; |
2657 | |
657 | 2658 for (p = h->value.data; *p; p++) { |
2659 | |
2660 if (*p != ';') { | |
2661 continue; | |
2662 } | |
2663 | |
2664 last = p; | |
2665 | |
2666 while (*++p == ' ') { /* void */ } | |
2667 | |
1968 | 2668 if (*p == '\0') { |
2669 return NGX_OK; | |
2670 } | |
2671 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1098
diff
changeset
|
2672 if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) { |
657 | 2673 continue; |
2674 } | |
2675 | |
2676 p += 8; | |
2677 | |
2678 r->headers_out.content_type_len = last - h->value.data; | |
2679 | |
2244 | 2680 if (*p == '"') { |
2681 p++; | |
2682 } | |
2683 | |
2684 last = h->value.data + h->value.len; | |
2685 | |
2686 if (*(last - 1) == '"') { | |
2687 last--; | |
2688 } | |
2689 | |
2690 r->headers_out.charset.len = last - p; | |
657 | 2691 r->headers_out.charset.data = p; |
1143
c6c42497106c
fix segfault if upstream sends trailing ";" in "charset="
Igor Sysoev <igor@sysoev.ru>
parents:
1109
diff
changeset
|
2692 |
c6c42497106c
fix segfault if upstream sends trailing ";" in "charset="
Igor Sysoev <igor@sysoev.ru>
parents:
1109
diff
changeset
|
2693 return NGX_OK; |
657 | 2694 } |
2695 | |
509 | 2696 return NGX_OK; |
2697 } | |
2698 | |
2699 | |
2700 static ngx_int_t | |
2701 ngx_http_upstream_copy_content_length(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2702 ngx_uint_t offset) | |
2703 { | |
2704 ngx_table_elt_t *ho; | |
2705 | |
2706 ho = ngx_list_push(&r->headers_out.headers); | |
2707 if (ho == NULL) { | |
2708 return NGX_ERROR; | |
2709 } | |
2710 | |
2711 *ho = *h; | |
2712 | |
2713 r->headers_out.content_length = ho; | |
2714 r->headers_out.content_length_n = ngx_atoof(h->value.data, h->value.len); | |
2715 | |
2716 return NGX_OK; | |
2717 } | |
2718 | |
2719 | |
2720 static ngx_int_t | |
2721 ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2722 ngx_uint_t offset) | |
2723 { | |
2724 ngx_int_t rc; | |
2725 ngx_table_elt_t *ho; | |
2726 | |
2727 ho = ngx_list_push(&r->headers_out.headers); | |
2728 if (ho == NULL) { | |
2729 return NGX_ERROR; | |
2730 } | |
2731 | |
2732 *ho = *h; | |
2733 | |
2734 if (r->upstream->rewrite_redirect) { | |
2735 rc = r->upstream->rewrite_redirect(r, ho, 0); | |
2736 | |
529 | 2737 if (rc == NGX_DECLINED) { |
2738 return NGX_OK; | |
2739 } | |
2740 | |
509 | 2741 if (rc == NGX_OK) { |
2742 r->headers_out.location = ho; | |
2743 | |
2744 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2745 "rewritten location: \"%V\"", &ho->value); | |
2746 } | |
2747 | |
2748 return rc; | |
2749 } | |
2750 | |
1653
ea681a6a0c61
set r->headers_out.location for non-local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
1640
diff
changeset
|
2751 if (ho->value.data[0] != '/') { |
ea681a6a0c61
set r->headers_out.location for non-local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
1640
diff
changeset
|
2752 r->headers_out.location = ho; |
ea681a6a0c61
set r->headers_out.location for non-local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
1640
diff
changeset
|
2753 } |
ea681a6a0c61
set r->headers_out.location for non-local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
1640
diff
changeset
|
2754 |
509 | 2755 /* |
2756 * we do not set r->headers_out.location here to avoid the handling | |
2757 * the local redirects without a host name by ngx_http_header_filter() | |
2758 */ | |
2759 | |
2760 return NGX_OK; | |
2761 } | |
2762 | |
2763 | |
2764 static ngx_int_t | |
2765 ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2766 ngx_uint_t offset) | |
2767 { | |
2768 u_char *p; | |
2769 ngx_int_t rc; | |
2770 ngx_table_elt_t *ho; | |
2771 | |
2772 ho = ngx_list_push(&r->headers_out.headers); | |
2773 if (ho == NULL) { | |
2774 return NGX_ERROR; | |
2775 } | |
2776 | |
2777 *ho = *h; | |
2778 | |
2779 if (r->upstream->rewrite_redirect) { | |
2780 | |
1549 | 2781 p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1); |
509 | 2782 |
2783 if (p) { | |
2784 rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data); | |
2785 | |
2786 } else { | |
2787 return NGX_OK; | |
2788 } | |
2789 | |
529 | 2790 if (rc == NGX_DECLINED) { |
2791 return NGX_OK; | |
2792 } | |
2793 | |
509 | 2794 if (rc == NGX_OK) { |
1654 | 2795 r->headers_out.refresh = ho; |
2796 | |
509 | 2797 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2798 "rewritten refresh: \"%V\"", &ho->value); | |
2799 } | |
2800 | |
2801 return rc; | |
2802 } | |
2803 | |
1654 | 2804 r->headers_out.refresh = ho; |
2805 | |
509 | 2806 return NGX_OK; |
2807 } | |
2808 | |
2809 | |
2810 #if (NGX_HTTP_GZIP) | |
2811 | |
2812 static ngx_int_t | |
2813 ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, | |
2814 ngx_table_elt_t *h, ngx_uint_t offset) | |
2815 { | |
2816 ngx_table_elt_t *ho; | |
2817 | |
2818 ho = ngx_list_push(&r->headers_out.headers); | |
2819 if (ho == NULL) { | |
2820 return NGX_ERROR; | |
2821 } | |
2822 | |
2823 *ho = *h; | |
2824 | |
2825 r->headers_out.content_encoding = ho; | |
2826 | |
2827 return NGX_OK; | |
2828 } | |
2829 | |
2830 #endif | |
2831 | |
2832 | |
487 | 2833 static ngx_int_t |
573 | 2834 ngx_http_upstream_add_variables(ngx_conf_t *cf) |
479 | 2835 { |
880 | 2836 ngx_http_variable_t *var, *v; |
479 | 2837 |
573 | 2838 for (v = ngx_http_upstream_vars; v->name.len; v++) { |
2839 var = ngx_http_add_variable(cf, &v->name, v->flags); | |
2840 if (var == NULL) { | |
2841 return NGX_ERROR; | |
2842 } | |
2843 | |
637 | 2844 var->get_handler = v->get_handler; |
573 | 2845 var->data = v->data; |
2846 } | |
2847 | |
479 | 2848 return NGX_OK; |
2849 } | |
509 | 2850 |
2851 | |
573 | 2852 static ngx_int_t |
1181 | 2853 ngx_http_upstream_addr_variable(ngx_http_request_t *r, |
2854 ngx_http_variable_value_t *v, uintptr_t data) | |
2855 { | |
2856 u_char *p; | |
2857 size_t len; | |
2858 ngx_uint_t i; | |
2859 ngx_http_upstream_state_t *state; | |
2860 | |
2861 v->valid = 1; | |
1565 | 2862 v->no_cacheable = 0; |
1181 | 2863 v->not_found = 0; |
2864 | |
2865 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) { | |
2866 v->not_found = 1; | |
2867 return NGX_OK; | |
2868 } | |
2869 | |
2870 len = 0; | |
2871 state = r->upstream_states->elts; | |
2872 | |
2873 for (i = 0; i < r->upstream_states->nelts; i++) { | |
2874 if (state[i].peer) { | |
2875 len += state[i].peer->len + 2; | |
2876 | |
2877 } else { | |
2878 len += 3; | |
2879 } | |
2880 } | |
2881 | |
2049 | 2882 p = ngx_pnalloc(r->pool, len); |
1181 | 2883 if (p == NULL) { |
2884 return NGX_ERROR; | |
2885 } | |
2886 | |
2887 v->data = p; | |
2888 | |
2889 i = 0; | |
2890 | |
2891 for ( ;; ) { | |
2892 if (state[i].peer) { | |
2893 p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len); | |
2894 } | |
2895 | |
2896 if (++i == r->upstream_states->nelts) { | |
2897 break; | |
2898 } | |
2899 | |
2900 if (state[i].peer) { | |
2901 *p++ = ','; | |
2902 *p++ = ' '; | |
2903 | |
2904 } else { | |
2905 *p++ = ' '; | |
2906 *p++ = ':'; | |
2907 *p++ = ' '; | |
2908 | |
2909 if (++i == r->upstream_states->nelts) { | |
2910 break; | |
2911 } | |
2912 | |
2913 continue; | |
2914 } | |
2915 } | |
2916 | |
2917 v->len = p - v->data; | |
2918 | |
2919 return NGX_OK; | |
2920 } | |
2921 | |
2922 | |
2923 static ngx_int_t | |
573 | 2924 ngx_http_upstream_status_variable(ngx_http_request_t *r, |
2925 ngx_http_variable_value_t *v, uintptr_t data) | |
2926 { | |
2927 u_char *p; | |
2928 size_t len; | |
2929 ngx_uint_t i; | |
2930 ngx_http_upstream_state_t *state; | |
2931 | |
2932 v->valid = 1; | |
1565 | 2933 v->no_cacheable = 0; |
573 | 2934 v->not_found = 0; |
2935 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2936 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) { |
573 | 2937 v->not_found = 1; |
2938 return NGX_OK; | |
2939 } | |
2940 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2941 len = r->upstream_states->nelts * (3 + 2); |
573 | 2942 |
2049 | 2943 p = ngx_pnalloc(r->pool, len); |
573 | 2944 if (p == NULL) { |
2945 return NGX_ERROR; | |
2946 } | |
2947 | |
2948 v->data = p; | |
2949 | |
2950 i = 0; | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2951 state = r->upstream_states->elts; |
573 | 2952 |
2953 for ( ;; ) { | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2954 if (state[i].status) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2955 p = ngx_sprintf(p, "%ui", state[i].status); |
573 | 2956 |
2957 } else { | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2958 *p++ = '-'; |
573 | 2959 } |
2960 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2961 if (++i == r->upstream_states->nelts) { |
573 | 2962 break; |
2963 } | |
2964 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2965 if (state[i].peer) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2966 *p++ = ','; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2967 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2968 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2969 } else { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2970 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2971 *p++ = ':'; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2972 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2973 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2974 if (++i == r->upstream_states->nelts) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2975 break; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2976 } |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2977 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2978 continue; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
2979 } |
573 | 2980 } |
2981 | |
2982 v->len = p - v->data; | |
2983 | |
2984 return NGX_OK; | |
2985 } | |
2986 | |
2987 | |
2988 static ngx_int_t | |
2989 ngx_http_upstream_response_time_variable(ngx_http_request_t *r, | |
2990 ngx_http_variable_value_t *v, uintptr_t data) | |
2991 { | |
2992 u_char *p; | |
2993 size_t len; | |
2994 ngx_uint_t i; | |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
2995 ngx_msec_int_t ms; |
573 | 2996 ngx_http_upstream_state_t *state; |
2997 | |
2998 v->valid = 1; | |
1565 | 2999 v->no_cacheable = 0; |
573 | 3000 v->not_found = 0; |
3001 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3002 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) { |
573 | 3003 v->not_found = 1; |
3004 return NGX_OK; | |
3005 } | |
3006 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3007 len = r->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2); |
573 | 3008 |
2049 | 3009 p = ngx_pnalloc(r->pool, len); |
573 | 3010 if (p == NULL) { |
3011 return NGX_ERROR; | |
3012 } | |
3013 | |
3014 v->data = p; | |
3015 | |
3016 i = 0; | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3017 state = r->upstream_states->elts; |
573 | 3018 |
3019 for ( ;; ) { | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3020 if (state[i].status) { |
1640 | 3021 ms = (ngx_msec_int_t) |
3022 (state[i].response_sec * 1000 + state[i].response_msec); | |
889
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
3023 ms = (ms >= 0) ? ms : 0; |
a9a7e4b1a72b
the previous fix does not actually fix overflow
Igor Sysoev <igor@sysoev.ru>
parents:
888
diff
changeset
|
3024 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3025 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3026 } else { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3027 *p++ = '-'; |
573 | 3028 } |
3029 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3030 if (++i == r->upstream_states->nelts) { |
573 | 3031 break; |
3032 } | |
3033 | |
1168
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3034 if (state[i].peer) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3035 *p++ = ','; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3036 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3037 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3038 } else { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3039 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3040 *p++ = ':'; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3041 *p++ = ' '; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3042 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3043 if (++i == r->upstream_states->nelts) { |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3044 break; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3045 } |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3046 |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3047 continue; |
4d0d12446c3b
store the upstream states before X-Accel-Redirect to a next upstream
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
3048 } |
573 | 3049 } |
3050 | |
3051 v->len = p - v->data; | |
3052 | |
3053 return NGX_OK; | |
3054 } | |
3055 | |
3056 | |
1162 | 3057 ngx_int_t |
3058 ngx_http_upstream_header_variable(ngx_http_request_t *r, | |
3059 ngx_http_variable_value_t *v, uintptr_t data) | |
3060 { | |
3061 if (r->upstream == NULL) { | |
3062 v->not_found = 1; | |
3063 return NGX_OK; | |
3064 } | |
3065 | |
3066 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, | |
3067 &r->upstream->headers_in.headers.part, | |
3068 sizeof("upstream_http_") - 1); | |
3069 } | |
3070 | |
3071 | |
651 | 3072 static char * |
3073 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) | |
3074 { | |
884 | 3075 char *rv; |
3076 void *mconf; | |
3077 ngx_str_t *value; | |
3078 ngx_url_t u; | |
3079 ngx_uint_t m; | |
3080 ngx_conf_t pcf; | |
3081 ngx_http_module_t *module; | |
3082 ngx_http_conf_ctx_t *ctx, *http_ctx; | |
3083 ngx_http_upstream_srv_conf_t *uscf; | |
3084 | |
3085 ngx_memzero(&u, sizeof(ngx_url_t)); | |
3086 | |
3087 value = cf->args->elts; | |
3088 u.host = value[1]; | |
3089 u.no_resolve = 1; | |
3090 | |
3091 uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE | |
3092 |NGX_HTTP_UPSTREAM_WEIGHT | |
3093 |NGX_HTTP_UPSTREAM_MAX_FAILS | |
3094 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT | |
3095 |NGX_HTTP_UPSTREAM_DOWN | |
3096 |NGX_HTTP_UPSTREAM_BACKUP); | |
3097 if (uscf == NULL) { | |
3098 return NGX_CONF_ERROR; | |
3099 } | |
3100 | |
651 | 3101 |
3102 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); | |
3103 if (ctx == NULL) { | |
3104 return NGX_CONF_ERROR; | |
3105 } | |
3106 | |
884 | 3107 http_ctx = cf->ctx; |
3108 ctx->main_conf = http_ctx->main_conf; | |
651 | 3109 |
3110 /* the upstream{}'s srv_conf */ | |
3111 | |
3112 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
3113 if (ctx->srv_conf == NULL) { | |
3114 return NGX_CONF_ERROR; | |
3115 } | |
3116 | |
3117 ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf; | |
3118 | |
884 | 3119 uscf->srv_conf = ctx->srv_conf; |
3120 | |
651 | 3121 |
3122 /* the upstream{}'s loc_conf */ | |
3123 | |
3124 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
3125 if (ctx->loc_conf == NULL) { | |
3126 return NGX_CONF_ERROR; | |
3127 } | |
3128 | |
3129 for (m = 0; ngx_modules[m]; m++) { | |
3130 if (ngx_modules[m]->type != NGX_HTTP_MODULE) { | |
3131 continue; | |
3132 } | |
3133 | |
3134 module = ngx_modules[m]->ctx; | |
3135 | |
884 | 3136 if (module->create_srv_conf) { |
3137 mconf = module->create_srv_conf(cf); | |
3138 if (mconf == NULL) { | |
3139 return NGX_CONF_ERROR; | |
3140 } | |
3141 | |
3142 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; | |
3143 } | |
3144 | |
651 | 3145 if (module->create_loc_conf) { |
3146 mconf = module->create_loc_conf(cf); | |
3147 if (mconf == NULL) { | |
3148 return NGX_CONF_ERROR; | |
3149 } | |
3150 | |
3151 ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf; | |
3152 } | |
3153 } | |
3154 | |
3155 | |
3156 /* parse inside upstream{} */ | |
3157 | |
3158 pcf = *cf; | |
3159 cf->ctx = ctx; | |
3160 cf->cmd_type = NGX_HTTP_UPS_CONF; | |
3161 | |
3162 rv = ngx_conf_parse(cf, NULL); | |
3163 | |
3164 *cf = pcf; | |
3165 | |
3166 if (rv != NGX_CONF_OK) { | |
3167 return rv; | |
3168 } | |
3169 | |
3170 if (uscf->servers == NULL) { | |
3171 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3172 "no servers are inside upstream"); | |
3173 return NGX_CONF_ERROR; | |
3174 } | |
3175 | |
3176 return rv; | |
3177 } | |
3178 | |
3179 | |
3180 static char * | |
3181 ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
3182 { | |
3183 ngx_http_upstream_srv_conf_t *uscf = conf; | |
3184 | |
884 | 3185 time_t fail_timeout; |
3186 ngx_str_t *value, s; | |
3187 ngx_url_t u; | |
3188 ngx_int_t weight, max_fails; | |
3189 ngx_uint_t i; | |
3190 ngx_http_upstream_server_t *us; | |
651 | 3191 |
3192 if (uscf->servers == NULL) { | |
884 | 3193 uscf->servers = ngx_array_create(cf->pool, 4, |
3194 sizeof(ngx_http_upstream_server_t)); | |
651 | 3195 if (uscf->servers == NULL) { |
3196 return NGX_CONF_ERROR; | |
3197 } | |
3198 } | |
3199 | |
884 | 3200 us = ngx_array_push(uscf->servers); |
3201 if (us == NULL) { | |
651 | 3202 return NGX_CONF_ERROR; |
3203 } | |
3204 | |
884 | 3205 ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); |
3206 | |
651 | 3207 value = cf->args->elts; |
3208 | |
3209 ngx_memzero(&u, sizeof(ngx_url_t)); | |
3210 | |
3211 u.url = value[1]; | |
906 | 3212 u.default_port = 80; |
651 | 3213 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1558
diff
changeset
|
3214 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { |
651 | 3215 if (u.err) { |
3216 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3217 "%s in upstream \"%V\"", u.err, &u.url); | |
3218 } | |
3219 | |
3220 return NGX_CONF_ERROR; | |
3221 } | |
3222 | |
663 | 3223 weight = 1; |
884 | 3224 max_fails = 1; |
3225 fail_timeout = 10; | |
3226 | |
3227 for (i = 2; i < cf->args->nelts; i++) { | |
3228 | |
3229 if (ngx_strncmp(value[i].data, "weight=", 7) == 0) { | |
3230 | |
3231 if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) { | |
3232 goto invalid; | |
3233 } | |
3234 | |
3235 weight = ngx_atoi(&value[i].data[7], value[i].len - 7); | |
663 | 3236 |
3237 if (weight == NGX_ERROR || weight == 0) { | |
3238 goto invalid; | |
3239 } | |
3240 | |
884 | 3241 continue; |
3242 } | |
3243 | |
3244 if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { | |
3245 | |
3246 if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) { | |
3247 goto invalid; | |
3248 } | |
3249 | |
3250 max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10); | |
3251 | |
3252 if (max_fails == NGX_ERROR) { | |
3253 goto invalid; | |
3254 } | |
3255 | |
3256 continue; | |
663 | 3257 } |
884 | 3258 |
3259 if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) { | |
3260 | |
3261 if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) { | |
3262 goto invalid; | |
3263 } | |
3264 | |
3265 s.len = value[i].len - 13; | |
3266 s.data = &value[i].data[13]; | |
3267 | |
3268 fail_timeout = ngx_parse_time(&s, 1); | |
3269 | |
1973 | 3270 if (fail_timeout == NGX_ERROR) { |
884 | 3271 goto invalid; |
3272 } | |
3273 | |
3274 continue; | |
3275 } | |
3276 | |
1378 | 3277 if (ngx_strncmp(value[i].data, "backup", 6) == 0) { |
3278 | |
3279 if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) { | |
3280 goto invalid; | |
3281 } | |
3282 | |
3283 us->backup = 1; | |
3284 | |
3285 continue; | |
3286 } | |
3287 | |
884 | 3288 if (ngx_strncmp(value[i].data, "down", 4) == 0) { |
3289 | |
3290 if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) { | |
3291 goto invalid; | |
3292 } | |
3293 | |
3294 us->down = 1; | |
3295 | |
3296 continue; | |
3297 } | |
3298 | |
3299 goto invalid; | |
663 | 3300 } |
3301 | |
884 | 3302 us->addrs = u.addrs; |
3303 us->naddrs = u.naddrs; | |
3304 us->weight = weight; | |
3305 us->max_fails = max_fails; | |
3306 us->fail_timeout = fail_timeout; | |
651 | 3307 |
3308 return NGX_CONF_OK; | |
663 | 3309 |
3310 invalid: | |
3311 | |
884 | 3312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
3313 "invalid parameter \"%V\"", &value[i]); | |
663 | 3314 |
3315 return NGX_CONF_ERROR; | |
651 | 3316 } |
3317 | |
3318 | |
3319 ngx_http_upstream_srv_conf_t * | |
884 | 3320 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) |
651 | 3321 { |
3322 ngx_uint_t i; | |
884 | 3323 ngx_http_upstream_server_t *us; |
651 | 3324 ngx_http_upstream_srv_conf_t *uscf, **uscfp; |
3325 ngx_http_upstream_main_conf_t *umcf; | |
3326 | |
884 | 3327 if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) { |
3328 | |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1558
diff
changeset
|
3329 if (ngx_parse_url(cf->pool, u) != NGX_OK) { |
651 | 3330 if (u->err) { |
3331 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3332 "%s in upstream \"%V\"", u->err, &u->url); | |
3333 } | |
3334 | |
3335 return NULL; | |
3336 } | |
3337 } | |
3338 | |
3339 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); | |
3340 | |
3341 uscfp = umcf->upstreams.elts; | |
3342 | |
3343 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
906 | 3344 |
3345 if (uscfp[i]->host.len != u->host.len | |
884 | 3346 || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) |
3347 != 0) | |
3348 { | |
651 | 3349 continue; |
3350 } | |
3351 | |
884 | 3352 if ((flags & NGX_HTTP_UPSTREAM_CREATE) |
3353 && (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE)) | |
651 | 3354 { |
884 | 3355 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
3356 "duplicate upstream \"%V\"", &u->host); | |
3357 return NULL; | |
651 | 3358 } |
884 | 3359 |
906 | 3360 if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && u->port) { |
884 | 3361 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
906 | 3362 "upstream \"%V\" may not have port %d", |
3363 &u->host, u->port); | |
3364 return NULL; | |
3365 } | |
3366 | |
3367 if ((flags & NGX_HTTP_UPSTREAM_CREATE) && uscfp[i]->port) { | |
3368 ngx_log_error(NGX_LOG_WARN, cf->log, 0, | |
3369 "upstream \"%V\" may not have port %d in %s:%ui", | |
3370 &u->host, uscfp[i]->port, | |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1469
diff
changeset
|
3371 uscfp[i]->file_name, uscfp[i]->line); |
906 | 3372 return NULL; |
3373 } | |
3374 | |
3375 if (uscfp[i]->port != u->port) { | |
3376 continue; | |
884 | 3377 } |
3378 | |
1340 | 3379 if (uscfp[i]->default_port && u->default_port |
3380 && uscfp[i]->default_port != u->default_port) | |
3381 { | |
3382 continue; | |
3383 } | |
3384 | |
884 | 3385 return uscfp[i]; |
651 | 3386 } |
3387 | |
3388 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t)); | |
3389 if (uscf == NULL) { | |
3390 return NULL; | |
3391 } | |
3392 | |
884 | 3393 uscf->flags = flags; |
651 | 3394 uscf->host = u->host; |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1469
diff
changeset
|
3395 uscf->file_name = cf->conf_file->file.name.data; |
651 | 3396 uscf->line = cf->conf_file->line; |
906 | 3397 uscf->port = u->port; |
3398 uscf->default_port = u->default_port; | |
884 | 3399 |
3400 if (u->naddrs == 1) { | |
3401 uscf->servers = ngx_array_create(cf->pool, 1, | |
3402 sizeof(ngx_http_upstream_server_t)); | |
3403 if (uscf->servers == NULL) { | |
3404 return NGX_CONF_ERROR; | |
3405 } | |
3406 | |
3407 us = ngx_array_push(uscf->servers); | |
3408 if (us == NULL) { | |
3409 return NGX_CONF_ERROR; | |
3410 } | |
3411 | |
3412 ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); | |
3413 | |
3414 us->addrs = u->addrs; | |
3415 us->naddrs = u->naddrs; | |
3416 } | |
651 | 3417 |
3418 uscfp = ngx_array_push(&umcf->upstreams); | |
3419 if (uscfp == NULL) { | |
3420 return NULL; | |
3421 } | |
3422 | |
3423 *uscfp = uscf; | |
3424 | |
3425 return uscf; | |
3426 } | |
3427 | |
3428 | |
1701
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3429 ngx_int_t |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3430 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3431 ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3432 ngx_str_t *default_hide_headers, ngx_hash_init_t *hash) |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3433 { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3434 ngx_str_t *h; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3435 ngx_uint_t i, j; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3436 ngx_array_t hide_headers; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3437 ngx_hash_key_t *hk; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3438 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3439 if (conf->hide_headers == NGX_CONF_UNSET_PTR |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3440 && conf->pass_headers == NGX_CONF_UNSET_PTR) |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3441 { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3442 conf->hide_headers_hash = prev->hide_headers_hash; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3443 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3444 if (conf->hide_headers_hash.buckets) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3445 return NGX_OK; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3446 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3447 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3448 conf->hide_headers = prev->hide_headers; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3449 conf->pass_headers = prev->pass_headers; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3450 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3451 } else { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3452 if (conf->hide_headers == NGX_CONF_UNSET_PTR) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3453 conf->hide_headers = prev->hide_headers; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3454 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3455 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3456 if (conf->pass_headers == NGX_CONF_UNSET_PTR) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3457 conf->pass_headers = prev->pass_headers; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3458 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3459 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3460 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3461 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3462 != NGX_OK) |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3463 { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3464 return NGX_ERROR; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3465 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3466 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3467 for (h = default_hide_headers; h->len; h++) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3468 hk = ngx_array_push(&hide_headers); |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3469 if (hk == NULL) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3470 return NGX_ERROR; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3471 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3472 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3473 hk->key = *h; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3474 hk->key_hash = ngx_hash_key_lc(h->data, h->len); |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3475 hk->value = (void *) 1; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3476 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3477 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3478 if (conf->hide_headers != NGX_CONF_UNSET_PTR) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3479 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3480 h = conf->hide_headers->elts; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3481 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3482 for (i = 0; i < conf->hide_headers->nelts; i++) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3483 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3484 hk = hide_headers.elts; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3485 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3486 for (j = 0; j < hide_headers.nelts; j++) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3487 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3488 goto exist; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3489 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3490 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3491 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3492 hk = ngx_array_push(&hide_headers); |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3493 if (hk == NULL) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3494 return NGX_ERROR; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3495 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3496 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3497 hk->key = h[i]; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3498 hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len); |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3499 hk->value = (void *) 1; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3500 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3501 exist: |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3502 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3503 continue; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3504 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3505 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3506 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3507 if (conf->pass_headers != NGX_CONF_UNSET_PTR) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3508 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3509 h = conf->pass_headers->elts; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3510 hk = hide_headers.elts; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3511 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3512 for (i = 0; i < conf->pass_headers->nelts; i++) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3513 for (j = 0; j < hide_headers.nelts; j++) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3514 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3515 if (hk[j].key.data == NULL) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3516 continue; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3517 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3518 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3519 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3520 hk[j].key.data = NULL; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3521 break; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3522 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3523 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3524 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3525 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3526 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3527 hash->hash = &conf->hide_headers_hash; |
1706
9242e21d2f8d
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1705
diff
changeset
|
3528 hash->key = ngx_hash_key_lc; |
1701
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3529 hash->pool = cf->pool; |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3530 hash->temp_pool = NULL; |
1706
9242e21d2f8d
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1705
diff
changeset
|
3531 |
1701
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3532 return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts); |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3533 } |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3534 |
40d004d95d88
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
Igor Sysoev <igor@sysoev.ru>
parents:
1699
diff
changeset
|
3535 |
509 | 3536 static void * |
3537 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) | |
3538 { | |
3539 ngx_http_upstream_main_conf_t *umcf; | |
3540 | |
3541 umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t)); | |
3542 if (umcf == NULL) { | |
3543 return NULL; | |
3544 } | |
3545 | |
651 | 3546 if (ngx_array_init(&umcf->upstreams, cf->pool, 4, |
3547 sizeof(ngx_http_upstream_srv_conf_t *)) | |
3548 != NGX_OK) | |
3549 { | |
3550 return NGX_CONF_ERROR; | |
3551 } | |
3552 | |
509 | 3553 return umcf; |
3554 } | |
3555 | |
3556 | |
3557 static char * | |
651 | 3558 ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf) |
509 | 3559 { |
3560 ngx_http_upstream_main_conf_t *umcf = conf; | |
3561 | |
651 | 3562 ngx_uint_t i; |
3563 ngx_array_t headers_in; | |
3564 ngx_hash_key_t *hk; | |
3565 ngx_hash_init_t hash; | |
884 | 3566 ngx_http_upstream_init_pt init; |
651 | 3567 ngx_http_upstream_header_t *header; |
3568 ngx_http_upstream_srv_conf_t **uscfp; | |
3569 | |
3570 uscfp = umcf->upstreams.elts; | |
3571 | |
3572 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
884 | 3573 |
3574 init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream: | |
3575 ngx_http_upstream_init_round_robin; | |
3576 | |
3577 if (init(cf, uscfp[i]) != NGX_OK) { | |
651 | 3578 return NGX_CONF_ERROR; |
3579 } | |
3580 } | |
649 | 3581 |
663 | 3582 |
884 | 3583 /* upstream_headers_in_hash */ |
3584 | |
649 | 3585 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) |
3586 != NGX_OK) | |
509 | 3587 { |
3588 return NGX_CONF_ERROR; | |
3589 } | |
3590 | |
649 | 3591 for (header = ngx_http_upstream_headers_in; header->name.len; header++) { |
3592 hk = ngx_array_push(&headers_in); | |
3593 if (hk == NULL) { | |
3594 return NGX_CONF_ERROR; | |
3595 } | |
3596 | |
3597 hk->key = header->name; | |
3598 hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len); | |
3599 hk->value = header; | |
3600 } | |
3601 | |
3602 hash.hash = &umcf->headers_in_hash; | |
3603 hash.key = ngx_hash_key_lc; | |
3604 hash.max_size = 512; | |
751
bae59a740c40
align hash bucket size to cache line
Igor Sysoev <igor@sysoev.ru>
parents:
750
diff
changeset
|
3605 hash.bucket_size = ngx_align(64, ngx_cacheline_size); |
649 | 3606 hash.name = "upstream_headers_in_hash"; |
3607 hash.pool = cf->pool; | |
3608 hash.temp_pool = NULL; | |
3609 | |
3610 if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) { | |
3611 return NGX_CONF_ERROR; | |
3612 } | |
509 | 3613 |
3614 return NGX_CONF_OK; | |
3615 } |