Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_upstream.c @ 439: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
438:3b8e9d1bc9bb | 439: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 |