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