Mercurial > hg > nginx-quic
comparison src/http/ngx_http_upstream.c @ 581:326634fb9d47 release-0.3.12
nginx-0.3.12-RELEASE import
*) Security: if nginx was built with the ngx_http_realip_module and the
"satisfy_any on" directive was used, then access and authorization
directives did not work. The ngx_http_realip_module was not built
and is not built by default.
*) Change: the "$time_gmt" variable name was changed to "$time_local".
*) Change: the "proxy_header_buffer_size" and
"fastcgi_header_buffer_size" directives was renamed to the
"proxy_buffer_size" and "fastcgi_buffer_size" directives.
*) Feature: the ngx_http_memcached_module.
*) Feature: the "proxy_buffering" directive.
*) Bugfix: the changes in accept mutex handling when the "rtsig" method
was used; the bug had appeared in 0.3.0.
*) Bugfix: if the client sent the "Transfer-Encoding: chunked" header
line, then nginx returns the 411 error.
*) Bugfix: if the "auth_basic" directive was inherited from the http
level, then the realm in the "WWW-Authenticate" header line was
without the "Basic realm" text.
*) Bugfix: if the "combined" format was explicitly specified in the
"access_log" directive, then the empty lines was written to the log;
the bug had appeared in 0.3.8.
*) Bugfix: nginx did not run on the sparc platform under any OS except
Solaris.
*) Bugfix: now it is not necessary to place space between the quoted
string and closing bracket in the "if" directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 26 Nov 2005 10:11:11 +0000 |
parents | 4d9ea73a627a |
children | 4e296b7d25bf |
comparison
equal
deleted
inserted
replaced
580:8393757dc220 | 581:326634fb9d47 |
---|---|
4 */ | 4 */ |
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event_connect.h> | |
10 #include <ngx_http.h> | 9 #include <ngx_http.h> |
11 | 10 |
12 | 11 |
13 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); | 12 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
14 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); | 13 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); |
22 ngx_http_upstream_t *u); | 21 ngx_http_upstream_t *u); |
23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); | 22 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); |
24 static void ngx_http_upstream_process_header(ngx_event_t *rev); | 23 static void ngx_http_upstream_process_header(ngx_event_t *rev); |
25 static void ngx_http_upstream_send_response(ngx_http_request_t *r, | 24 static void ngx_http_upstream_send_response(ngx_http_request_t *r, |
26 ngx_http_upstream_t *u); | 25 ngx_http_upstream_t *u); |
26 static void | |
27 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); | |
28 static void ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev); | |
29 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data); | |
30 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, | |
31 ssize_t bytes); | |
27 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); | 32 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r); |
28 static void ngx_http_upstream_process_body(ngx_event_t *ev); | 33 static void ngx_http_upstream_process_body(ngx_event_t *ev); |
29 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); | 34 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev); |
30 static void ngx_http_upstream_next(ngx_http_request_t *r, | 35 static void ngx_http_upstream_next(ngx_http_request_t *r, |
31 ngx_http_upstream_t *u, ngx_uint_t ft_type); | 36 ngx_http_upstream_t *u, ngx_uint_t ft_type); |
697 | 702 |
698 u->output.buf = NULL; | 703 u->output.buf = NULL; |
699 u->output.in = NULL; | 704 u->output.in = NULL; |
700 u->output.busy = NULL; | 705 u->output.busy = NULL; |
701 | 706 |
702 /* reinit u->header_in buffer */ | 707 /* reinit u->buffer */ |
703 | 708 |
704 #if 0 | 709 #if 0 |
705 if (u->cache) { | 710 if (u->cache) { |
706 u->header_in.pos = u->header_in.start + u->cache->ctx.header_size; | 711 u->buffer.pos = u->buffer.start + u->cache->ctx.header_size; |
707 u->header_in.last = u->header_in.pos; | 712 u->buffer.last = u->buffer.pos; |
708 | 713 |
709 } else { | 714 } else { |
710 u->header_in.pos = u->header_in.start; | 715 u->buffer.pos = u->buffer.start; |
711 u->header_in.last = u->header_in.start; | 716 u->buffer.last = u->buffer.start; |
712 } | 717 } |
713 #else | 718 #else |
714 | 719 |
715 u->header_in.pos = u->header_in.start; | 720 u->buffer.pos = u->buffer.start; |
716 u->header_in.last = u->header_in.start; | 721 u->buffer.last = u->buffer.start; |
717 | 722 |
718 #endif | 723 #endif |
719 | 724 |
720 /* add one more state */ | 725 /* add one more state */ |
721 | 726 |
879 if (rev->timedout) { | 884 if (rev->timedout) { |
880 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); | 885 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); |
881 return; | 886 return; |
882 } | 887 } |
883 | 888 |
884 if (u->header_in.start == NULL) { | 889 if (u->buffer.start == NULL) { |
885 u->header_in.start = ngx_palloc(r->pool, u->conf->header_buffer_size); | 890 u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size); |
886 if (u->header_in.start == NULL) { | 891 if (u->buffer.start == NULL) { |
887 ngx_http_upstream_finalize_request(r, u, | 892 ngx_http_upstream_finalize_request(r, u, |
888 NGX_HTTP_INTERNAL_SERVER_ERROR); | 893 NGX_HTTP_INTERNAL_SERVER_ERROR); |
889 return; | 894 return; |
890 } | 895 } |
891 | 896 |
892 u->header_in.pos = u->header_in.start; | 897 u->buffer.pos = u->buffer.start; |
893 u->header_in.last = u->header_in.start; | 898 u->buffer.last = u->buffer.start; |
894 u->header_in.end = u->header_in.start + u->conf->header_buffer_size; | 899 u->buffer.end = u->buffer.start + u->conf->buffer_size; |
895 u->header_in.temporary = 1; | 900 u->buffer.temporary = 1; |
896 | 901 |
897 u->header_in.tag = u->output.tag; | 902 u->buffer.tag = u->output.tag; |
898 | 903 |
899 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, | 904 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, |
900 sizeof(ngx_table_elt_t)) == NGX_ERROR) | 905 sizeof(ngx_table_elt_t)) |
906 != NGX_OK) | |
901 { | 907 { |
902 ngx_http_upstream_finalize_request(r, u, | 908 ngx_http_upstream_finalize_request(r, u, |
903 NGX_HTTP_INTERNAL_SERVER_ERROR); | 909 NGX_HTTP_INTERNAL_SERVER_ERROR); |
904 return; | 910 return; |
905 } | 911 } |
906 | 912 |
907 #if 0 | 913 #if 0 |
908 if (u->cache) { | 914 if (u->cache) { |
909 u->header_in.pos += u->cache->ctx.header_size; | 915 u->buffer.pos += u->cache->ctx.header_size; |
910 u->header_in.last = u->header_in.pos; | 916 u->buffer.last = u->buffer.pos; |
911 } | 917 } |
912 #endif | 918 #endif |
913 } | 919 } |
914 | 920 |
915 n = u->peer.connection->recv(u->peer.connection, u->header_in.last, | 921 n = u->peer.connection->recv(u->peer.connection, u->buffer.last, |
916 u->header_in.end - u->header_in.last); | 922 u->buffer.end - u->buffer.last); |
917 | 923 |
918 if (n == NGX_AGAIN) { | 924 if (n == NGX_AGAIN) { |
919 #if 0 | 925 #if 0 |
920 ngx_add_timer(rev, u->read_timeout); | 926 ngx_add_timer(rev, u->read_timeout); |
921 #endif | 927 #endif |
937 if (n == NGX_ERROR || n == 0) { | 943 if (n == NGX_ERROR || n == 0) { |
938 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); | 944 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); |
939 return; | 945 return; |
940 } | 946 } |
941 | 947 |
942 u->header_in.last += n; | 948 u->buffer.last += n; |
943 | 949 |
944 #if 0 | 950 #if 0 |
945 u->valid_header_in = 0; | 951 u->valid_header_in = 0; |
946 | 952 |
947 u->peer.cached = 0; | 953 u->peer.cached = 0; |
952 if (rc == NGX_AGAIN) { | 958 if (rc == NGX_AGAIN) { |
953 #if 0 | 959 #if 0 |
954 ngx_add_timer(rev, u->read_timeout); | 960 ngx_add_timer(rev, u->read_timeout); |
955 #endif | 961 #endif |
956 | 962 |
957 if (u->header_in.pos == u->header_in.end) { | 963 if (u->buffer.pos == u->buffer.end) { |
958 ngx_log_error(NGX_LOG_ERR, rev->log, 0, | 964 ngx_log_error(NGX_LOG_ERR, rev->log, 0, |
959 "upstream sent too big header"); | 965 "upstream sent too big header"); |
960 | 966 |
961 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); | 967 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); |
962 return; | 968 return; |
1018 | 1024 |
1019 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST | 1025 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST |
1020 && u->conf->redirect_errors | 1026 && u->conf->redirect_errors |
1021 && r->err_ctx == NULL) | 1027 && r->err_ctx == NULL) |
1022 { | 1028 { |
1029 if (u->headers_in.status_n == NGX_HTTP_NOT_FOUND | |
1030 && u->conf->redirect_404) | |
1031 { | |
1032 ngx_http_upstream_finalize_request(r, u, 404); | |
1033 return; | |
1034 } | |
1035 | |
1023 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 1036 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
1024 | 1037 |
1025 if (clcf->error_pages) { | 1038 if (clcf->error_pages) { |
1026 | 1039 |
1027 err_page = clcf->error_pages->elts; | 1040 err_page = clcf->error_pages->elts; |
1110 | 1123 |
1111 | 1124 |
1112 static void | 1125 static void |
1113 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) | 1126 ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) |
1114 { | 1127 { |
1128 ssize_t size; | |
1115 ngx_int_t rc; | 1129 ngx_int_t rc; |
1116 ngx_uint_t i, key; | 1130 ngx_uint_t i, key; |
1117 ngx_list_part_t *part; | 1131 ngx_list_part_t *part; |
1118 ngx_table_elt_t *h; | 1132 ngx_table_elt_t *h; |
1119 ngx_event_pipe_t *p; | 1133 ngx_event_pipe_t *p; |
1163 } | 1177 } |
1164 | 1178 |
1165 r->headers_out.status = u->headers_in.status_n; | 1179 r->headers_out.status = u->headers_in.status_n; |
1166 r->headers_out.status_line = u->headers_in.status_line; | 1180 r->headers_out.status_line = u->headers_in.status_line; |
1167 | 1181 |
1182 if (r->headers_out.content_length_n != -1) { | |
1183 u->length = (size_t) r->headers_out.content_length_n; | |
1184 | |
1185 } else { | |
1186 u->length = NGX_MAX_SIZE_T_VALUE; | |
1187 } | |
1188 | |
1168 rc = ngx_http_send_header(r); | 1189 rc = ngx_http_send_header(r); |
1169 | 1190 |
1170 if (rc == NGX_ERROR || rc > NGX_OK) { | 1191 if (rc == NGX_ERROR || rc > NGX_OK) { |
1171 ngx_http_upstream_finalize_request(r, u, rc); | 1192 ngx_http_upstream_finalize_request(r, u, rc); |
1172 return; | 1193 return; |
1186 } | 1207 } |
1187 } | 1208 } |
1188 } | 1209 } |
1189 } | 1210 } |
1190 | 1211 |
1212 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1213 | |
1214 if (u->pipe == NULL) { | |
1215 | |
1216 if (u->input_filter == NULL) { | |
1217 u->input_filter_init = ngx_http_upstream_non_buffered_filter_init; | |
1218 u->input_filter = ngx_http_upstream_non_buffered_filter; | |
1219 u->input_filter_ctx = r; | |
1220 } | |
1221 | |
1222 u->peer.connection->read->handler = | |
1223 ngx_http_upstream_process_non_buffered_body; | |
1224 r->write_event_handler = | |
1225 ngx_http_upstream_process_non_buffered_downstream; | |
1226 | |
1227 r->limit_rate = 0; | |
1228 | |
1229 if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { | |
1230 ngx_http_upstream_finalize_request(r, u, 0); | |
1231 return; | |
1232 } | |
1233 | |
1234 size = u->buffer.last - u->buffer.pos; | |
1235 | |
1236 if (size) { | |
1237 u->buffer.last = u->buffer.pos; | |
1238 | |
1239 if (u->input_filter(u->input_filter_ctx, size) == NGX_ERROR) { | |
1240 ngx_http_upstream_finalize_request(r, u, 0); | |
1241 return; | |
1242 } | |
1243 | |
1244 ngx_http_upstream_process_non_buffered_body(r->connection->write); | |
1245 | |
1246 } else { | |
1247 u->buffer.pos = u->buffer.start; | |
1248 u->buffer.last = u->buffer.start; | |
1249 | |
1250 if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { | |
1251 ngx_http_upstream_finalize_request(r, u, 0); | |
1252 return; | |
1253 } | |
1254 } | |
1255 | |
1256 return; | |
1257 } | |
1258 | |
1191 /* TODO: preallocate event_pipe bufs, look "Content-Length" */ | 1259 /* TODO: preallocate event_pipe bufs, look "Content-Length" */ |
1192 | 1260 |
1193 #if 0 | 1261 #if 0 |
1194 | 1262 |
1195 if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) { | 1263 if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) { |
1199 u->cache->ctx.file.name.data); | 1267 u->cache->ctx.file.name.data); |
1200 } | 1268 } |
1201 } | 1269 } |
1202 | 1270 |
1203 if (u->cachable) { | 1271 if (u->cachable) { |
1204 header = (ngx_http_cache_header_t *) u->header_in->start; | 1272 header = (ngx_http_cache_header_t *) u->buffer->start; |
1205 | 1273 |
1206 header->expires = u->cache->ctx.expires; | 1274 header->expires = u->cache->ctx.expires; |
1207 header->last_modified = u->cache->ctx.last_modified; | 1275 header->last_modified = u->cache->ctx.last_modified; |
1208 header->date = u->cache->ctx.date; | 1276 header->date = u->cache->ctx.date; |
1209 header->length = r->headers_out.content_length_n; | 1277 header->length = r->headers_out.content_length_n; |
1214 header->key[header->key_len] = LF; | 1282 header->key[header->key_len] = LF; |
1215 } | 1283 } |
1216 | 1284 |
1217 #endif | 1285 #endif |
1218 | 1286 |
1219 p = &u->pipe; | 1287 p = u->pipe; |
1220 | 1288 |
1221 p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter; | 1289 p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter; |
1222 p->output_ctx = r; | 1290 p->output_ctx = r; |
1223 p->tag = u->output.tag; | 1291 p->tag = u->output.tag; |
1224 p->bufs = u->conf->bufs; | 1292 p->bufs = u->conf->bufs; |
1254 p->preread_bufs = ngx_alloc_chain_link(r->pool); | 1322 p->preread_bufs = ngx_alloc_chain_link(r->pool); |
1255 if (p->preread_bufs == NULL) { | 1323 if (p->preread_bufs == NULL) { |
1256 ngx_http_upstream_finalize_request(r, u, 0); | 1324 ngx_http_upstream_finalize_request(r, u, 0); |
1257 return; | 1325 return; |
1258 } | 1326 } |
1259 p->preread_bufs->buf = &u->header_in; | 1327 p->preread_bufs->buf = &u->buffer; |
1260 p->preread_bufs->next = NULL; | 1328 p->preread_bufs->next = NULL; |
1261 u->header_in.recycled = 1; | 1329 u->buffer.recycled = 1; |
1262 | 1330 |
1263 p->preread_size = u->header_in.last - u->header_in.pos; | 1331 p->preread_size = u->buffer.last - u->buffer.pos; |
1264 | 1332 |
1265 if (u->cachable) { | 1333 if (u->cachable) { |
1266 p->buf_to_file = ngx_calloc_buf(r->pool); | 1334 p->buf_to_file = ngx_calloc_buf(r->pool); |
1267 if (p->buf_to_file == NULL) { | 1335 if (p->buf_to_file == NULL) { |
1268 ngx_http_upstream_finalize_request(r, u, 0); | 1336 ngx_http_upstream_finalize_request(r, u, 0); |
1269 return; | 1337 return; |
1270 } | 1338 } |
1271 p->buf_to_file->pos = u->header_in.start; | 1339 p->buf_to_file->pos = u->buffer.start; |
1272 p->buf_to_file->last = u->header_in.pos; | 1340 p->buf_to_file->last = u->buffer.pos; |
1273 p->buf_to_file->temporary = 1; | 1341 p->buf_to_file->temporary = 1; |
1274 } | 1342 } |
1275 | 1343 |
1276 if (ngx_event_flags & NGX_USE_AIO_EVENT) { | 1344 if (ngx_event_flags & NGX_USE_AIO_EVENT) { |
1277 /* the posted aio operation may currupt a shadow buffer */ | 1345 /* the posted aio operation may currupt a shadow buffer */ |
1280 | 1348 |
1281 /* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */ | 1349 /* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */ |
1282 p->free_bufs = 1; | 1350 p->free_bufs = 1; |
1283 | 1351 |
1284 /* | 1352 /* |
1285 * event_pipe would do u->header_in.last += p->preread_size | 1353 * event_pipe would do u->buffer.last += p->preread_size |
1286 * as though these bytes were read | 1354 * as though these bytes were read |
1287 */ | 1355 */ |
1288 u->header_in.last = u->header_in.pos; | 1356 u->buffer.last = u->buffer.pos; |
1289 | 1357 |
1290 if (u->conf->cyclic_temp_file) { | 1358 if (u->conf->cyclic_temp_file) { |
1291 | 1359 |
1292 /* | 1360 /* |
1293 * we need to disable the use of sendfile() if we use cyclic temp file | 1361 * we need to disable the use of sendfile() if we use cyclic temp file |
1300 | 1368 |
1301 } else { | 1369 } else { |
1302 p->cyclic_temp_file = 0; | 1370 p->cyclic_temp_file = 0; |
1303 } | 1371 } |
1304 | 1372 |
1305 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1306 | |
1307 p->read_timeout = u->conf->read_timeout; | 1373 p->read_timeout = u->conf->read_timeout; |
1308 p->send_timeout = clcf->send_timeout; | 1374 p->send_timeout = clcf->send_timeout; |
1309 p->send_lowat = clcf->send_lowat; | 1375 p->send_lowat = clcf->send_lowat; |
1310 | 1376 |
1311 u->peer.connection->read->handler = ngx_http_upstream_process_body; | 1377 u->peer.connection->read->handler = ngx_http_upstream_process_body; |
1312 r->write_event_handler = ngx_http_upstream_process_downstream; | 1378 r->write_event_handler = ngx_http_upstream_process_downstream; |
1313 | 1379 |
1314 ngx_http_upstream_process_body(u->peer.connection->read); | 1380 ngx_http_upstream_process_body(u->peer.connection->read); |
1381 } | |
1382 | |
1383 | |
1384 static void | |
1385 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) | |
1386 { | |
1387 ngx_http_upstream_process_non_buffered_body(r->connection->write); | |
1388 } | |
1389 | |
1390 | |
1391 static void | |
1392 ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) | |
1393 { | |
1394 size_t size; | |
1395 ssize_t n; | |
1396 ngx_buf_t *b; | |
1397 ngx_uint_t do_write; | |
1398 ngx_connection_t *c; | |
1399 ngx_http_request_t *r; | |
1400 ngx_http_upstream_t *u; | |
1401 ngx_http_core_loc_conf_t *clcf; | |
1402 | |
1403 c = ev->data; | |
1404 | |
1405 if (ev->write) { | |
1406 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1407 "http upstream process non buffered downstream"); | |
1408 c->log->action = "sending to client"; | |
1409 | |
1410 } else { | |
1411 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
1412 "http upstream process non buffered upstream"); | |
1413 c->log->action = "reading upstream"; | |
1414 } | |
1415 | |
1416 if (ev->timedout) { | |
1417 if (ev->write) { | |
1418 c->timedout = 1; | |
1419 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, | |
1420 "client timed out"); | |
1421 } else { | |
1422 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, | |
1423 "upstream timed out"); | |
1424 } | |
1425 } | |
1426 | |
1427 r = c->data; | |
1428 u = r->upstream; | |
1429 | |
1430 b = &u->buffer; | |
1431 | |
1432 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1433 | |
1434 do_write = ev->write; | |
1435 | |
1436 for ( ;; ) { | |
1437 | |
1438 if (do_write) { | |
1439 | |
1440 if (u->out_bufs || u->busy_bufs) { | |
1441 if (ngx_http_output_filter(r, u->out_bufs) == NGX_ERROR) { | |
1442 ngx_http_upstream_finalize_request(r, u, 0); | |
1443 return; | |
1444 } | |
1445 | |
1446 ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs, | |
1447 &u->out_bufs, u->output.tag); | |
1448 } | |
1449 | |
1450 if (u->busy_bufs == NULL) { | |
1451 | |
1452 if (u->length == 0 | |
1453 || u->peer.connection->read->eof | |
1454 || u->peer.connection->read->error) | |
1455 { | |
1456 ngx_http_upstream_finalize_request(r, u, 0); | |
1457 return; | |
1458 } | |
1459 | |
1460 b->pos = b->start; | |
1461 b->last = b->start; | |
1462 } | |
1463 } | |
1464 | |
1465 size = b->end - b->last; | |
1466 | |
1467 if (size > u->length) { | |
1468 size = u->length; | |
1469 } | |
1470 | |
1471 if (size && u->peer.connection->read->ready) { | |
1472 n = u->peer.connection->recv(u->peer.connection, b->last, size); | |
1473 | |
1474 if (n == NGX_AGAIN) { | |
1475 break; | |
1476 } | |
1477 | |
1478 if (n > 0) { | |
1479 if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) { | |
1480 ngx_http_upstream_finalize_request(r, u, 0); | |
1481 return; | |
1482 } | |
1483 } | |
1484 | |
1485 do_write = 1; | |
1486 | |
1487 continue; | |
1488 } | |
1489 | |
1490 break; | |
1491 } | |
1492 | |
1493 if (ngx_handle_write_event(r->connection->write, clcf->send_lowat) | |
1494 == NGX_ERROR) | |
1495 { | |
1496 ngx_http_upstream_finalize_request(r, u, 0); | |
1497 return; | |
1498 } | |
1499 | |
1500 if (r->connection->write->active) { | |
1501 ngx_add_timer(r->connection->write, clcf->send_timeout); | |
1502 | |
1503 } else if (r->connection->write->timer_set) { | |
1504 ngx_del_timer(r->connection->write); | |
1505 } | |
1506 | |
1507 if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) { | |
1508 ngx_http_upstream_finalize_request(r, u, 0); | |
1509 return; | |
1510 } | |
1511 | |
1512 if (u->peer.connection->read->active) { | |
1513 ngx_add_timer(u->peer.connection->read, u->conf->read_timeout); | |
1514 | |
1515 } else if (r->connection->read->timer_set) { | |
1516 ngx_del_timer(r->connection->read); | |
1517 } | |
1518 } | |
1519 | |
1520 | |
1521 static ngx_int_t | |
1522 ngx_http_upstream_non_buffered_filter_init(void *data) | |
1523 { | |
1524 return NGX_OK; | |
1525 } | |
1526 | |
1527 | |
1528 static ngx_int_t | |
1529 ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes) | |
1530 { | |
1531 ngx_http_request_t *r = data; | |
1532 | |
1533 ngx_buf_t *b; | |
1534 ngx_chain_t *cl, **ll; | |
1535 ngx_http_upstream_t *u; | |
1536 | |
1537 u = r->upstream; | |
1538 | |
1539 for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { | |
1540 ll = &cl->next; | |
1541 } | |
1542 | |
1543 cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs); | |
1544 if (cl == NULL) { | |
1545 return NGX_ERROR; | |
1546 } | |
1547 | |
1548 *ll = cl; | |
1549 | |
1550 cl->buf->flush = 1; | |
1551 cl->buf->memory = 1; | |
1552 | |
1553 b = &u->buffer; | |
1554 | |
1555 cl->buf->pos = b->last; | |
1556 b->last += bytes; | |
1557 cl->buf->last = b->last; | |
1558 | |
1559 if (u->length == NGX_MAX_SIZE_T_VALUE) { | |
1560 return NGX_OK; | |
1561 } | |
1562 | |
1563 u->length -= bytes; | |
1564 | |
1565 return NGX_OK; | |
1315 } | 1566 } |
1316 | 1567 |
1317 | 1568 |
1318 static void | 1569 static void |
1319 ngx_http_upstream_process_downstream(ngx_http_request_t *r) | 1570 ngx_http_upstream_process_downstream(ngx_http_request_t *r) |
1343 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | 1594 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
1344 "http upstream process upstream"); | 1595 "http upstream process upstream"); |
1345 c->log->action = "reading upstream"; | 1596 c->log->action = "reading upstream"; |
1346 } | 1597 } |
1347 | 1598 |
1348 p = &u->pipe; | 1599 p = u->pipe; |
1349 | 1600 |
1350 if (ev->timedout) { | 1601 if (ev->timedout) { |
1351 if (ev->write) { | 1602 if (ev->write) { |
1352 if (ev->delayed) { | 1603 if (ev->delayed) { |
1353 | 1604 |
1612 if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) | 1863 if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) |
1613 { | 1864 { |
1614 rc = 0; | 1865 rc = 0; |
1615 } | 1866 } |
1616 | 1867 |
1617 if (u->pipe.temp_file) { | 1868 if (u->pipe && u->pipe->temp_file) { |
1618 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1869 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1619 "http upstream temp fd: %d", | 1870 "http upstream temp fd: %d", |
1620 u->pipe.temp_file->file.fd); | 1871 u->pipe->temp_file->file.fd); |
1621 } | 1872 } |
1622 | 1873 |
1623 #if 0 | 1874 #if 0 |
1624 if (u->cache) { | 1875 if (u->cache) { |
1625 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1876 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1635 } | 1886 } |
1636 | 1887 |
1637 r->connection->log->action = "sending to client"; | 1888 r->connection->log->action = "sending to client"; |
1638 | 1889 |
1639 if (rc == 0 && r->main == r) { | 1890 if (rc == 0 && r->main == r) { |
1640 rc = ngx_http_send_last(r); | 1891 rc = ngx_http_send_special(r, NGX_HTTP_LAST); |
1641 } | 1892 } |
1642 | 1893 |
1643 ngx_http_finalize_request(r, rc); | 1894 ngx_http_finalize_request(r, rc); |
1644 } | 1895 } |
1645 | 1896 |