comparison src/http/ngx_http_upstream.c @ 509:9b8c906f6e63 release-0.1.29

nginx-0.1.29-RELEASE import *) 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; the bug had 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 <igor@sysoev.ru>
date Thu, 12 May 2005 14:58:06 +0000
parents cd3117ad9aab
children c12967aadd87
comparison
equal deleted inserted replaced
508:ca1020ce99ba 509:9b8c906f6e63
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 }