Mercurial > hg > nginx-quic
comparison src/http/modules/proxy/ngx_http_proxy_upstream.c @ 501:d4ea69372b94 release-0.1.25
nginx-0.1.25-RELEASE import
*) Bugfix: nginx did run on Linux parisc.
*) Feature: nginx now does not start under FreeBSD if the sysctl
kern.ipc.somaxconn value is too big.
*) Bugfix: if a request was internally redirected by the
ngx_http_index_module module to the ngx_http_proxy_module or
ngx_http_fastcgi_module modules, then the index file was not closed
after request completion.
*) Feature: the "proxy_pass" can be used in location with regular
expression.
*) Feature: the ngx_http_rewrite_filter_module module supports the
condition like "if ($HTTP_USER_AGENT ~ MSIE)".
*) Bugfix: nginx started too slow if the large number of addresses and
text values were used in the "geo" directive.
*) Change: a variable name must be declared as "$name" in the "geo"
directive. The previous variant without "$" is still supported, but
will be removed soon.
*) Feature: the "%{VARIABLE}v" logging parameter.
*) Feature: the "set $name value" directive.
*) Bugfix: gcc 4.0 compatibility.
*) Feature: the --with-openssl-opt=OPTIONS autoconfiguration directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 19 Mar 2005 12:38:37 +0000 |
parents | 64d9afb209da |
children | ee66921ecd47 |
comparison
equal
deleted
inserted
replaced
500:9a0f304470f5 | 501:d4ea69372b94 |
---|---|
56 ngx_http_request_t *r; | 56 ngx_http_request_t *r; |
57 ngx_http_proxy_upstream_t *u; | 57 ngx_http_proxy_upstream_t *u; |
58 | 58 |
59 r = p->request; | 59 r = p->request; |
60 | 60 |
61 if (!(u = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_upstream_t)))) { | 61 u = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_upstream_t)); |
62 if (u == NULL) { | |
62 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 63 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
63 } | 64 } |
64 | 65 |
65 p->upstream = u; | 66 p->upstream = u; |
66 | 67 |
83 } | 84 } |
84 | 85 |
85 | 86 |
86 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) | 87 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) |
87 { | 88 { |
88 size_t len; | 89 size_t len, loc_len; |
89 ngx_uint_t i, escape, *index; | 90 ngx_uint_t i, escape, *index; |
90 ngx_buf_t *b; | 91 ngx_buf_t *b; |
91 ngx_chain_t *chain; | 92 ngx_chain_t *chain; |
92 ngx_list_part_t *part; | 93 ngx_list_part_t *part; |
93 ngx_table_elt_t *header; | 94 ngx_table_elt_t *header; |
94 ngx_http_request_t *r; | 95 ngx_http_request_t *r; |
95 ngx_http_variable_t *var; | 96 ngx_http_variable_t *var; |
96 ngx_http_variable_value_t *value; | 97 ngx_http_variable_value_t *value; |
98 ngx_http_core_loc_conf_t *clcf; | |
97 ngx_http_core_main_conf_t *cmcf; | 99 ngx_http_core_main_conf_t *cmcf; |
98 ngx_http_proxy_upstream_conf_t *uc; | 100 ngx_http_proxy_upstream_conf_t *uc; |
99 | 101 |
100 r = p->request; | 102 r = p->request; |
101 uc = p->lcf->upstream; | 103 uc = p->lcf->upstream; |
110 | 112 |
111 } else { | 113 } else { |
112 len = r->method_name.len; | 114 len = r->method_name.len; |
113 } | 115 } |
114 | 116 |
117 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
118 | |
119 #if (NGX_PCRE) | |
120 loc_len = (clcf->regex) ? 1 : clcf->name.len; | |
121 #else | |
122 loc_len = clcf->name.len; | |
123 #endif | |
124 | |
115 if (r->quoted_uri) { | 125 if (r->quoted_uri) { |
116 escape = 2 * ngx_escape_uri(NULL, r->uri.data + uc->location->len, | 126 escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
117 r->uri.len - uc->location->len, | 127 r->uri.len - loc_len, NGX_ESCAPE_URI); |
118 NGX_ESCAPE_URI); | |
119 } else { | 128 } else { |
120 escape = 0; | 129 escape = 0; |
121 } | 130 } |
122 | 131 |
123 len += uc->uri.len | 132 len += uc->uri.len |
124 + r->uri.len - uc->location->len + escape | 133 + r->uri.len - loc_len + escape |
125 + sizeof("?") - 1 + r->args.len | 134 + sizeof("?") - 1 + r->args.len |
126 + sizeof(http_version) - 1 | 135 + sizeof(http_version) - 1 |
127 + sizeof(connection_close_header) - 1 | 136 + sizeof(connection_close_header) - 1 |
128 + sizeof(CRLF) - 1; | 137 + sizeof(CRLF) - 1; |
129 | 138 |
188 var = cmcf->variables.elts; | 197 var = cmcf->variables.elts; |
189 index = p->lcf->x_vars->elts; | 198 index = p->lcf->x_vars->elts; |
190 | 199 |
191 for (i = 0; i < p->lcf->x_vars->nelts; i++) { | 200 for (i = 0; i < p->lcf->x_vars->nelts; i++) { |
192 | 201 |
193 if (!(value = ngx_http_get_indexed_variable(r, index[i]))) { | 202 value = ngx_http_get_indexed_variable(r, index[i]); |
203 if (value == NULL) { | |
194 continue; | 204 continue; |
195 } | 205 } |
196 | 206 |
197 if (value->text.len) { | 207 if (value->text.len) { |
198 len += sizeof("X-") - 1 + var[index[i]].name.len | 208 len += sizeof("X-") - 1 + var[index[i]].name.len |
231 | 241 |
232 #if (NGX_DEBUG) | 242 #if (NGX_DEBUG) |
233 len++; | 243 len++; |
234 #endif | 244 #endif |
235 | 245 |
236 if (!(b = ngx_create_temp_buf(r->pool, len))) { | 246 b = ngx_create_temp_buf(r->pool, len); |
247 if (b == NULL) { | |
237 return NULL; | 248 return NULL; |
238 } | 249 } |
239 | 250 |
240 if (!(chain = ngx_alloc_chain_link(r->pool))) { | 251 chain = ngx_alloc_chain_link(r->pool); |
252 if (chain == NULL) { | |
241 return NULL; | 253 return NULL; |
242 } | 254 } |
243 | 255 |
244 chain->buf = b; | 256 chain->buf = b; |
245 chain->next = NULL; | 257 chain->next = NULL; |
256 } | 268 } |
257 | 269 |
258 b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len); | 270 b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len); |
259 | 271 |
260 if (escape) { | 272 if (escape) { |
261 ngx_escape_uri(b->last, r->uri.data + uc->location->len, | 273 ngx_escape_uri(b->last, r->uri.data + loc_len, |
262 r->uri.len - uc->location->len, NGX_ESCAPE_URI); | 274 r->uri.len - loc_len, NGX_ESCAPE_URI); |
263 b->last += r->uri.len - uc->location->len + escape; | 275 b->last += r->uri.len - loc_len + escape; |
264 | 276 |
265 } else { | 277 } else { |
266 b->last = ngx_cpymem(b->last, | 278 b->last = ngx_cpymem(b->last, r->uri.data + loc_len, |
267 r->uri.data + uc->location->len, | 279 r->uri.len - loc_len); |
268 r->uri.len - uc->location->len); | |
269 } | 280 } |
270 | 281 |
271 if (r->args.len > 0) { | 282 if (r->args.len > 0) { |
272 *b->last++ = '?'; | 283 *b->last++ = '?'; |
273 b->last = ngx_cpymem(b->last, r->args.data, r->args.len); | 284 b->last = ngx_cpymem(b->last, r->args.data, r->args.len); |
377 | 388 |
378 | 389 |
379 if (p->lcf->x_vars) { | 390 if (p->lcf->x_vars) { |
380 for (i = 0; i < p->lcf->x_vars->nelts; i++) { | 391 for (i = 0; i < p->lcf->x_vars->nelts; i++) { |
381 | 392 |
382 if (!(value = ngx_http_get_indexed_variable(r, index[i]))) { | 393 value = ngx_http_get_indexed_variable(r, index[i]); |
394 if (value == NULL) { | |
383 continue; | 395 continue; |
384 } | 396 } |
385 | 397 |
386 if (value->text.len == 0) { | 398 if (value->text.len == 0) { |
387 continue; | 399 continue; |
504 } | 516 } |
505 } | 517 } |
506 } | 518 } |
507 | 519 |
508 | 520 |
509 if (!(cl = ngx_http_proxy_create_request(p))) { | 521 cl = ngx_http_proxy_create_request(p); |
522 if (cl == NULL) { | |
510 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 523 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
511 return; | 524 return; |
512 } | 525 } |
513 | 526 |
514 if (r->request_body->bufs) { | 527 if (r->request_body->bufs) { |
515 cl->next = r->request_body->bufs; | 528 cl->next = r->request_body->bufs; |
516 } | 529 } |
517 | 530 |
518 r->request_body->bufs = cl; | 531 r->request_body->bufs = cl; |
519 | 532 |
520 if (!(ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_log_ctx_t)))) { | 533 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_log_ctx_t)); |
534 if (ctx == NULL) { | |
521 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | 535 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); |
522 return; | 536 return; |
523 } | 537 } |
524 ctx->connection = r->connection->number; | 538 ctx->connection = r->connection->number; |
525 ctx->proxy = p; | 539 ctx->proxy = p; |
529 p->saved_handler = r->connection->log->handler; | 543 p->saved_handler = r->connection->log->handler; |
530 r->connection->log->data = ctx; | 544 r->connection->log->data = ctx; |
531 r->connection->log->handler = ngx_http_proxy_log_error; | 545 r->connection->log->handler = ngx_http_proxy_log_error; |
532 p->action = "connecting to upstream"; | 546 p->action = "connecting to upstream"; |
533 | 547 |
534 if (!(output = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)))) { | 548 output = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); |
549 if (output == NULL) { | |
535 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | 550 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); |
536 return; | 551 return; |
537 } | 552 } |
538 | 553 |
539 p->upstream->output_chain_ctx = output; | 554 p->upstream->output_chain_ctx = output; |
542 output->pool = r->pool; | 557 output->pool = r->pool; |
543 output->bufs.num = 1; | 558 output->bufs.num = 1; |
544 output->tag = (ngx_buf_tag_t) &ngx_http_proxy_module; | 559 output->tag = (ngx_buf_tag_t) &ngx_http_proxy_module; |
545 output->output_filter = ngx_chain_writer; | 560 output->output_filter = ngx_chain_writer; |
546 | 561 |
547 if (!(writer = ngx_palloc(r->pool, sizeof(ngx_chain_writer_ctx_t)))) { | 562 writer = ngx_palloc(r->pool, sizeof(ngx_chain_writer_ctx_t)); |
563 if (writer == NULL) { | |
548 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | 564 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); |
549 return; | 565 return; |
550 } | 566 } |
551 | 567 |
552 output->filter_ctx = writer; | 568 output->filter_ctx = writer; |
601 | 617 |
602 /* add one more state */ | 618 /* add one more state */ |
603 | 619 |
604 state = p->state->cache_state; | 620 state = p->state->cache_state; |
605 | 621 |
606 if (!(p->state = ngx_push_array(&p->states))) { | 622 p->state = ngx_array_push(&p->states); |
623 if (p->state == NULL) { | |
607 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | 624 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); |
608 return; | 625 return; |
609 } | 626 } |
610 | 627 |
611 ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t)); | 628 ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t)); |
773 } | 790 } |
774 | 791 |
775 if (r->request_body->buf) { | 792 if (r->request_body->buf) { |
776 if (r->request_body->temp_file) { | 793 if (r->request_body->temp_file) { |
777 | 794 |
778 if (!(output->free = ngx_alloc_chain_link(r->pool))) { | 795 output->free = ngx_alloc_chain_link(r->pool); |
796 if (output->free == NULL) { | |
779 ngx_http_proxy_finalize_request(p, | 797 ngx_http_proxy_finalize_request(p, |
780 NGX_HTTP_INTERNAL_SERVER_ERROR); | 798 NGX_HTTP_INTERNAL_SERVER_ERROR); |
781 return; | 799 return; |
782 } | 800 } |
783 | 801 |
1003 p->upstream->peer.cached = 0; | 1021 p->upstream->peer.cached = 0; |
1004 | 1022 |
1005 rc = ngx_http_proxy_parse_status_line(p); | 1023 rc = ngx_http_proxy_parse_status_line(p); |
1006 | 1024 |
1007 if (rc == NGX_AGAIN) { | 1025 if (rc == NGX_AGAIN) { |
1008 if (p->header_in->pos == p->header_in->last) { | 1026 if (p->header_in->pos == p->header_in->end) { |
1009 ngx_log_error(NGX_LOG_ERR, rev->log, 0, | 1027 ngx_log_error(NGX_LOG_ERR, rev->log, 0, |
1010 "upstream sent too long status line"); | 1028 "upstream sent too long status line"); |
1011 ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_INVALID_HEADER); | 1029 ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_INVALID_HEADER); |
1012 } | 1030 } |
1013 return; | 1031 return; |
1156 | 1174 |
1157 if (rc == NGX_OK) { | 1175 if (rc == NGX_OK) { |
1158 | 1176 |
1159 /* a header line has been parsed successfully */ | 1177 /* a header line has been parsed successfully */ |
1160 | 1178 |
1161 if (!(h = ngx_list_push(&p->upstream->headers_in.headers))) { | 1179 h = ngx_list_push(&p->upstream->headers_in.headers); |
1180 if (h == NULL) { | |
1162 ngx_http_proxy_finalize_request(p, | 1181 ngx_http_proxy_finalize_request(p, |
1163 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1182 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1164 return; | 1183 return; |
1165 } | 1184 } |
1166 | 1185 |
1312 } | 1331 } |
1313 | 1332 |
1314 /* TODO: preallocate event_pipe bufs, look "Content-Length" */ | 1333 /* TODO: preallocate event_pipe bufs, look "Content-Length" */ |
1315 | 1334 |
1316 rc = ngx_http_send_header(r); | 1335 rc = ngx_http_send_header(r); |
1336 | |
1337 if (rc == NGX_ERROR || rc > NGX_OK) { | |
1338 ngx_http_proxy_finalize_request(p, rc); | |
1339 return; | |
1340 } | |
1317 | 1341 |
1318 p->header_sent = 1; | 1342 p->header_sent = 1; |
1319 | 1343 |
1320 if (p->cache && p->cache->ctx.file.fd != NGX_INVALID_FILE) { | 1344 if (p->cache && p->cache->ctx.file.fd != NGX_INVALID_FILE) { |
1321 if (ngx_close_file(p->cache->ctx.file.fd) == NGX_FILE_ERROR) { | 1345 if (ngx_close_file(p->cache->ctx.file.fd) == NGX_FILE_ERROR) { |
1359 ep->pool = r->pool; | 1383 ep->pool = r->pool; |
1360 ep->log = r->connection->log; | 1384 ep->log = r->connection->log; |
1361 | 1385 |
1362 ep->cachable = p->cachable; | 1386 ep->cachable = p->cachable; |
1363 | 1387 |
1364 if (!(ep->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) { | 1388 ep->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); |
1389 if (ep->temp_file == NULL) { | |
1365 ngx_http_proxy_finalize_request(p, 0); | 1390 ngx_http_proxy_finalize_request(p, 0); |
1366 return; | 1391 return; |
1367 } | 1392 } |
1368 | 1393 |
1369 ep->temp_file->file.fd = NGX_INVALID_FILE; | 1394 ep->temp_file->file.fd = NGX_INVALID_FILE; |
1379 } | 1404 } |
1380 | 1405 |
1381 ep->max_temp_file_size = p->lcf->max_temp_file_size; | 1406 ep->max_temp_file_size = p->lcf->max_temp_file_size; |
1382 ep->temp_file_write_size = p->lcf->temp_file_write_size; | 1407 ep->temp_file_write_size = p->lcf->temp_file_write_size; |
1383 | 1408 |
1384 if (!(ep->preread_bufs = ngx_alloc_chain_link(r->pool))) { | 1409 ep->preread_bufs = ngx_alloc_chain_link(r->pool); |
1410 if (ep->preread_bufs == NULL) { | |
1385 ngx_http_proxy_finalize_request(p, 0); | 1411 ngx_http_proxy_finalize_request(p, 0); |
1386 return; | 1412 return; |
1387 } | 1413 } |
1388 ep->preread_bufs->buf = p->header_in; | 1414 ep->preread_bufs->buf = p->header_in; |
1389 ep->preread_bufs->next = NULL; | 1415 ep->preread_bufs->next = NULL; |
1465 | 1491 |
1466 } else { | 1492 } else { |
1467 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, | 1493 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, |
1468 "http proxy process upstream"); | 1494 "http proxy process upstream"); |
1469 p = c->data; | 1495 p = c->data; |
1470 r = p->request; | |
1471 p->action = "reading upstream body"; | 1496 p->action = "reading upstream body"; |
1472 } | 1497 } |
1473 | 1498 |
1474 ep = p->upstream->event_pipe; | 1499 ep = p->upstream->event_pipe; |
1475 | 1500 |