comparison src/http/ngx_http_upstream.c @ 126:df17fbafec8f NGINX_0_3_10

nginx 0.3.10 *) Change: the "valid_referers" directive and the "$invalid_referer" variable were moved to the new ngx_http_referer_module from the ngx_http_rewrite_module. *) Change: the "$apache_bytes_sent" variable name was changed to "$body_bytes_sent". *) Feature: the "$sent_http_..." variables. *) Feature: the "if" directive supports the "=" and "!=" operations. *) Feature: the "proxy_pass" directive supports the HTTPS protocol. *) Feature: the "proxy_set_body" directive. *) Feature: the "post_action" directive. *) Feature: the ngx_http_empty_gif_module. *) Feature: the "worker_cpu_affinity" directive for Linux. *) Bugfix: the "rewrite" directive did not unescape URI part in redirect, now it is unescaped except the %00-%25 and %7F-%FF characters. *) Bugfix: nginx could not be built by the icc 9.0 compiler. *) Bugfix: if the SSI was enabled for zero size static file, then the chunked response was encoded incorrectly.
author Igor Sysoev <http://sysoev.ru>
date Tue, 15 Nov 2005 00:00:00 +0300
parents d25a1d6034f1
children 82d695e3d662
comparison
equal deleted inserted replaced
125:97504de1f89e 126:df17fbafec8f
82 ngx_http_variable_value_t *v, uintptr_t data); 82 ngx_http_variable_value_t *v, uintptr_t data);
83 83
84 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); 84 static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
85 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); 85 static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
86 86
87 #if (NGX_HTTP_SSL)
88 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
89 static void ngx_http_upstream_ssl_shutdown(ngx_connection_t *c,
90 ngx_peer_t *peer);
91 #endif
92
87 93
88 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = { 94 ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
89 95
90 { ngx_string("Status"), 96 { ngx_string("Status"),
91 ngx_http_upstream_process_header_line, 97 ngx_http_upstream_process_header_line,
145 ngx_http_upstream_process_header_line, 151 ngx_http_upstream_process_header_line,
146 offsetof(ngx_http_upstream_headers_in_t, expires), 152 offsetof(ngx_http_upstream_headers_in_t, expires),
147 ngx_http_upstream_copy_header_line, 153 ngx_http_upstream_copy_header_line,
148 offsetof(ngx_http_headers_out_t, expires), 1 }, 154 offsetof(ngx_http_headers_out_t, expires), 1 },
149 155
156 { ngx_string("Accept-Ranges"),
157 ngx_http_upstream_process_header_line,
158 offsetof(ngx_http_upstream_headers_in_t, accept_ranges),
159 ngx_http_upstream_copy_header_line,
160 offsetof(ngx_http_headers_out_t, accept_ranges), 1 },
161
150 { ngx_string("Connection"), 162 { ngx_string("Connection"),
151 ngx_http_upstream_ignore_header_line, 0, 163 ngx_http_upstream_ignore_header_line, 0,
152 ngx_http_upstream_ignore_header_line, 0, 0 }, 164 ngx_http_upstream_ignore_header_line, 0, 0 },
153 165
154 { ngx_string("X-Pad"), 166 { ngx_string("X-Pad"),
197 NULL, /* merge server configuration */ 209 NULL, /* merge server configuration */
198 210
199 NULL, /* create location configuration */ 211 NULL, /* create location configuration */
200 NULL /* merge location configuration */ 212 NULL /* merge location configuration */
201 }; 213 };
202 214
203 215
204 ngx_module_t ngx_http_upstream_module = { 216 ngx_module_t ngx_http_upstream_module = {
205 NGX_MODULE_V1, 217 NGX_MODULE_V1,
206 &ngx_http_upstream_module_ctx, /* module context */ 218 &ngx_http_upstream_module_ctx, /* module context */
207 NULL, /* module directives */ 219 NULL, /* module directives */
264 ngx_del_timer(c->read); 276 ngx_del_timer(c->read);
265 } 277 }
266 278
267 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection; 279 r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
268 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection; 280 r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
269 281
270 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { 282 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
271 283
272 if (!c->write->active) { 284 if (!c->write->active) {
273 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) 285 if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT)
274 == NGX_ERROR) 286 == NGX_ERROR)
357 ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, 369 ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
358 ngx_event_t *ev) 370 ngx_event_t *ev)
359 { 371 {
360 int n; 372 int n;
361 char buf[1]; 373 char buf[1];
362 ngx_err_t err; 374 ngx_err_t err;
363 ngx_connection_t *c; 375 ngx_connection_t *c;
364 ngx_http_upstream_t *u; 376 ngx_http_upstream_t *u;
365 377
366 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0, 378 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
367 "http upstream check client, write event:%d, \"%V\"", 379 "http upstream check client, write event:%d, \"%V\"",
480 492
481 static void 493 static void
482 ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u) 494 ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
483 { 495 {
484 ngx_int_t rc; 496 ngx_int_t rc;
497 ngx_peer_t *peer;
485 ngx_connection_t *c; 498 ngx_connection_t *c;
486 499
487 r->connection->log->action = "connecting to upstream"; 500 r->connection->log->action = "connecting to upstream";
488 501
489 r->connection->single_connection = 0; 502 r->connection->single_connection = 0;
497 ngx_http_upstream_finalize_request(r, u, 510 ngx_http_upstream_finalize_request(r, u,
498 NGX_HTTP_INTERNAL_SERVER_ERROR); 511 NGX_HTTP_INTERNAL_SERVER_ERROR);
499 return; 512 return;
500 } 513 }
501 514
502 u->state->peer = &u->peer.peers->peer[u->peer.cur_peer].name; 515 peer = &u->peer.peers->peer[u->peer.cur_peer];
516 u->state->peer = &peer->name;
503 517
504 if (rc == NGX_BUSY) { 518 if (rc == NGX_BUSY) {
505 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); 519 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
506 } 520 }
507 521
508 if (rc == NGX_BUSY || rc == NGX_DECLINED) { 522 if (rc == NGX_BUSY || rc == NGX_DECLINED) {
509 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); 523 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
510 return; 524 return;
511 } 525 }
526
527 /* rc == NGX_OK || rc == NGX_AGAIN */
512 528
513 c = u->peer.connection; 529 c = u->peer.connection;
514 530
515 c->data = r; 531 c->data = r;
516 c->write->handler = ngx_http_upstream_send_request_handler; 532 c->write->handler = ngx_http_upstream_send_request_handler;
566 return; 582 return;
567 } 583 }
568 584
569 /* rc == NGX_OK */ 585 /* rc == NGX_OK */
570 586
587 #if (NGX_HTTP_SSL)
588
589 if (u->conf->ssl) {
590 if (c->ssl == NULL) {
591
592 if (ngx_ssl_create_connection(u->conf->ssl, c,
593 NGX_SSL_BUFFER|NGX_SSL_CLIENT)
594 == NGX_ERROR)
595 {
596 ngx_http_upstream_finalize_request(r, u,
597 NGX_HTTP_INTERNAL_SERVER_ERROR);
598 return;
599 }
600
601 c->sendfile = 0;
602 }
603
604 if (ngx_ssl_set_session(c, peer->ssl_session) != NGX_OK) {
605 ngx_http_upstream_finalize_request(r, u,
606 NGX_HTTP_INTERNAL_SERVER_ERROR);
607 return;
608 }
609
610 rc = ngx_ssl_handshake(c);
611
612 if (rc == NGX_AGAIN) {
613 c->ssl->handler = ngx_http_upstream_ssl_handshake;
614 return;
615 }
616
617 ngx_http_upstream_ssl_handshake(c);
618
619 return;
620 }
621
622 #endif
623
571 ngx_http_upstream_send_request(r, u); 624 ngx_http_upstream_send_request(r, u);
572 } 625 }
626
627
628 #if (NGX_HTTP_SSL)
629
630 static void
631 ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
632 {
633 ngx_http_request_t *r;
634 ngx_http_upstream_t *u;
635
636 r = c->data;
637 u = r->upstream;
638
639 if (c->ssl->handshaked) {
640
641 c->write->handler = ngx_http_upstream_send_request_handler;
642 c->read->handler = ngx_http_upstream_process_header;
643
644 ngx_http_upstream_send_request(r, u);
645
646 return;
647 }
648
649 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
650
651 }
652
653 #endif
573 654
574 655
575 static ngx_int_t 656 static ngx_int_t
576 ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u) 657 ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
577 { 658 {
589 { 670 {
590 return NGX_ERROR; 671 return NGX_ERROR;
591 } 672 }
592 673
593 /* reinit the request chain */ 674 /* reinit the request chain */
594 675
595 for (cl = u->request_bufs; cl; cl = cl->next) { 676 for (cl = u->request_bufs; cl; cl = cl->next) {
596 cl->buf->pos = cl->buf->start; 677 cl->buf->pos = cl->buf->start;
597 cl->buf->file_pos = 0; 678 cl->buf->file_pos = 0;
598 } 679 }
599 680
615 } 696 }
616 697
617 u->output.buf = NULL; 698 u->output.buf = NULL;
618 u->output.in = NULL; 699 u->output.in = NULL;
619 u->output.busy = NULL; 700 u->output.busy = NULL;
620 701
621 /* reinit u->header_in buffer */ 702 /* reinit u->header_in buffer */
622 703
623 #if 0 704 #if 0
624 if (u->cache) { 705 if (u->cache) {
625 u->header_in.pos = u->header_in.start + u->cache->ctx.header_size; 706 u->header_in.pos = u->header_in.start + u->cache->ctx.header_size;
626 u->header_in.last = u->header_in.pos; 707 u->header_in.last = u->header_in.pos;
627 708
652 static void 733 static void
653 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u) 734 ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
654 { 735 {
655 int rc; 736 int rc;
656 ngx_connection_t *c; 737 ngx_connection_t *c;
657 738
658 c = u->peer.connection; 739 c = u->peer.connection;
659 740
660 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 741 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
661 "http upstream send request"); 742 "http upstream send request");
662 743
708 if (ngx_tcp_push(c->fd) == NGX_ERROR) { 789 if (ngx_tcp_push(c->fd) == NGX_ERROR) {
709 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, 790 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
710 ngx_tcp_push_n " failed"); 791 ngx_tcp_push_n " failed");
711 ngx_http_upstream_finalize_request(r, u, 792 ngx_http_upstream_finalize_request(r, u,
712 NGX_HTTP_INTERNAL_SERVER_ERROR); 793 NGX_HTTP_INTERNAL_SERVER_ERROR);
713 return; 794 return;
714 } 795 }
715 796
716 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; 797 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
717 } 798 }
718 799
719 ngx_add_timer(c->read, u->conf->read_timeout); 800 ngx_add_timer(c->read, u->conf->read_timeout);
720 801
721 #if 1 802 #if 1
722 if (c->read->ready) { 803 if (c->read->ready) {
723 804
724 /* post aio operation */ 805 /* post aio operation */
725 806
726 /* 807 /*
727 * TODO comment 808 * TODO comment
728 * although we can post aio operation just in the end 809 * although we can post aio operation just in the end
797 878
798 if (rev->timedout) { 879 if (rev->timedout) {
799 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); 880 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
800 return; 881 return;
801 } 882 }
802 883
803 if (u->header_in.start == NULL) { 884 if (u->header_in.start == NULL) {
804 u->header_in.start = ngx_palloc(r->pool, u->conf->header_buffer_size); 885 u->header_in.start = ngx_palloc(r->pool, u->conf->header_buffer_size);
805 if (u->header_in.start == NULL) { 886 if (u->header_in.start == NULL) {
806 ngx_http_upstream_finalize_request(r, u, 887 ngx_http_upstream_finalize_request(r, u,
807 NGX_HTTP_INTERNAL_SERVER_ERROR); 888 NGX_HTTP_INTERNAL_SERVER_ERROR);
829 u->header_in.last = u->header_in.pos; 910 u->header_in.last = u->header_in.pos;
830 } 911 }
831 #endif 912 #endif
832 } 913 }
833 914
834 n = ngx_recv(u->peer.connection, u->header_in.last, 915 n = u->peer.connection->recv(u->peer.connection, u->header_in.last,
835 u->header_in.end - u->header_in.last); 916 u->header_in.end - u->header_in.last);
836 917
837 if (n == NGX_AGAIN) { 918 if (n == NGX_AGAIN) {
838 #if 0 919 #if 0
839 ngx_add_timer(rev, u->read_timeout); 920 ngx_add_timer(rev, u->read_timeout);
840 #endif 921 #endif
956 ngx_http_upstream_finalize_request(r, u, 1037 ngx_http_upstream_finalize_request(r, u,
957 NGX_HTTP_INTERNAL_SERVER_ERROR); 1038 NGX_HTTP_INTERNAL_SERVER_ERROR);
958 return; 1039 return;
959 } 1040 }
960 1041
961 *r->headers_out.www_authenticate = 1042 *r->headers_out.www_authenticate =
962 *u->headers_in.www_authenticate; 1043 *u->headers_in.www_authenticate;
963 } 1044 }
964 1045
965 ngx_http_upstream_finalize_request(r, u, 1046 ngx_http_upstream_finalize_request(r, u,
966 u->headers_in.status_n); 1047 u->headers_in.status_n);
983 1064
984 if (i >= part->nelts) { 1065 if (i >= part->nelts) {
985 if (part->next == NULL) { 1066 if (part->next == NULL) {
986 break; 1067 break;
987 } 1068 }
988 1069
989 part = part->next; 1070 part = part->next;
990 h = part->elts; 1071 h = part->elts;
991 i = 0; 1072 i = 0;
992 } 1073 }
993 1074
1052 1133
1053 if (i >= part->nelts) { 1134 if (i >= part->nelts) {
1054 if (part->next == NULL) { 1135 if (part->next == NULL) {
1055 break; 1136 break;
1056 } 1137 }
1057 1138
1058 part = part->next; 1139 part = part->next;
1059 h = part->elts; 1140 h = part->elts;
1060 i = 0; 1141 i = 0;
1061 } 1142 }
1062 1143
1138 p = &u->pipe; 1219 p = &u->pipe;
1139 1220
1140 p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter; 1221 p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter;
1141 p->output_ctx = r; 1222 p->output_ctx = r;
1142 p->tag = u->output.tag; 1223 p->tag = u->output.tag;
1143 p->bufs = u->conf->bufs; 1224 p->bufs = u->conf->bufs;
1144 p->busy_size = u->conf->busy_buffers_size; 1225 p->busy_size = u->conf->busy_buffers_size;
1145 p->upstream = u->peer.connection; 1226 p->upstream = u->peer.connection;
1146 p->downstream = r->connection; 1227 p->downstream = r->connection;
1147 p->pool = r->pool; 1228 p->pool = r->pool;
1148 p->log = r->connection->log; 1229 p->log = r->connection->log;
1149 1230
1150 p->cachable = u->cachable; 1231 p->cachable = u->cachable;
1151 1232
1152 p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); 1233 p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
1153 if (p->temp_file == NULL) { 1234 if (p->temp_file == NULL) {
1154 ngx_http_upstream_finalize_request(r, u, 0); 1235 ngx_http_upstream_finalize_request(r, u, 0);
1157 1238
1158 p->temp_file->file.fd = NGX_INVALID_FILE; 1239 p->temp_file->file.fd = NGX_INVALID_FILE;
1159 p->temp_file->file.log = r->connection->log; 1240 p->temp_file->file.log = r->connection->log;
1160 p->temp_file->path = u->conf->temp_path; 1241 p->temp_file->path = u->conf->temp_path;
1161 p->temp_file->pool = r->pool; 1242 p->temp_file->pool = r->pool;
1162 1243
1163 if (u->cachable) { 1244 if (u->cachable) {
1164 p->temp_file->persistent = 1; 1245 p->temp_file->persistent = 1;
1165 } else { 1246 } else {
1166 p->temp_file->warn = "an upstream response is buffered " 1247 p->temp_file->warn = "an upstream response is buffered "
1167 "to a temporary file"; 1248 "to a temporary file";
1255 1336
1256 if (ev->write) { 1337 if (ev->write) {
1257 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 1338 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1258 "http upstream process downstream"); 1339 "http upstream process downstream");
1259 c->log->action = "sending to client"; 1340 c->log->action = "sending to client";
1260 1341
1261 } else { 1342 } else {
1262 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 1343 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1263 "http upstream process upstream"); 1344 "http upstream process upstream");
1264 c->log->action = "reading upstream"; 1345 c->log->action = "reading upstream";
1265 } 1346 }
1266 1347
1267 p = &u->pipe; 1348 p = &u->pipe;
1268 1349
1269 if (ev->timedout) { 1350 if (ev->timedout) {
1270 if (ev->write) { 1351 if (ev->write) {
1271 if (ev->delayed) { 1352 if (ev->delayed) {
1290 return; 1371 return;
1291 } 1372 }
1292 1373
1293 } else { 1374 } else {
1294 p->downstream_error = 1; 1375 p->downstream_error = 1;
1376 c->timedout = 1;
1295 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, 1377 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
1296 "client timed out"); 1378 "client timed out");
1297 } 1379 }
1298 1380
1299 } else { 1381 } else {
1300 p->upstream_error = 1; 1382 p->upstream_error = 1;
1301 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, 1383 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
1302 "upstream timed out"); 1384 "upstream timed out");
1303 } 1385 }
1304 1386
1305 } else { 1387 } else {
1317 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { 1399 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
1318 ngx_http_upstream_finalize_request(r, u, 0); 1400 ngx_http_upstream_finalize_request(r, u, 0);
1319 return; 1401 return;
1320 } 1402 }
1321 } 1403 }
1322 1404
1323 if (u->peer.connection) { 1405 if (u->peer.connection) {
1324 1406
1325 #if (NGX_HTTP_FILE_CACHE) 1407 #if (NGX_HTTP_FILE_CACHE)
1326 1408
1327 if (p->upstream_done && u->cachable) { 1409 if (p->upstream_done && u->cachable) {
1397 1479
1398 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { 1480 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
1399 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, 1481 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
1400 "upstream timed out"); 1482 "upstream timed out");
1401 } 1483 }
1402 1484
1403 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { 1485 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) {
1404 status = 0; 1486 status = 0;
1405 1487
1406 } else { 1488 } else {
1407 switch(ft_type) { 1489 switch(ft_type) {
1456 1538
1457 if (u->peer.connection) { 1539 if (u->peer.connection) {
1458 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1540 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1459 "close http upstream connection: %d", 1541 "close http upstream connection: %d",
1460 u->peer.connection->fd); 1542 u->peer.connection->fd);
1461 1543 #if (NGX_HTTP_SSL)
1544 if (u->peer.connection->ssl) {
1545 ngx_http_upstream_ssl_shutdown(u->peer.connection,
1546 &u->peer.peers->peer[u->peer.cur_peer]);
1547 }
1548 #endif
1462 ngx_close_connection(u->peer.connection); 1549 ngx_close_connection(u->peer.connection);
1463 } 1550 }
1464 1551
1465 #if 0 1552 #if 0
1466 if (u->conf->busy_lock && !u->busy_locked) { 1553 if (u->conf->busy_lock && !u->busy_locked) {
1506 1593
1507 if (u->peer.connection) { 1594 if (u->peer.connection) {
1508 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1595 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1509 "close http upstream connection: %d", 1596 "close http upstream connection: %d",
1510 u->peer.connection->fd); 1597 u->peer.connection->fd);
1511 1598 #if (NGX_HTTP_SSL)
1599
1600 /* TODO: do not shutdown persistent connection */
1601
1602 if (u->peer.connection->ssl) {
1603 ngx_http_upstream_ssl_shutdown(u->peer.connection,
1604 &u->peer.peers->peer[u->peer.cur_peer]);
1605 }
1606 #endif
1512 ngx_close_connection(u->peer.connection); 1607 ngx_close_connection(u->peer.connection);
1513 } 1608 }
1514 1609
1515 u->peer.connection = NULL; 1610 u->peer.connection = NULL;
1516 1611
1547 1642
1548 ngx_http_finalize_request(r, rc); 1643 ngx_http_finalize_request(r, rc);
1549 } 1644 }
1550 1645
1551 1646
1647 #if (NGX_HTTP_SSL)
1648
1649 static void
1650 ngx_http_upstream_ssl_shutdown(ngx_connection_t *c, ngx_peer_t *peer)
1651 {
1652 /* lock peer mutex */
1653
1654 if (peer->ssl_session) {
1655 ngx_ssl_free_session(peer->ssl_session);
1656 }
1657
1658 peer->ssl_session = ngx_ssl_get_session(c);
1659
1660 /* unlock peer mutex */
1661
1662 /*
1663 * We send the "close notify" shutdown alert to the upstream only
1664 * and do not wait its "close notify" shutdown alert.
1665 * It is acceptable according to the TLS standard.
1666 */
1667
1668 c->ssl->no_wait_shutdown = 1;
1669
1670 (void) ngx_ssl_shutdown(c);
1671 }
1672
1673 #endif
1674
1675
1552 static ngx_int_t 1676 static ngx_int_t
1553 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, 1677 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
1554 ngx_uint_t offset) 1678 ngx_uint_t offset)
1555 { 1679 {
1556 ngx_table_elt_t **ph; 1680 ngx_table_elt_t **ph;
1557 1681
1558 ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset); 1682 ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset);
1559 1683
1560 if (*ph == NULL) { 1684 if (*ph == NULL) {
1561 *ph = h; 1685 *ph = h;
1562 } 1686 }
1601 1725
1602 1726
1603 static ngx_int_t 1727 static ngx_int_t
1604 ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h, 1728 ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
1605 ngx_uint_t offset) 1729 ngx_uint_t offset)
1606 { 1730 {
1607 ngx_int_t n; 1731 ngx_int_t n;
1608 1732
1609 r->upstream->headers_in.x_accel_limit_rate = h; 1733 r->upstream->headers_in.x_accel_limit_rate = h;
1610 1734
1611 n = ngx_atoi(h->value.data, h->value.len); 1735 n = ngx_atoi(h->value.data, h->value.len);
2117 static char * 2241 static char *
2118 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) 2242 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
2119 { 2243 {
2120 ngx_http_upstream_main_conf_t *umcf = conf; 2244 ngx_http_upstream_main_conf_t *umcf = conf;
2121 2245
2122 umcf->headers_in_hash.max_size = 100; 2246 umcf->headers_in_hash.max_size = 100;
2123 umcf->headers_in_hash.bucket_limit = 1; 2247 umcf->headers_in_hash.bucket_limit = 1;
2124 umcf->headers_in_hash.bucket_size = sizeof(ngx_http_upstream_header_t); 2248 umcf->headers_in_hash.bucket_size = sizeof(ngx_http_upstream_header_t);
2125 umcf->headers_in_hash.name = "upstream_headers_in"; 2249 umcf->headers_in_hash.name = "upstream_headers_in";
2126 2250
2127 if (ngx_hash_init(&umcf->headers_in_hash, cf->pool, 2251 if (ngx_hash_init(&umcf->headers_in_hash, cf->pool,