comparison src/http/ngx_http_upstream.c @ 130:82d695e3d662 NGINX_0_3_12

nginx 0.3.12 *) 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; bug 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; bug 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 <http://sysoev.ru>
date Sat, 26 Nov 2005 00:00:00 +0300
parents df17fbafec8f
children 91372f004adf
comparison
equal deleted inserted replaced
129:a27c77ef3ad8 130:82d695e3d662
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