Mercurial > hg > nginx
comparison src/http/ngx_http_upstream.c @ 577:4d9ea73a627a release-0.3.10
nginx-0.3.10-RELEASE import
*) 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 <igor@sysoev.ru> |
---|---|
date | Tue, 15 Nov 2005 13:30:52 +0000 |
parents | 58475592100c |
children | 326634fb9d47 |
comparison
equal
deleted
inserted
replaced
576:3e0b61c26426 | 577:4d9ea73a627a |
---|---|
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, |