comparison src/http/ngx_http_upstream.c @ 430:dac47e9ef0d5 NGINX_0_7_27

nginx 0.7.27 *) Feature: the "try_files" directive. *) Feature: variables support in the "fastcgi_pass" directive. *) Feature: now the $geo variable may get an address from a variable. Thanks to Andrei Nigmatulin. *) Feature: now a location's modifier may be used without space before name. *) Feature: the $upstream_response_length variable. *) Bugfix: now a "add_header" directive does not add an empty value. *) Bugfix: if zero length static file was requested, then nginx just closed connection; the bug had appeared in 0.7.25. *) Bugfix: a MOVE method could not move file in non-existent directory. *) Bugfix: a segmentation fault occurred in worker process, if no one named location was defined in server, but some one was used in an error_page directive. Thanks to Sergey Bochenkov.
author Igor Sysoev <http://sysoev.ru>
date Mon, 15 Dec 2008 00:00:00 +0300
parents 21aff1b3da48
children fd759445d8a8
comparison
equal deleted inserted replaced
429:3b8e9d1bc9bb 430:dac47e9ef0d5
18 ngx_http_upstream_t *u); 18 ngx_http_upstream_t *u);
19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r, 19 static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
20 ngx_http_upstream_t *u); 20 ngx_http_upstream_t *u);
21 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,
22 ngx_http_upstream_t *u); 22 ngx_http_upstream_t *u);
23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); 23 static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
24 static void ngx_http_upstream_process_header(ngx_event_t *rev); 24 ngx_http_upstream_t *u);
25 static void ngx_http_upstream_process_header(ngx_http_request_t *r,
26 ngx_http_upstream_t *u);
25 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r, 27 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
26 ngx_http_upstream_t *u); 28 ngx_http_upstream_t *u);
27 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, 29 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
28 ngx_http_upstream_t *u); 30 ngx_http_upstream_t *u);
29 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); 31 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
30 static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); 32 static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
33 ngx_http_upstream_t *u);
31 static void ngx_http_upstream_send_response(ngx_http_request_t *r, 34 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
32 ngx_http_upstream_t *u); 35 ngx_http_upstream_t *u);
33 static void 36 static void
34 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); 37 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
35 static void ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *ev); 38 static void
39 ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
40 ngx_http_upstream_t *u);
36 static void 41 static void
37 ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r, 42 ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
38 ngx_uint_t do_write); 43 ngx_uint_t do_write);
39 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data); 44 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
40 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, 45 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
41 ssize_t bytes); 46 ssize_t bytes);
42 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); 47 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
43 static void ngx_http_upstream_process_upstream(ngx_event_t *rev); 48 static void ngx_http_upstream_process_upstream(ngx_http_request_t *r,
49 ngx_http_upstream_t *u);
44 static void ngx_http_upstream_process_request(ngx_http_request_t *r); 50 static void ngx_http_upstream_process_request(ngx_http_request_t *r);
45 static void ngx_http_upstream_store(ngx_http_request_t *r, 51 static void ngx_http_upstream_store(ngx_http_request_t *r,
46 ngx_http_upstream_t *u); 52 ngx_http_upstream_t *u);
47 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); 53 static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r,
54 ngx_http_upstream_t *u);
48 static void ngx_http_upstream_next(ngx_http_request_t *r, 55 static void ngx_http_upstream_next(ngx_http_request_t *r,
49 ngx_http_upstream_t *u, ngx_uint_t ft_type); 56 ngx_http_upstream_t *u, ngx_uint_t ft_type);
50 static void ngx_http_upstream_cleanup(void *data); 57 static void ngx_http_upstream_cleanup(void *data);
51 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, 58 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
52 ngx_http_upstream_t *u, ngx_int_t rc); 59 ngx_http_upstream_t *u, ngx_int_t rc);
87 ngx_http_variable_value_t *v, uintptr_t data); 94 ngx_http_variable_value_t *v, uintptr_t data);
88 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r, 95 static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
89 ngx_http_variable_value_t *v, uintptr_t data); 96 ngx_http_variable_value_t *v, uintptr_t data);
90 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r, 97 static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
91 ngx_http_variable_value_t *v, uintptr_t data); 98 ngx_http_variable_value_t *v, uintptr_t data);
99 static ngx_int_t ngx_http_upstream_response_length_variable(
100 ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
92 101
93 static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); 102 static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
94 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, 103 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
95 void *conf); 104 void *conf);
96 105
287 296
288 { ngx_string("upstream_response_time"), NULL, 297 { ngx_string("upstream_response_time"), NULL,
289 ngx_http_upstream_response_time_variable, 0, 298 ngx_http_upstream_response_time_variable, 0,
290 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 }, 299 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 },
291 300
301 { ngx_string("upstream_response_length"), NULL,
302 ngx_http_upstream_response_length_variable, 0,
303 NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE, 0 },
304
292 { ngx_null_string, NULL, NULL, 0, 0, 0 } 305 { ngx_null_string, NULL, NULL, 0, 0, 0 }
293 }; 306 };
294 307
295 308
296 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = { 309 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
536 549
537 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, 550 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
538 "http upstream request: \"%V?%V\"", &r->uri, &r->args); 551 "http upstream request: \"%V?%V\"", &r->uri, &r->args);
539 552
540 if (ev->write) { 553 if (ev->write) {
541 u->write_event_handler(ev); 554 u->write_event_handler(r, u);
542 555
543 } else { 556 } else {
544 u->read_event_handler(ev); 557 u->read_event_handler(r, u);
545 } 558 }
546 559
547 ngx_http_run_posted_requests(c); 560 ngx_http_run_posted_requests(c);
548 } 561 }
549 562
994 } 1007 }
995 1008
996 if (rc == NGX_AGAIN) { 1009 if (rc == NGX_AGAIN) {
997 ngx_add_timer(c->write, u->conf->send_timeout); 1010 ngx_add_timer(c->write, u->conf->send_timeout);
998 1011
999 if (ngx_handle_write_event(c->write, u->conf->send_lowat) == NGX_ERROR) 1012 if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) {
1000 {
1001 ngx_http_upstream_finalize_request(r, u, 1013 ngx_http_upstream_finalize_request(r, u,
1002 NGX_HTTP_INTERNAL_SERVER_ERROR); 1014 NGX_HTTP_INTERNAL_SERVER_ERROR);
1003 return; 1015 return;
1004 } 1016 }
1005 1017
1032 * although we can post aio operation just in the end 1044 * although we can post aio operation just in the end
1033 * of ngx_http_upstream_connect() CHECK IT !!! 1045 * of ngx_http_upstream_connect() CHECK IT !!!
1034 * it's better to do here because we postpone header buffer allocation 1046 * it's better to do here because we postpone header buffer allocation
1035 */ 1047 */
1036 1048
1037 ngx_http_upstream_process_header(c->read); 1049 ngx_http_upstream_process_header(r, u);
1038 return; 1050 return;
1039 } 1051 }
1040 #endif 1052 #endif
1041 1053
1042 u->write_event_handler = ngx_http_upstream_dummy_handler; 1054 u->write_event_handler = ngx_http_upstream_dummy_handler;
1043 1055
1044 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { 1056 if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
1045 ngx_http_upstream_finalize_request(r, u, 1057 ngx_http_upstream_finalize_request(r, u,
1046 NGX_HTTP_INTERNAL_SERVER_ERROR); 1058 NGX_HTTP_INTERNAL_SERVER_ERROR);
1047 return; 1059 return;
1048 } 1060 }
1049 } 1061 }
1050 1062
1051 1063
1052 static void 1064 static void
1053 ngx_http_upstream_send_request_handler(ngx_event_t *wev) 1065 ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
1054 { 1066 ngx_http_upstream_t *u)
1055 ngx_connection_t *c; 1067 {
1056 ngx_http_request_t *r; 1068 ngx_connection_t *c;
1057 ngx_http_upstream_t *u; 1069
1058 1070 c = u->peer.connection;
1059 c = wev->data; 1071
1060 r = c->data; 1072 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1061 u = r->upstream;
1062
1063 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
1064 "http upstream send request handler"); 1073 "http upstream send request handler");
1065 1074
1066 if (wev->timedout) { 1075 if (c->write->timedout) {
1067 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); 1076 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
1068 return; 1077 return;
1069 } 1078 }
1070 1079
1071 #if (NGX_HTTP_SSL) 1080 #if (NGX_HTTP_SSL)
1078 #endif 1087 #endif
1079 1088
1080 if (u->header_sent) { 1089 if (u->header_sent) {
1081 u->write_event_handler = ngx_http_upstream_dummy_handler; 1090 u->write_event_handler = ngx_http_upstream_dummy_handler;
1082 1091
1083 (void) ngx_handle_write_event(wev, 0); 1092 (void) ngx_handle_write_event(c->write, 0);
1084 1093
1085 return; 1094 return;
1086 } 1095 }
1087 1096
1088 ngx_http_upstream_send_request(r, u); 1097 ngx_http_upstream_send_request(r, u);
1089 } 1098 }
1090 1099
1091 1100
1092 static void 1101 static void
1093 ngx_http_upstream_process_header(ngx_event_t *rev) 1102 ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
1094 { 1103 {
1095 ssize_t n; 1104 ssize_t n;
1096 ngx_int_t rc; 1105 ngx_int_t rc;
1097 ngx_str_t *uri, args; 1106 ngx_str_t *uri, args;
1098 ngx_uint_t i, flags; 1107 ngx_uint_t i, flags;
1099 ngx_list_part_t *part; 1108 ngx_list_part_t *part;
1100 ngx_table_elt_t *h; 1109 ngx_table_elt_t *h;
1101 ngx_connection_t *c; 1110 ngx_connection_t *c;
1102 ngx_http_request_t *r;
1103 ngx_http_upstream_t *u;
1104 ngx_http_upstream_header_t *hh; 1111 ngx_http_upstream_header_t *hh;
1105 ngx_http_upstream_main_conf_t *umcf; 1112 ngx_http_upstream_main_conf_t *umcf;
1106 1113
1107 c = rev->data; 1114 c = u->peer.connection;
1108 r = c->data; 1115
1109 u = r->upstream; 1116 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1110
1111 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
1112 "http upstream process header"); 1117 "http upstream process header");
1113 1118
1114 c->log->action = "reading response header from upstream"; 1119 c->log->action = "reading response header from upstream";
1115 1120
1116 if (rev->timedout) { 1121 if (c->read->timedout) {
1117 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); 1122 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
1118 return; 1123 return;
1119 } 1124 }
1120 1125
1121 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { 1126 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
1162 if (n == NGX_AGAIN) { 1167 if (n == NGX_AGAIN) {
1163 #if 0 1168 #if 0
1164 ngx_add_timer(rev, u->read_timeout); 1169 ngx_add_timer(rev, u->read_timeout);
1165 #endif 1170 #endif
1166 1171
1167 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { 1172 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1168 ngx_http_upstream_finalize_request(r, u, 1173 ngx_http_upstream_finalize_request(r, u,
1169 NGX_HTTP_INTERNAL_SERVER_ERROR); 1174 NGX_HTTP_INTERNAL_SERVER_ERROR);
1170 return; 1175 return;
1171 } 1176 }
1172 1177
1173 return; 1178 return;
1174 } 1179 }
1175 1180
1176 if (n == 0) { 1181 if (n == 0) {
1177 ngx_log_error(NGX_LOG_ERR, rev->log, 0, 1182 ngx_log_error(NGX_LOG_ERR, c->log, 0,
1178 "upstream prematurely closed connection"); 1183 "upstream prematurely closed connection");
1179 } 1184 }
1180 1185
1181 if (n == NGX_ERROR || n == 0) { 1186 if (n == NGX_ERROR || n == 0) {
1182 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); 1187 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1194 rc = u->process_header(r); 1199 rc = u->process_header(r);
1195 1200
1196 if (rc == NGX_AGAIN) { 1201 if (rc == NGX_AGAIN) {
1197 1202
1198 if (u->buffer.pos == u->buffer.end) { 1203 if (u->buffer.pos == u->buffer.end) {
1199 ngx_log_error(NGX_LOG_ERR, rev->log, 0, 1204 ngx_log_error(NGX_LOG_ERR, c->log, 0,
1200 "upstream sent too big header"); 1205 "upstream sent too big header");
1201 1206
1202 ngx_http_upstream_next(r, u, 1207 ngx_http_upstream_next(r, u,
1203 NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); 1208 NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1204 return; 1209 return;
1378 n = u->buffer.last - u->buffer.pos; 1383 n = u->buffer.last - u->buffer.pos;
1379 1384
1380 if (n) { 1385 if (n) {
1381 u->buffer.last -= n; 1386 u->buffer.last -= n;
1382 1387
1388 u->state->response_length += n;
1389
1383 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { 1390 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1384 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 1391 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1385 return; 1392 return;
1386 } 1393 }
1387 1394
1391 } 1398 }
1392 } 1399 }
1393 1400
1394 u->read_event_handler = ngx_http_upstream_process_body_in_memory; 1401 u->read_event_handler = ngx_http_upstream_process_body_in_memory;
1395 1402
1396 ngx_http_upstream_process_body_in_memory(rev); 1403 ngx_http_upstream_process_body_in_memory(r, u);
1397 } 1404 }
1398 1405
1399 1406
1400 static ngx_int_t 1407 static ngx_int_t
1401 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u) 1408 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1535 return NGX_OK; 1542 return NGX_OK;
1536 } 1543 }
1537 1544
1538 1545
1539 static void 1546 static void
1540 ngx_http_upstream_process_body_in_memory(ngx_event_t *rev) 1547 ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
1541 { 1548 ngx_http_upstream_t *u)
1542 size_t size; 1549 {
1543 ssize_t n; 1550 size_t size;
1544 ngx_buf_t *b; 1551 ssize_t n;
1545 ngx_connection_t *c; 1552 ngx_buf_t *b;
1546 ngx_http_request_t *r; 1553 ngx_event_t *rev;
1547 ngx_http_upstream_t *u; 1554 ngx_connection_t *c;
1548 1555
1549 c = rev->data; 1556 c = u->peer.connection;
1550 r = c->data; 1557 rev = c->read;
1551 u = r->upstream;
1552 1558
1553 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 1559 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1554 "http upstream process body on memory"); 1560 "http upstream process body on memory");
1555 1561
1556 if (rev->timedout) { 1562 if (rev->timedout) {
1581 if (n == 0 || n == NGX_ERROR) { 1587 if (n == 0 || n == NGX_ERROR) {
1582 ngx_http_upstream_finalize_request(r, u, n); 1588 ngx_http_upstream_finalize_request(r, u, n);
1583 return; 1589 return;
1584 } 1590 }
1585 1591
1592 u->state->response_length += n;
1593
1586 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { 1594 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1587 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 1595 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1588 return; 1596 return;
1589 } 1597 }
1590 1598
1591 if (!rev->ready) { 1599 if (!rev->ready) {
1592 break; 1600 break;
1593 } 1601 }
1594 } 1602 }
1595 1603
1596 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { 1604 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
1597 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); 1605 ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1598 return; 1606 return;
1599 } 1607 }
1600 1608
1601 if (rev->active) { 1609 if (rev->active) {
1609 1617
1610 static void 1618 static void
1611 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) 1619 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
1612 { 1620 {
1613 int tcp_nodelay; 1621 int tcp_nodelay;
1614 ssize_t size; 1622 ssize_t n;
1615 ngx_int_t rc; 1623 ngx_int_t rc;
1616 ngx_event_pipe_t *p; 1624 ngx_event_pipe_t *p;
1617 ngx_connection_t *c; 1625 ngx_connection_t *c;
1618 ngx_pool_cleanup_t *cl; 1626 ngx_pool_cleanup_t *cl;
1619 ngx_pool_cleanup_file_t *clf; 1627 ngx_pool_cleanup_file_t *clf;
1681 } 1689 }
1682 1690
1683 c->tcp_nodelay = NGX_TCP_NODELAY_SET; 1691 c->tcp_nodelay = NGX_TCP_NODELAY_SET;
1684 } 1692 }
1685 1693
1686 size = u->buffer.last - u->buffer.pos; 1694 n = u->buffer.last - u->buffer.pos;
1687 1695
1688 if (size) { 1696 if (n) {
1689 u->buffer.last = u->buffer.pos; 1697 u->buffer.last = u->buffer.pos;
1690 1698
1691 if (u->input_filter(u->input_filter_ctx, size) == NGX_ERROR) { 1699 u->state->response_length += n;
1700
1701 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1692 ngx_http_upstream_finalize_request(r, u, 0); 1702 ngx_http_upstream_finalize_request(r, u, 0);
1693 return; 1703 return;
1694 } 1704 }
1695 1705
1696 ngx_http_upstream_process_non_buffered_downstream(r); 1706 ngx_http_upstream_process_non_buffered_downstream(r);
1703 ngx_http_upstream_finalize_request(r, u, 0); 1713 ngx_http_upstream_finalize_request(r, u, 0);
1704 return; 1714 return;
1705 } 1715 }
1706 1716
1707 if (u->peer.connection->read->ready) { 1717 if (u->peer.connection->read->ready) {
1708 ngx_http_upstream_process_non_buffered_upstream( 1718 ngx_http_upstream_process_non_buffered_upstream(r, u);
1709 u->peer.connection->read);
1710 } 1719 }
1711 } 1720 }
1712 1721
1713 return; 1722 return;
1714 } 1723 }
1837 p->send_lowat = clcf->send_lowat; 1846 p->send_lowat = clcf->send_lowat;
1838 1847
1839 u->read_event_handler = ngx_http_upstream_process_upstream; 1848 u->read_event_handler = ngx_http_upstream_process_upstream;
1840 r->write_event_handler = ngx_http_upstream_process_downstream; 1849 r->write_event_handler = ngx_http_upstream_process_downstream;
1841 1850
1842 ngx_http_upstream_process_upstream(u->peer.connection->read); 1851 ngx_http_upstream_process_upstream(r, u);
1843 } 1852 }
1844 1853
1845 1854
1846 static void 1855 static void
1847 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) 1856 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
1869 ngx_http_upstream_process_non_buffered_request(r, 1); 1878 ngx_http_upstream_process_non_buffered_request(r, 1);
1870 } 1879 }
1871 1880
1872 1881
1873 static void 1882 static void
1874 ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *rev) 1883 ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
1875 { 1884 ngx_http_upstream_t *u)
1876 ngx_connection_t *c; 1885 {
1877 ngx_http_request_t *r; 1886 ngx_connection_t *c;
1878 ngx_http_upstream_t *u; 1887
1879 1888 c = u->peer.connection;
1880 c = rev->data;
1881 r = c->data;
1882 u = r->upstream;
1883 1889
1884 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 1890 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1885 "http upstream process non buffered upstream"); 1891 "http upstream process non buffered upstream");
1886 1892
1887 c->log->action = "reading upstream"; 1893 c->log->action = "reading upstream";
1888 1894
1889 if (rev->timedout) { 1895 if (c->read->timedout) {
1890 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); 1896 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
1891 ngx_http_upstream_finalize_request(r, u, 0); 1897 ngx_http_upstream_finalize_request(r, u, 0);
1892 return; 1898 return;
1893 } 1899 }
1894 1900
1964 if (n == NGX_AGAIN) { 1970 if (n == NGX_AGAIN) {
1965 break; 1971 break;
1966 } 1972 }
1967 1973
1968 if (n > 0) { 1974 if (n > 0) {
1975 u->state->response_length += n;
1976
1969 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { 1977 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1970 ngx_http_upstream_finalize_request(r, u, 0); 1978 ngx_http_upstream_finalize_request(r, u, 0);
1971 return; 1979 return;
1972 } 1980 }
1973 } 1981 }
2140 ngx_http_upstream_process_request(r); 2148 ngx_http_upstream_process_request(r);
2141 } 2149 }
2142 2150
2143 2151
2144 static void 2152 static void
2145 ngx_http_upstream_process_upstream(ngx_event_t *rev) 2153 ngx_http_upstream_process_upstream(ngx_http_request_t *r,
2146 { 2154 ngx_http_upstream_t *u)
2147 ngx_connection_t *c; 2155 {
2148 ngx_event_pipe_t *p; 2156 ngx_connection_t *c;
2149 ngx_http_request_t *r; 2157
2150 ngx_http_upstream_t *u; 2158 c = u->peer.connection;
2151
2152 c = rev->data;
2153 r = c->data;
2154 u = r->upstream;
2155 p = u->pipe;
2156 2159
2157 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 2160 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2158 "http upstream process upstream"); 2161 "http upstream process upstream");
2159 2162
2160 c->log->action = "reading upstream"; 2163 c->log->action = "reading upstream";
2161 2164
2162 if (rev->timedout) { 2165 if (c->read->timedout) {
2163 p->upstream_error = 1; 2166 u->pipe->upstream_error = 1;
2164 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); 2167 ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2165 2168
2166 } else { 2169 } else {
2167 c = r->connection; 2170 c = r->connection;
2168 2171
2169 if (ngx_event_pipe(p, 0) == NGX_ABORT) { 2172 if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
2170 2173
2171 if (c->destroyed) { 2174 if (c->destroyed) {
2172 return; 2175 return;
2173 } 2176 }
2174 2177
2297 2300
2298 u->pipe->temp_file = tf; 2301 u->pipe->temp_file = tf;
2299 } 2302 }
2300 2303
2301 ext.access = u->conf->store_access; 2304 ext.access = u->conf->store_access;
2305 ext.path_access = u->conf->store_access;
2302 ext.time = -1; 2306 ext.time = -1;
2303 ext.create_path = 1; 2307 ext.create_path = 1;
2304 ext.delete_file = 1; 2308 ext.delete_file = 1;
2309 ext.log_rename_error = 1;
2305 ext.log = r->connection->log; 2310 ext.log = r->connection->log;
2306 2311
2307 if (u->headers_in.last_modified) { 2312 if (u->headers_in.last_modified) {
2308 2313
2309 lm = ngx_http_parse_time(u->headers_in.last_modified->value.data, 2314 lm = ngx_http_parse_time(u->headers_in.last_modified->value.data,
2335 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext); 2340 (void) ngx_ext_rename_file(&tf->file.name, &path, &ext);
2336 } 2341 }
2337 2342
2338 2343
2339 static void 2344 static void
2340 ngx_http_upstream_dummy_handler(ngx_event_t *wev) 2345 ngx_http_upstream_dummy_handler(ngx_http_request_t *r, ngx_http_upstream_t *u)
2341 { 2346 {
2342 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, 2347 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2343 "http upstream dummy handler"); 2348 "http upstream dummy handler");
2344 } 2349 }
2345 2350
2346 2351
2347 static void 2352 static void
2487 2492
2488 if (u->state && u->state->response_sec) { 2493 if (u->state && u->state->response_sec) {
2489 tp = ngx_timeofday(); 2494 tp = ngx_timeofday();
2490 u->state->response_sec = tp->sec - u->state->response_sec; 2495 u->state->response_sec = tp->sec - u->state->response_sec;
2491 u->state->response_msec = tp->msec - u->state->response_msec; 2496 u->state->response_msec = tp->msec - u->state->response_msec;
2497
2498 if (u->pipe) {
2499 u->state->response_length = u->pipe->read_length;
2500 }
2492 } 2501 }
2493 2502
2494 u->finalize_request(r, rc); 2503 u->finalize_request(r, rc);
2495 2504
2496 if (u->peer.free) { 2505 if (u->peer.free) {
3102 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); 3111 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
3103 3112
3104 } else { 3113 } else {
3105 *p++ = '-'; 3114 *p++ = '-';
3106 } 3115 }
3116
3117 if (++i == r->upstream_states->nelts) {
3118 break;
3119 }
3120
3121 if (state[i].peer) {
3122 *p++ = ',';
3123 *p++ = ' ';
3124
3125 } else {
3126 *p++ = ' ';
3127 *p++ = ':';
3128 *p++ = ' ';
3129
3130 if (++i == r->upstream_states->nelts) {
3131 break;
3132 }
3133
3134 continue;
3135 }
3136 }
3137
3138 v->len = p - v->data;
3139
3140 return NGX_OK;
3141 }
3142
3143
3144 static ngx_int_t
3145 ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
3146 ngx_http_variable_value_t *v, uintptr_t data)
3147 {
3148 u_char *p;
3149 size_t len;
3150 ngx_uint_t i;
3151 ngx_http_upstream_state_t *state;
3152
3153 v->valid = 1;
3154 v->no_cacheable = 0;
3155 v->not_found = 0;
3156
3157 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
3158 v->not_found = 1;
3159 return NGX_OK;
3160 }
3161
3162 len = r->upstream_states->nelts * (NGX_OFF_T_LEN + 2);
3163
3164 p = ngx_pnalloc(r->pool, len);
3165 if (p == NULL) {
3166 return NGX_ERROR;
3167 }
3168
3169 v->data = p;
3170
3171 i = 0;
3172 state = r->upstream_states->elts;
3173
3174 for ( ;; ) {
3175 p = ngx_sprintf(p, "%O", state[i].response_length);
3107 3176
3108 if (++i == r->upstream_states->nelts) { 3177 if (++i == r->upstream_states->nelts) {
3109 break; 3178 break;
3110 } 3179 }
3111 3180