Mercurial > hg > nginx-vendor-0-8
comparison src/http/ngx_http_upstream.c @ 58:b55cbf18157e NGINX_0_1_29
nginx 0.1.29
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; bug appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 12 May 2005 00:00:00 +0400 |
parents | 3050baa54a26 |
children | df7d3fff122b |
comparison
equal
deleted
inserted
replaced
57:5df375c55338 | 58:b55cbf18157e |
---|---|
4 */ | 4 */ |
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event_connect.h> | |
9 #include <ngx_http.h> | 10 #include <ngx_http.h> |
10 #include <ngx_event_connect.h> | 11 |
11 | 12 |
12 | 13 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
13 static void ngx_http_upstream_check_broken_connection(ngx_event_t *ev); | 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); | |
14 static void ngx_http_upstream_connect(ngx_http_request_t *r, | 17 static void ngx_http_upstream_connect(ngx_http_request_t *r, |
15 ngx_http_upstream_t *u); | 18 ngx_http_upstream_t *u); |
16 static void ngx_http_upstream_reinit(ngx_http_request_t *r, | 19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, |
17 ngx_http_upstream_t *u); | 20 ngx_http_upstream_t *u); |
18 static void ngx_http_upstream_send_request(ngx_http_request_t *r, | 21 static void ngx_http_upstream_send_request(ngx_http_request_t *r, |
19 ngx_http_upstream_t *u); | 22 ngx_http_upstream_t *u); |
20 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); | 23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); |
21 static void ngx_http_upstream_process_header(ngx_event_t *rev); | 24 static void ngx_http_upstream_process_header(ngx_event_t *rev); |
22 static void ngx_http_upstream_send_response(ngx_http_request_t *r, | 25 static void ngx_http_upstream_send_response(ngx_http_request_t *r, |
23 ngx_http_upstream_t *u); | 26 ngx_http_upstream_t *u); |
27 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); | |
24 static void ngx_http_upstream_process_body(ngx_event_t *ev); | 28 static void ngx_http_upstream_process_body(ngx_event_t *ev); |
25 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); | 29 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); |
26 static void ngx_http_upstream_next(ngx_http_request_t *r, | 30 static void ngx_http_upstream_next(ngx_http_request_t *r, |
27 ngx_http_upstream_t *u, ngx_uint_t ft_type); | 31 ngx_http_upstream_t *u, ngx_uint_t ft_type); |
28 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, | 32 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
29 ngx_http_upstream_t *u, ngx_int_t rc); | 33 ngx_http_upstream_t *u, ngx_int_t rc); |
30 | 34 |
35 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, | |
36 ngx_table_elt_t *h, ngx_uint_t offset); | |
37 static ngx_int_t | |
38 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | |
39 ngx_table_elt_t *h, ngx_uint_t offset); | |
40 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, | |
41 ngx_table_elt_t *h, ngx_uint_t offset); | |
42 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, | |
43 ngx_table_elt_t *h, ngx_uint_t offset); | |
44 static ngx_int_t | |
45 ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r, | |
46 ngx_table_elt_t *h, ngx_uint_t offset); | |
47 static ngx_int_t | |
48 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, | |
49 ngx_table_elt_t *h, ngx_uint_t offset); | |
50 static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r, | |
51 ngx_table_elt_t *h, ngx_uint_t offset); | |
52 static ngx_int_t ngx_http_upstream_copy_content_length(ngx_http_request_t *r, | |
53 ngx_table_elt_t *h, ngx_uint_t offset); | |
54 static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r, | |
55 ngx_table_elt_t *h, ngx_uint_t offset); | |
56 static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, | |
57 ngx_table_elt_t *h, ngx_uint_t offset); | |
58 #if (NGX_HTTP_GZIP) | |
59 static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, | |
60 ngx_table_elt_t *h, ngx_uint_t offset); | |
61 #endif | |
62 | |
31 static size_t ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, | 63 static size_t ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, |
32 uintptr_t data); | 64 uintptr_t data); |
33 static u_char *ngx_http_upstream_log_status(ngx_http_request_t *r, | 65 static u_char *ngx_http_upstream_log_status(ngx_http_request_t *r, |
34 u_char *buf, ngx_http_log_op_t *op); | 66 u_char *buf, ngx_http_log_op_t *op); |
35 | 67 |
68 static u_char *ngx_http_upstream_log_error(ngx_http_request_t *r, u_char *buf, | |
69 size_t len); | |
36 static ngx_int_t ngx_http_upstream_add_log_formats(ngx_conf_t *cf); | 70 static ngx_int_t ngx_http_upstream_add_log_formats(ngx_conf_t *cf); |
71 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); | |
72 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); | |
73 | |
74 | |
75 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { | |
76 | |
77 { ngx_string("Status"), | |
78 ngx_http_upstream_process_header_line, | |
79 offsetof(ngx_http_upstream_headers_in_t, status), | |
80 /* STUB */ ngx_http_upstream_ignore_header_line, 0 }, | |
81 | |
82 { ngx_string("Content-Type"), | |
83 ngx_http_upstream_process_header_line, | |
84 offsetof(ngx_http_upstream_headers_in_t, content_type), | |
85 ngx_http_upstream_copy_content_type, 0 }, | |
86 | |
87 { ngx_string("Content-Length"), | |
88 ngx_http_upstream_process_header_line, | |
89 offsetof(ngx_http_upstream_headers_in_t, content_length), | |
90 ngx_http_upstream_copy_content_length, 0 }, | |
91 | |
92 { ngx_string("Date"), | |
93 ngx_http_upstream_process_header_line, | |
94 offsetof(ngx_http_upstream_headers_in_t, date), | |
95 ngx_http_upstream_conditional_copy_header_line, | |
96 offsetof(ngx_http_upstream_conf_t, pass_date) }, | |
97 | |
98 { ngx_string("Server"), | |
99 ngx_http_upstream_process_header_line, | |
100 offsetof(ngx_http_upstream_headers_in_t, server), | |
101 ngx_http_upstream_conditional_copy_header_line, | |
102 offsetof(ngx_http_upstream_conf_t, pass_server) }, | |
103 | |
104 { ngx_string("Location"), | |
105 ngx_http_upstream_ignore_header_line, 0, | |
106 ngx_http_upstream_rewrite_location, 0 }, | |
107 | |
108 { ngx_string("Refresh"), | |
109 ngx_http_upstream_ignore_header_line, 0, | |
110 ngx_http_upstream_rewrite_refresh, 0 }, | |
111 | |
112 { ngx_string("Cache-Control"), | |
113 ngx_http_upstream_process_multi_header_lines, | |
114 offsetof(ngx_http_upstream_headers_in_t, cache_control), | |
115 ngx_http_upstream_copy_multi_header_lines, | |
116 offsetof(ngx_http_headers_out_t, cache_control) }, | |
117 | |
118 { ngx_string("Connection"), | |
119 ngx_http_upstream_ignore_header_line, 0, | |
120 ngx_http_upstream_ignore_header_line, 0 }, | |
121 | |
122 { ngx_string("X-Pad"), | |
123 ngx_http_upstream_ignore_header_line, 0, | |
124 ngx_http_upstream_ignore_header_line, 0 }, | |
125 | |
126 { ngx_string("X-Powered-By"), | |
127 ngx_http_upstream_ignore_header_line, 0, | |
128 ngx_http_upstream_conditional_copy_header_line, | |
129 offsetof(ngx_http_upstream_conf_t, pass_x_powered_by) }, | |
130 | |
131 { ngx_string("X-Accel-Expires"), | |
132 ngx_http_upstream_process_header_line, | |
133 offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), | |
134 ngx_http_upstream_conditional_copy_header_line, | |
135 offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires) }, | |
136 | |
137 #if (NGX_HTTP_GZIP) | |
138 { ngx_string("Content-Encoding"), | |
139 ngx_http_upstream_process_header_line, | |
140 offsetof(ngx_http_upstream_headers_in_t, content_encoding), | |
141 ngx_http_upstream_copy_content_encoding, 0 }, | |
142 #endif | |
143 | |
144 { ngx_null_string, NULL, 0, NULL, 0 } | |
145 }; | |
37 | 146 |
38 | 147 |
39 ngx_http_module_t ngx_http_upstream_module_ctx = { | 148 ngx_http_module_t ngx_http_upstream_module_ctx = { |
40 ngx_http_upstream_add_log_formats, /* pre conf */ | 149 ngx_http_upstream_add_log_formats, /* preconfiguration */ |
41 | 150 NULL, /* postconfiguration */ |
42 NULL, /* create main configuration */ | 151 |
43 NULL, /* init main configuration */ | 152 ngx_http_upstream_create_main_conf, /* create main configuration */ |
153 ngx_http_core_init_main_conf, /* init main configuration */ | |
44 | 154 |
45 NULL, /* create server configuration */ | 155 NULL, /* create server configuration */ |
46 NULL, /* merge server configuration */ | 156 NULL, /* merge server configuration */ |
47 | 157 |
48 NULL, /* create location configuration */ | 158 NULL, /* create location configuration */ |
49 NULL /* merge location configuration */ | 159 NULL /* merge location configuration */ |
50 }; | 160 }; |
51 | 161 |
52 | 162 |
53 ngx_module_t ngx_http_upstream_module = { | 163 ngx_module_t ngx_http_upstream_module = { |
54 NGX_MODULE, | 164 NGX_MODULE_V1, |
55 &ngx_http_upstream_module_ctx, /* module context */ | 165 &ngx_http_upstream_module_ctx, /* module context */ |
56 NULL, /* module directives */ | 166 NULL, /* module directives */ |
57 NGX_HTTP_MODULE, /* module type */ | 167 NGX_HTTP_MODULE, /* module type */ |
58 NULL, /* init module */ | 168 NULL, /* init module */ |
59 NULL /* init process */ | 169 NULL /* init process */ |
75 | 185 |
76 | 186 |
77 void | 187 void |
78 ngx_http_upstream_init(ngx_http_request_t *r) | 188 ngx_http_upstream_init(ngx_http_request_t *r) |
79 { | 189 { |
80 ngx_connection_t *c; | 190 ngx_connection_t *c; |
81 ngx_http_upstream_t *u; | 191 ngx_http_upstream_t *u; |
192 ngx_http_core_loc_conf_t *clcf; | |
82 | 193 |
83 c = r->connection; | 194 c = r->connection; |
84 | 195 |
85 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 196 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
86 "http init upstream, client timer: %d", c->read->timer_set); | 197 "http init upstream, client timer: %d", c->read->timer_set); |
87 | 198 |
88 if (c->read->timer_set) { | 199 if (c->read->timer_set) { |
89 ngx_del_timer(c->read); | 200 ngx_del_timer(c->read); |
90 } | 201 } |
91 | 202 |
92 c->read->event_handler = ngx_http_upstream_check_broken_connection; | 203 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; |
93 | 204 |
94 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { | 205 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { |
95 | 206 |
96 c->write->event_handler = ngx_http_upstream_check_broken_connection; | 207 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; |
97 | 208 |
98 if (!c->write->active) { | 209 if (!c->write->active) { |
99 if (ngx_add_event(c->write, NGX_WRITE_EVENT, | 210 if (ngx_add_event(c->write, NGX_WRITE_EVENT, |
100 NGX_CLEAR_EVENT) == NGX_ERROR) | 211 NGX_CLEAR_EVENT) == NGX_ERROR) |
101 { | 212 { |
105 } | 216 } |
106 } | 217 } |
107 | 218 |
108 u = r->upstream; | 219 u = r->upstream; |
109 | 220 |
110 u->method = r->method; | 221 u->request_bufs = r->request_body->bufs; |
222 | |
223 if (u->conf->method == NGX_CONF_UNSET_UINT) { | |
224 u->method = r->method; | |
225 | |
226 } else { | |
227 u->method = u->conf->method; | |
228 } | |
111 | 229 |
112 if (u->create_request(r) == NGX_ERROR) { | 230 if (u->create_request(r) == NGX_ERROR) { |
113 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 231 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
114 return; | 232 return; |
115 } | 233 } |
116 | 234 |
117 u->peer.log = r->connection->log; | 235 u->peer.log = r->connection->log; |
118 u->saved_log_ctx = r->connection->log->data; | 236 u->saved_log_handler = r->log_handler; |
119 u->saved_log_handler = r->connection->log->handler; | 237 r->log_handler = ngx_http_upstream_log_error; |
120 r->connection->log->data = u->log_ctx; | 238 |
121 r->connection->log->handler = u->log_handler; | 239 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
122 | 240 |
123 u->output.sendfile = r->connection->sendfile; | 241 u->output.sendfile = r->connection->sendfile; |
124 u->output.pool = r->pool; | 242 u->output.pool = r->pool; |
125 u->output.bufs.num = 1; | 243 u->output.bufs.num = 1; |
244 u->output.bufs.size = clcf->client_body_buffer_size; | |
126 u->output.output_filter = ngx_chain_writer; | 245 u->output.output_filter = ngx_chain_writer; |
127 u->output.filter_ctx = &u->writer; | 246 u->output.filter_ctx = &u->writer; |
128 | 247 |
129 u->writer.pool = r->pool; | 248 u->writer.pool = r->pool; |
130 | 249 |
146 ngx_http_upstream_connect(r, u); | 265 ngx_http_upstream_connect(r, u); |
147 } | 266 } |
148 | 267 |
149 | 268 |
150 static void | 269 static void |
151 ngx_http_upstream_check_broken_connection(ngx_event_t *ev) | 270 ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r) |
271 { | |
272 ngx_http_upstream_check_broken_connection(r, r->connection->read); | |
273 } | |
274 | |
275 | |
276 static void | |
277 ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r) | |
278 { | |
279 ngx_http_upstream_check_broken_connection(r, r->connection->write); | |
280 } | |
281 | |
282 | |
283 static void | |
284 ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, | |
285 ngx_event_t *ev) | |
152 { | 286 { |
153 int n; | 287 int n; |
154 char buf[1]; | 288 char buf[1]; |
155 ngx_err_t err; | 289 ngx_err_t err; |
156 ngx_connection_t *c; | 290 ngx_connection_t *c; |
157 ngx_http_request_t *r; | |
158 ngx_http_upstream_t *u; | 291 ngx_http_upstream_t *u; |
159 | 292 |
160 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, | 293 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, |
161 "http upstream check client, write event:%d", ev->write); | 294 "http upstream check client, write event:%d", ev->write); |
162 | 295 |
163 c = ev->data; | 296 c = r->connection; |
164 r = c->data; | |
165 u = r->upstream; | 297 u = r->upstream; |
166 | 298 |
167 if (u->peer.connection == NULL) { | 299 if (u->peer.connection == NULL) { |
168 return; | 300 return; |
169 } | 301 } |
294 } | 426 } |
295 | 427 |
296 c = u->peer.connection; | 428 c = u->peer.connection; |
297 | 429 |
298 c->data = r; | 430 c->data = r; |
299 c->write->event_handler = ngx_http_upstream_send_request_handler; | 431 c->write->handler = ngx_http_upstream_send_request_handler; |
300 c->read->event_handler = ngx_http_upstream_process_header; | 432 c->read->handler = ngx_http_upstream_process_header; |
301 | 433 |
302 c->sendfile = r->connection->sendfile; | 434 c->sendfile = r->connection->sendfile; |
303 | 435 |
304 c->pool = r->pool; | 436 c->pool = r->pool; |
305 c->read->log = c->write->log = c->log = r->connection->log; | 437 c->read->log = c->write->log = c->log = r->connection->log; |
310 u->writer.last = &u->writer.out; | 442 u->writer.last = &u->writer.out; |
311 u->writer.connection = c; | 443 u->writer.connection = c; |
312 u->writer.limit = 0; | 444 u->writer.limit = 0; |
313 | 445 |
314 if (u->request_sent) { | 446 if (u->request_sent) { |
315 ngx_http_upstream_reinit(r, u); | 447 if (ngx_http_upstream_reinit(r, u) != NGX_OK) { |
316 } | 448 ngx_http_upstream_finalize_request(r, u, |
317 | 449 NGX_HTTP_INTERNAL_SERVER_ERROR); |
318 if (r->request_body->buf) { | 450 return; |
319 if (r->request_body->temp_file) { | 451 } |
452 } | |
453 | |
454 if (r->request_body) { | |
455 if (r->request_body->temp_file && r->main == NULL) { | |
456 | |
457 /* | |
458 * the r->request_body->buf can be reused for one request only, | |
459 * the subrequests should allocate their own temporay bufs | |
460 */ | |
320 | 461 |
321 u->output.free = ngx_alloc_chain_link(r->pool); | 462 u->output.free = ngx_alloc_chain_link(r->pool); |
322 if (u->output.free == NULL) { | 463 if (u->output.free == NULL) { |
323 ngx_http_upstream_finalize_request(r, u, | 464 ngx_http_upstream_finalize_request(r, u, |
324 NGX_HTTP_INTERNAL_SERVER_ERROR); | 465 NGX_HTTP_INTERNAL_SERVER_ERROR); |
330 u->output.allocated = 1; | 471 u->output.allocated = 1; |
331 | 472 |
332 r->request_body->buf->pos = r->request_body->buf->start; | 473 r->request_body->buf->pos = r->request_body->buf->start; |
333 r->request_body->buf->last = r->request_body->buf->start; | 474 r->request_body->buf->last = r->request_body->buf->start; |
334 r->request_body->buf->tag = u->output.tag; | 475 r->request_body->buf->tag = u->output.tag; |
335 | |
336 } else { | |
337 r->request_body->buf->pos = r->request_body->buf->start; | |
338 } | 476 } |
339 } | 477 } |
340 | 478 |
341 u->request_sent = 0; | 479 u->request_sent = 0; |
342 | 480 |
349 | 487 |
350 ngx_http_upstream_send_request(r, u); | 488 ngx_http_upstream_send_request(r, u); |
351 } | 489 } |
352 | 490 |
353 | 491 |
354 static void | 492 static ngx_int_t |
355 ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u) | 493 ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u) |
356 { | 494 { |
357 ngx_chain_t *cl; | 495 ngx_chain_t *cl; |
358 | 496 |
359 if (u->reinit_request(r) == NGX_ERROR) { | 497 if (u->reinit_request(r) != NGX_OK) { |
360 ngx_http_upstream_finalize_request(r, u, | 498 return NGX_ERROR; |
361 NGX_HTTP_INTERNAL_SERVER_ERROR); | 499 } |
362 return; | 500 |
501 ngx_memzero(&r->upstream->headers_in, | |
502 sizeof(ngx_http_upstream_headers_in_t)); | |
503 | |
504 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, | |
505 sizeof(ngx_table_elt_t)) != NGX_OK) | |
506 { | |
507 return NGX_ERROR; | |
363 } | 508 } |
364 | 509 |
365 /* reinit the request chain */ | 510 /* reinit the request chain */ |
366 | 511 |
367 for (cl = r->request_body->bufs; cl; cl = cl->next) { | 512 for (cl = u->request_bufs; cl; cl = cl->next) { |
368 cl->buf->pos = cl->buf->start; | 513 cl->buf->pos = cl->buf->start; |
369 cl->buf->file_pos = 0; | 514 cl->buf->file_pos = 0; |
370 } | 515 } |
371 | 516 |
372 /* reinit the ngx_output_chain() context */ | 517 /* reinit the subrequest's ngx_output_chain() context */ |
518 | |
519 if (r->request_body) { | |
520 if (r->request_body->temp_file && r->main && u->output.buf) { | |
521 | |
522 u->output.free = ngx_alloc_chain_link(r->pool); | |
523 if (u->output.free == NULL) { | |
524 return NGX_ERROR; | |
525 } | |
526 | |
527 u->output.free->buf = u->output.buf; | |
528 u->output.free->next = NULL; | |
529 | |
530 u->output.buf->pos = u->output.buf->start; | |
531 u->output.buf->last = u->output.buf->start; | |
532 } | |
533 } | |
373 | 534 |
374 u->output.buf = NULL; | 535 u->output.buf = NULL; |
375 u->output.in = NULL; | 536 u->output.in = NULL; |
376 u->output.free = NULL; | |
377 u->output.busy = NULL; | 537 u->output.busy = NULL; |
378 | 538 |
379 /* reinit u->header_in buffer */ | 539 /* reinit u->header_in buffer */ |
380 | 540 |
381 #if 0 | 541 #if 0 |
386 } else { | 546 } else { |
387 u->header_in.pos = u->header_in.start; | 547 u->header_in.pos = u->header_in.start; |
388 u->header_in.last = u->header_in.start; | 548 u->header_in.last = u->header_in.start; |
389 } | 549 } |
390 #else | 550 #else |
551 | |
391 u->header_in.pos = u->header_in.start; | 552 u->header_in.pos = u->header_in.start; |
392 u->header_in.last = u->header_in.start; | 553 u->header_in.last = u->header_in.start; |
554 | |
393 #endif | 555 #endif |
394 | 556 |
395 /* add one more state */ | 557 /* add one more state */ |
396 | 558 |
397 u->state = ngx_array_push(&u->states); | 559 u->state = ngx_array_push(&u->states); |
398 if (u->state == NULL) { | 560 if (u->state == NULL) { |
399 ngx_http_upstream_finalize_request(r, u, | 561 return NGX_ERROR; |
400 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
401 return; | |
402 } | 562 } |
403 | 563 |
404 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); | 564 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); |
565 | |
566 return NGX_OK; | |
405 } | 567 } |
406 | 568 |
407 | 569 |
408 static void | 570 static void |
409 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) | 571 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) |
431 | 593 |
432 #endif | 594 #endif |
433 | 595 |
434 c->log->action = "sending request to upstream"; | 596 c->log->action = "sending request to upstream"; |
435 | 597 |
436 rc = ngx_output_chain(&u->output, | 598 rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs); |
437 u->request_sent ? NULL : r->request_body->bufs); | |
438 | 599 |
439 u->request_sent = 1; | 600 u->request_sent = 1; |
440 | 601 |
441 if (rc == NGX_ERROR) { | 602 if (rc == NGX_ERROR) { |
442 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | 603 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
492 ngx_http_upstream_process_header(c->read); | 653 ngx_http_upstream_process_header(c->read); |
493 return; | 654 return; |
494 } | 655 } |
495 #endif | 656 #endif |
496 | 657 |
497 c->write->event_handler = ngx_http_upstream_dummy_handler; | 658 c->write->handler = ngx_http_upstream_dummy_handler; |
498 | 659 |
499 if (ngx_handle_level_write_event(c->write) == NGX_ERROR) { | 660 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
500 ngx_http_upstream_finalize_request(r, u, | 661 ngx_http_upstream_finalize_request(r, u, |
501 NGX_HTTP_INTERNAL_SERVER_ERROR); | 662 NGX_HTTP_INTERNAL_SERVER_ERROR); |
502 return; | 663 return; |
503 } | 664 } |
504 } | 665 } |
573 u->header_in.end = u->header_in.start + u->conf->header_buffer_size; | 734 u->header_in.end = u->header_in.start + u->conf->header_buffer_size; |
574 u->header_in.temporary = 1; | 735 u->header_in.temporary = 1; |
575 | 736 |
576 u->header_in.tag = u->output.tag; | 737 u->header_in.tag = u->output.tag; |
577 | 738 |
739 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, | |
740 sizeof(ngx_table_elt_t)) == NGX_ERROR) | |
741 { | |
742 ngx_http_upstream_finalize_request(r, u, | |
743 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
744 return; | |
745 } | |
746 | |
578 #if 0 | 747 #if 0 |
579 if (u->cache) { | 748 if (u->cache) { |
580 u->header_in.pos += u->cache->ctx.header_size; | 749 u->header_in.pos += u->cache->ctx.header_size; |
581 u->header_in.last = u->header_in.pos; | 750 u->header_in.last = u->header_in.pos; |
582 } | 751 } |
629 if (rc == NGX_AGAIN) { | 798 if (rc == NGX_AGAIN) { |
630 #if 0 | 799 #if 0 |
631 ngx_add_timer(rev, u->read_timeout); | 800 ngx_add_timer(rev, u->read_timeout); |
632 #endif | 801 #endif |
633 | 802 |
634 if (u->header_in.last == u->header_in.end) { | 803 if (u->header_in.pos == u->header_in.end) { |
635 ngx_log_error(NGX_LOG_ERR, rev->log, 0, | 804 ngx_log_error(NGX_LOG_ERR, rev->log, 0, |
636 "upstream sent too big header"); | 805 "upstream sent too big header"); |
637 | 806 |
638 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); | 807 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); |
639 return; | 808 return; |
658 NGX_HTTP_INTERNAL_SERVER_ERROR); | 827 NGX_HTTP_INTERNAL_SERVER_ERROR); |
659 return; | 828 return; |
660 } | 829 } |
661 | 830 |
662 /* rc == NGX_OK */ | 831 /* rc == NGX_OK */ |
832 | |
833 if (r->headers_out.status == NGX_HTTP_INTERNAL_SERVER_ERROR) { | |
834 | |
835 if (u->peer.tries > 1 | |
836 && (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500)) | |
837 { | |
838 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500); | |
839 return; | |
840 } | |
841 | |
842 #if (NGX_HTTP_CACHE) | |
843 | |
844 if (u->peer.tries == 0 | |
845 && u->stale | |
846 && (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500)) | |
847 { | |
848 ngx_http_upstream_finalize_request(r, u, | |
849 ngx_http_send_cached_response(r)); | |
850 return; | |
851 } | |
852 | |
853 #endif | |
854 } | |
855 | |
856 if (r->headers_out.status == NGX_HTTP_NOT_FOUND | |
857 && u->peer.tries > 1 | |
858 && u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404) | |
859 { | |
860 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404); | |
861 return; | |
862 } | |
863 | |
663 | 864 |
664 if (r->headers_out.status >= NGX_HTTP_BAD_REQUEST | 865 if (r->headers_out.status >= NGX_HTTP_BAD_REQUEST |
665 && u->conf->redirect_errors | 866 && u->conf->redirect_errors |
666 && r->err_ctx == NULL) | 867 && r->err_ctx == NULL) |
667 { | 868 { |
685 | 886 |
686 | 887 |
687 static void | 888 static void |
688 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) | 889 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) |
689 { | 890 { |
690 ngx_int_t rc; | 891 ngx_int_t rc; |
691 ngx_event_pipe_t *p; | 892 ngx_uint_t i, key; |
692 ngx_http_core_loc_conf_t *clcf; | 893 ngx_list_part_t *part; |
693 | 894 ngx_table_elt_t *h; |
694 rc = u->send_header(r); | 895 ngx_event_pipe_t *p; |
896 ngx_http_core_loc_conf_t *clcf; | |
897 ngx_http_upstream_header_t *hh; | |
898 ngx_http_upstream_main_conf_t *umcf; | |
899 | |
900 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | |
901 hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets; | |
902 | |
903 part = &r->upstream->headers_in.headers.part; | |
904 h = part->elts; | |
905 | |
906 for (i = 0; /* void */; i++) { | |
907 | |
908 if (i >= part->nelts) { | |
909 if (part->next == NULL) { | |
910 break; | |
911 } | |
912 | |
913 part = part->next; | |
914 h = part->elts; | |
915 i = 0; | |
916 } | |
917 | |
918 key = h[i].hash % umcf->headers_in_hash.hash_size; | |
919 | |
920 if (hh[key].name.len == h[i].key.len | |
921 && ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0) | |
922 { | |
923 if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) { | |
924 ngx_http_upstream_finalize_request(r, u, | |
925 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
926 return; | |
927 } | |
928 | |
929 continue; | |
930 } | |
931 | |
932 if (ngx_http_upstream_copy_header_line(r, &h[i], 0) != NGX_OK) { | |
933 ngx_http_upstream_finalize_request(r, u, | |
934 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
935 return; | |
936 } | |
937 } | |
938 | |
939 rc = ngx_http_send_header(r); | |
695 | 940 |
696 if (rc == NGX_ERROR || rc > NGX_OK) { | 941 if (rc == NGX_ERROR || rc > NGX_OK) { |
697 ngx_http_upstream_finalize_request(r, u, rc); | 942 ngx_http_upstream_finalize_request(r, u, rc); |
698 return; | 943 return; |
699 } | 944 } |
818 | 1063 |
819 p->read_timeout = u->conf->read_timeout; | 1064 p->read_timeout = u->conf->read_timeout; |
820 p->send_timeout = clcf->send_timeout; | 1065 p->send_timeout = clcf->send_timeout; |
821 p->send_lowat = clcf->send_lowat; | 1066 p->send_lowat = clcf->send_lowat; |
822 | 1067 |
823 u->peer.connection->read->event_handler = ngx_http_upstream_process_body; | 1068 u->peer.connection->read->handler = ngx_http_upstream_process_body; |
824 r->connection->write->event_handler = ngx_http_upstream_process_body; | 1069 r->write_event_handler = ngx_http_upstream_process_downstream; |
825 | 1070 |
826 ngx_http_upstream_process_body(u->peer.connection->read); | 1071 ngx_http_upstream_process_body(u->peer.connection->read); |
1072 } | |
1073 | |
1074 | |
1075 static void | |
1076 ngx_http_upstream_process_downstream(ngx_http_request_t *r) | |
1077 { | |
1078 ngx_http_upstream_process_body(r->connection->write); | |
827 } | 1079 } |
828 | 1080 |
829 | 1081 |
830 static void | 1082 static void |
831 ngx_http_upstream_process_body(ngx_event_t *ev) | 1083 ngx_http_upstream_process_body(ngx_event_t *ev) |
832 { | 1084 { |
1085 ngx_event_pipe_t *p; | |
833 ngx_connection_t *c; | 1086 ngx_connection_t *c; |
834 ngx_http_request_t *r; | 1087 ngx_http_request_t *r; |
835 ngx_http_upstream_t *u; | 1088 ngx_http_upstream_t *u; |
836 ngx_event_pipe_t *p; | |
837 | 1089 |
838 c = ev->data; | 1090 c = ev->data; |
839 r = c->data; | 1091 r = c->data; |
840 u = r->upstream; | 1092 u = r->upstream; |
841 | 1093 |
1044 && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) | 1296 && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) |
1045 { | 1297 { |
1046 rc = 0; | 1298 rc = 0; |
1047 } | 1299 } |
1048 | 1300 |
1049 if (u->saved_log_ctx) { | |
1050 r->connection->log->data = u->saved_log_ctx; | |
1051 r->connection->log->handler = u->saved_log_handler; | |
1052 } | |
1053 | |
1054 if (u->pipe.temp_file) { | 1301 if (u->pipe.temp_file) { |
1055 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1302 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1056 "http upstream temp fd: %d", | 1303 "http upstream temp fd: %d", |
1057 u->pipe.temp_file->file.fd); | 1304 u->pipe.temp_file->file.fd); |
1058 } | 1305 } |
1063 "http upstream cache fd: %d", | 1310 "http upstream cache fd: %d", |
1064 u->cache->ctx.file.fd); | 1311 u->cache->ctx.file.fd); |
1065 } | 1312 } |
1066 #endif | 1313 #endif |
1067 | 1314 |
1068 if (u->pipe.temp_file) { | 1315 r->log_handler = u->saved_log_handler; |
1069 r->file.fd = u->pipe.temp_file->file.fd; | |
1070 | |
1071 #if 0 | |
1072 } else if (u->cache) { | |
1073 r->file.fd = u->cache->ctx.file.fd; | |
1074 #endif | |
1075 } | |
1076 | |
1077 r->connection->log->action = "sending to client"; | 1316 r->connection->log->action = "sending to client"; |
1078 | 1317 |
1079 if (rc == 0 && r->main == NULL) { | 1318 if (rc == 0 && r->main == NULL) { |
1080 rc = ngx_http_send_last(r); | 1319 rc = ngx_http_send_last(r); |
1081 } | 1320 } |
1082 | 1321 |
1083 ngx_http_finalize_request(r, rc); | 1322 ngx_http_finalize_request(r, rc); |
1084 } | 1323 } |
1324 | |
1325 | |
1326 static ngx_int_t | |
1327 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1328 ngx_uint_t offset) | |
1329 { | |
1330 ngx_table_elt_t **ph; | |
1331 | |
1332 ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset); | |
1333 | |
1334 if (*ph == NULL) { | |
1335 *ph = h; | |
1336 } | |
1337 | |
1338 return NGX_OK; | |
1339 } | |
1340 | |
1341 | |
1342 static ngx_int_t | |
1343 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | |
1344 ngx_table_elt_t *h, ngx_uint_t offset) | |
1345 { | |
1346 ngx_array_t *pa; | |
1347 ngx_table_elt_t **ph; | |
1348 | |
1349 pa = (ngx_array_t *) ((char *) &r->upstream->headers_in + offset); | |
1350 | |
1351 if (pa->elts == NULL) { | |
1352 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) | |
1353 { | |
1354 return NGX_ERROR; | |
1355 } | |
1356 } | |
1357 | |
1358 ph = ngx_array_push(pa); | |
1359 if (ph == NULL) { | |
1360 return NGX_ERROR; | |
1361 } | |
1362 | |
1363 *ph = h; | |
1364 | |
1365 return NGX_OK; | |
1366 } | |
1367 | |
1368 | |
1369 static ngx_int_t | |
1370 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1371 ngx_uint_t offset) | |
1372 { | |
1373 return NGX_OK; | |
1374 } | |
1375 | |
1376 | |
1377 static ngx_int_t | |
1378 ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1379 ngx_uint_t offset) | |
1380 { | |
1381 ngx_table_elt_t *ho; | |
1382 | |
1383 ho = ngx_list_push(&r->headers_out.headers); | |
1384 if (ho == NULL) { | |
1385 return NGX_ERROR; | |
1386 } | |
1387 | |
1388 *ho = *h; | |
1389 | |
1390 return NGX_OK; | |
1391 } | |
1392 | |
1393 | |
1394 static ngx_int_t | |
1395 ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r, | |
1396 ngx_table_elt_t *h, ngx_uint_t offset) | |
1397 { | |
1398 ngx_flag_t *f; | |
1399 ngx_table_elt_t *ho; | |
1400 | |
1401 f = (ngx_flag_t *) ((char *) r->upstream->conf + offset); | |
1402 | |
1403 if (*f == 0) { | |
1404 return NGX_OK; | |
1405 } | |
1406 | |
1407 ho = ngx_list_push(&r->headers_out.headers); | |
1408 if (ho == NULL) { | |
1409 return NGX_ERROR; | |
1410 } | |
1411 | |
1412 *ho = *h; | |
1413 | |
1414 return NGX_OK; | |
1415 } | |
1416 | |
1417 | |
1418 static ngx_int_t | |
1419 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, | |
1420 ngx_table_elt_t *h, ngx_uint_t offset) | |
1421 { | |
1422 ngx_array_t *pa; | |
1423 ngx_table_elt_t *ho, **ph; | |
1424 | |
1425 pa = (ngx_array_t *) ((char *) &r->headers_out + offset); | |
1426 | |
1427 if (pa->elts == NULL) { | |
1428 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) | |
1429 { | |
1430 return NGX_ERROR; | |
1431 } | |
1432 } | |
1433 | |
1434 ph = ngx_array_push(pa); | |
1435 if (ph == NULL) { | |
1436 return NGX_ERROR; | |
1437 } | |
1438 | |
1439 ho = ngx_list_push(&r->headers_out.headers); | |
1440 if (ho == NULL) { | |
1441 return NGX_ERROR; | |
1442 } | |
1443 | |
1444 *ho = *h; | |
1445 *ph = ho; | |
1446 | |
1447 return NGX_OK; | |
1448 } | |
1449 | |
1450 | |
1451 static ngx_int_t | |
1452 ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1453 ngx_uint_t offset) | |
1454 { | |
1455 r->headers_out.content_type = h->value; | |
1456 | |
1457 return NGX_OK; | |
1458 } | |
1459 | |
1460 | |
1461 static ngx_int_t | |
1462 ngx_http_upstream_copy_content_length(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1463 ngx_uint_t offset) | |
1464 { | |
1465 ngx_table_elt_t *ho; | |
1466 | |
1467 ho = ngx_list_push(&r->headers_out.headers); | |
1468 if (ho == NULL) { | |
1469 return NGX_ERROR; | |
1470 } | |
1471 | |
1472 *ho = *h; | |
1473 | |
1474 r->headers_out.content_length = ho; | |
1475 r->headers_out.content_length_n = ngx_atoof(h->value.data, h->value.len); | |
1476 | |
1477 return NGX_OK; | |
1478 } | |
1479 | |
1480 | |
1481 static ngx_int_t | |
1482 ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1483 ngx_uint_t offset) | |
1484 { | |
1485 ngx_int_t rc; | |
1486 ngx_table_elt_t *ho; | |
1487 | |
1488 ho = ngx_list_push(&r->headers_out.headers); | |
1489 if (ho == NULL) { | |
1490 return NGX_ERROR; | |
1491 } | |
1492 | |
1493 *ho = *h; | |
1494 | |
1495 if (r->upstream->rewrite_redirect) { | |
1496 rc = r->upstream->rewrite_redirect(r, ho, 0); | |
1497 | |
1498 if (rc == NGX_OK) { | |
1499 r->headers_out.location = ho; | |
1500 | |
1501 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1502 "rewritten location: \"%V\"", &ho->value); | |
1503 } | |
1504 | |
1505 return rc; | |
1506 } | |
1507 | |
1508 /* | |
1509 * we do not set r->headers_out.location here to avoid the handling | |
1510 * the local redirects without a host name by ngx_http_header_filter() | |
1511 */ | |
1512 | |
1513 return NGX_OK; | |
1514 } | |
1515 | |
1516 | |
1517 static ngx_int_t | |
1518 ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h, | |
1519 ngx_uint_t offset) | |
1520 { | |
1521 u_char *p; | |
1522 ngx_int_t rc; | |
1523 ngx_table_elt_t *ho; | |
1524 | |
1525 ho = ngx_list_push(&r->headers_out.headers); | |
1526 if (ho == NULL) { | |
1527 return NGX_ERROR; | |
1528 } | |
1529 | |
1530 *ho = *h; | |
1531 | |
1532 if (r->upstream->rewrite_redirect) { | |
1533 | |
1534 p = (u_char *) ngx_strstr(ho->value.data, "url="); | |
1535 | |
1536 if (p) { | |
1537 rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data); | |
1538 | |
1539 } else { | |
1540 return NGX_OK; | |
1541 } | |
1542 | |
1543 #if (NGX_DEBUG) | |
1544 if (rc == NGX_OK) { | |
1545 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1546 "rewritten refresh: \"%V\"", &ho->value); | |
1547 } | |
1548 #endif | |
1549 | |
1550 return rc; | |
1551 } | |
1552 | |
1553 return NGX_OK; | |
1554 } | |
1555 | |
1556 | |
1557 #if (NGX_HTTP_GZIP) | |
1558 | |
1559 static ngx_int_t | |
1560 ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r, | |
1561 ngx_table_elt_t *h, ngx_uint_t offset) | |
1562 { | |
1563 ngx_table_elt_t *ho; | |
1564 | |
1565 ho = ngx_list_push(&r->headers_out.headers); | |
1566 if (ho == NULL) { | |
1567 return NGX_ERROR; | |
1568 } | |
1569 | |
1570 *ho = *h; | |
1571 | |
1572 r->headers_out.content_encoding = ho; | |
1573 | |
1574 return NGX_OK; | |
1575 } | |
1576 | |
1577 #endif | |
1085 | 1578 |
1086 | 1579 |
1087 static size_t | 1580 static size_t |
1088 ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, uintptr_t data) | 1581 ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, uintptr_t data) |
1089 { | 1582 { |
1129 *buf++ = ' '; | 1622 *buf++ = ' '; |
1130 } | 1623 } |
1131 } | 1624 } |
1132 | 1625 |
1133 | 1626 |
1134 u_char * | 1627 static u_char * |
1135 ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len) | 1628 ngx_http_upstream_log_error(ngx_http_request_t *r, u_char *buf, size_t len) |
1136 { | 1629 { |
1137 u_char *p; | 1630 u_char *p; |
1138 uintptr_t escape; | 1631 uintptr_t escape; |
1139 ngx_http_log_ctx_t *ctx; | |
1140 ngx_http_request_t *r; | |
1141 ngx_http_upstream_t *u; | 1632 ngx_http_upstream_t *u; |
1142 ngx_peer_connection_t *peer; | 1633 ngx_peer_connection_t *peer; |
1143 | 1634 |
1144 ctx = log->data; | |
1145 r = ctx->request; | |
1146 u = r->upstream; | 1635 u = r->upstream; |
1147 peer = &u->peer; | 1636 peer = &u->peer; |
1148 | 1637 |
1149 p = ngx_snprintf(buf, len, | 1638 p = ngx_snprintf(buf, len, |
1150 " while %s, client: %V, server: %V, URL: \"%V\"," | 1639 ", server: %V, URL: \"%V\"," |
1151 " upstream: %V%V%s%V", | 1640 " upstream: %V%V%s%V", |
1152 log->action, | |
1153 &r->connection->addr_text, | |
1154 &r->server_name, | 1641 &r->server_name, |
1155 &r->unparsed_uri, | 1642 &r->unparsed_uri, |
1156 &u->schema0, | 1643 &u->conf->schema, |
1157 &peer->peers->peer[peer->cur_peer].name, | 1644 &peer->peers->peer[peer->cur_peer].name, |
1158 peer->peers->peer[peer->cur_peer].uri_separator, | 1645 peer->peers->peer[peer->cur_peer].uri_separator, |
1159 &u->uri0); | 1646 &u->conf->uri); |
1160 len -= p - buf; | 1647 len -= p - buf; |
1161 buf = p; | 1648 buf = p; |
1162 | 1649 |
1163 if (r->quoted_uri) { | 1650 if (r->quoted_uri) { |
1164 escape = 2 * ngx_escape_uri(NULL, r->uri.data + u->location0->len, | 1651 escape = 2 * ngx_escape_uri(NULL, r->uri.data + u->conf->location->len, |
1165 r->uri.len - u->location0->len, | 1652 r->uri.len - u->conf->location->len, |
1166 NGX_ESCAPE_URI); | 1653 NGX_ESCAPE_URI); |
1167 } else { | 1654 } else { |
1168 escape = 0; | 1655 escape = 0; |
1169 } | 1656 } |
1170 | 1657 |
1171 if (escape) { | 1658 if (escape) { |
1172 if (len >= r->uri.len - u->location0->len + escape) { | 1659 if (len >= r->uri.len - u->conf->location->len + escape) { |
1173 | 1660 |
1174 ngx_escape_uri(buf, r->uri.data + u->location0->len, | 1661 ngx_escape_uri(buf, r->uri.data + u->conf->location->len, |
1175 r->uri.len - u->location0->len, NGX_ESCAPE_URI); | 1662 r->uri.len - u->conf->location->len, NGX_ESCAPE_URI); |
1176 | 1663 |
1177 buf += r->uri.len - u->location0->len + escape; | 1664 buf += r->uri.len - u->conf->location->len + escape; |
1178 len -= r->uri.len - u->location0->len + escape; | 1665 len -= r->uri.len - u->conf->location->len + escape; |
1179 | 1666 |
1180 if (r->args.len) { | 1667 if (r->args.len) { |
1181 p = ngx_snprintf(buf, len, "?%V", &r->args); | 1668 p = ngx_snprintf(buf, len, "?%V", &r->args); |
1182 len -= p - buf; | 1669 len -= p - buf; |
1183 buf = p; | 1670 buf = p; |
1184 } | 1671 } |
1185 | 1672 |
1186 return ngx_http_log_error_info(r, buf, len); | 1673 return ngx_http_log_error_info(r, buf, len); |
1187 } | 1674 } |
1188 | 1675 |
1189 p = ngx_palloc(r->pool, r->uri.len - u->location0->len + escape); | 1676 p = ngx_palloc(r->pool, r->uri.len - u->conf->location->len + escape); |
1190 if (p == NULL) { | 1677 if (p == NULL) { |
1191 return buf; | 1678 return buf; |
1192 } | 1679 } |
1193 | 1680 |
1194 ngx_escape_uri(p, r->uri.data + u->location0->len, | 1681 ngx_escape_uri(p, r->uri.data + u->conf->location->len, |
1195 r->uri.len - u->location0->len, NGX_ESCAPE_URI); | 1682 r->uri.len - u->conf->location->len, NGX_ESCAPE_URI); |
1196 | 1683 |
1197 p = ngx_cpymem(buf, p, r->uri.len - u->location0->len + escape); | 1684 p = ngx_cpymem(buf, p, r->uri.len - u->conf->location->len + escape); |
1198 | 1685 |
1199 } else { | 1686 } else { |
1200 p = ngx_cpymem(buf, r->uri.data + u->location0->len, | 1687 p = ngx_cpymem(buf, r->uri.data + u->conf->location->len, |
1201 r->uri.len - u->location0->len); | 1688 r->uri.len - u->conf->location->len); |
1202 } | 1689 } |
1203 | 1690 |
1204 len -= p - buf; | 1691 len -= p - buf; |
1205 buf = p; | 1692 buf = p; |
1206 | 1693 |
1230 | 1717 |
1231 op->run = (ngx_http_log_op_run_pt) ngx_http_upstream_log_fmt_ops; | 1718 op->run = (ngx_http_log_op_run_pt) ngx_http_upstream_log_fmt_ops; |
1232 | 1719 |
1233 return NGX_OK; | 1720 return NGX_OK; |
1234 } | 1721 } |
1722 | |
1723 | |
1724 static void * | |
1725 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) | |
1726 { | |
1727 ngx_http_upstream_main_conf_t *umcf; | |
1728 | |
1729 umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t)); | |
1730 if (umcf == NULL) { | |
1731 return NULL; | |
1732 } | |
1733 | |
1734 return umcf; | |
1735 } | |
1736 | |
1737 | |
1738 static char * | |
1739 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) | |
1740 { | |
1741 ngx_http_upstream_main_conf_t *umcf = conf; | |
1742 | |
1743 umcf->headers_in_hash.max_size = 100; | |
1744 umcf->headers_in_hash.bucket_limit = 1; | |
1745 umcf->headers_in_hash.bucket_size = sizeof(ngx_http_upstream_header_t); | |
1746 umcf->headers_in_hash.name = "upstream_headers_in"; | |
1747 | |
1748 if (ngx_hash_init(&umcf->headers_in_hash, cf->pool, | |
1749 ngx_http_upstream_headers_in, 0) != NGX_OK) | |
1750 { | |
1751 return NGX_CONF_ERROR; | |
1752 } | |
1753 | |
1754 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, | |
1755 "http upstream headers_in hash size: %ui, " | |
1756 "max buckets per entry: %ui", | |
1757 umcf->headers_in_hash.hash_size, | |
1758 umcf->headers_in_hash.min_buckets); | |
1759 | |
1760 return NGX_CONF_OK; | |
1761 } |