comparison src/http/ngx_http_upstream.c @ 132:91372f004adf NGINX_0_3_13

nginx 0.3.13 *) Feature: the IMAP/POP3 proxy supports STARTTLS and STLS. *) Bugfix: the IMAP/POP3 proxy did not work with the select, poll, and /dev/poll methods. *) Bugfix: in SSI handling. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket. *) Bugfix: the "auth_basic" directive did not disable the authorization; bug appeared in 0.3.11.
author Igor Sysoev <http://sysoev.ru>
date Mon, 05 Dec 2005 00:00:00 +0300
parents 82d695e3d662
children 8e6d4d96ec4c
comparison
equal deleted inserted replaced
131:add6b1e86d38 132:91372f004adf
232 NULL, /* exit master */ 232 NULL, /* exit master */
233 NGX_MODULE_V1_PADDING 233 NGX_MODULE_V1_PADDING
234 }; 234 };
235 235
236 236
237 static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = { 237 static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = {
238 { ngx_string("upstream_status"), 0, NULL, 238 { ngx_string("upstream_status"), 0, NULL,
239 ngx_http_upstream_log_status_getlen, 239 ngx_http_upstream_log_status_getlen,
240 ngx_http_upstream_log_status }, 240 ngx_http_upstream_log_status },
241 { ngx_string("upstream_response_time"), 0, NULL, 241 { ngx_string("upstream_response_time"), 0, NULL,
242 ngx_http_upstream_log_response_time_getlen, 242 ngx_http_upstream_log_response_time_getlen,
246 246
247 247
248 static ngx_http_variable_t ngx_http_upstream_vars[] = { 248 static ngx_http_variable_t ngx_http_upstream_vars[] = {
249 249
250 { ngx_string("upstream_status"), 250 { ngx_string("upstream_status"),
251 ngx_http_upstream_status_variable, 0, 0, 0 }, 251 ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
252 252
253 { ngx_string("upstream_response_time"), 253 { ngx_string("upstream_response_time"),
254 ngx_http_upstream_response_time_variable, 0, 0, 0 }, 254 ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
255 255
256 { ngx_null_string, NULL, 0, 0, 0 } 256 { ngx_null_string, NULL, 0, 0, 0 }
257 }; 257 };
258 258
259 259
385 ev->write, &r->uri); 385 ev->write, &r->uri);
386 386
387 c = r->connection; 387 c = r->connection;
388 u = r->upstream; 388 u = r->upstream;
389 389
390 if (c->closed) { 390 if (c->error) {
391 ngx_http_upstream_finalize_request(r, u, 391 ngx_http_upstream_finalize_request(r, u,
392 NGX_HTTP_CLIENT_CLOSED_REQUEST); 392 NGX_HTTP_CLIENT_CLOSED_REQUEST);
393 return; 393 return;
394 } 394 }
395 395
404 if (!ev->pending_eof) { 404 if (!ev->pending_eof) {
405 return; 405 return;
406 } 406 }
407 407
408 ev->eof = 1; 408 ev->eof = 1;
409 c->closed = 1; 409 c->error = 1;
410 410
411 if (ev->kq_errno) { 411 if (ev->kq_errno) {
412 ev->error = 1; 412 ev->error = 1;
413 } 413 }
414 414
471 } else { /* n == 0 */ 471 } else { /* n == 0 */
472 err = 0; 472 err = 0;
473 } 473 }
474 474
475 ev->eof = 1; 475 ev->eof = 1;
476 c->closed = 1; 476 c->error = 1;
477 477
478 if (!u->cachable && u->peer.connection) { 478 if (!u->cachable && u->peer.connection) {
479 ngx_log_error(NGX_LOG_INFO, ev->log, err, 479 ngx_log_error(NGX_LOG_INFO, ev->log, err,
480 "client closed prematurely connection, " 480 "client closed prematurely connection, "
481 "so upstream connection is closed too"); 481 "so upstream connection is closed too");
1123 1123
1124 1124
1125 static void 1125 static void
1126 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)
1127 { 1127 {
1128 int tcp_nodelay;
1128 ssize_t size; 1129 ssize_t size;
1129 ngx_int_t rc; 1130 ngx_int_t rc;
1130 ngx_uint_t i, key; 1131 ngx_uint_t i, key;
1131 ngx_list_part_t *part; 1132 ngx_list_part_t *part;
1132 ngx_table_elt_t *h; 1133 ngx_table_elt_t *h;
1133 ngx_event_pipe_t *p; 1134 ngx_event_pipe_t *p;
1135 ngx_connection_t *c;
1134 ngx_pool_cleanup_t *cl; 1136 ngx_pool_cleanup_t *cl;
1135 ngx_pool_cleanup_file_t *clf; 1137 ngx_pool_cleanup_file_t *clf;
1136 ngx_http_core_loc_conf_t *clcf; 1138 ngx_http_core_loc_conf_t *clcf;
1137 ngx_http_upstream_header_t *hh; 1139 ngx_http_upstream_header_t *hh;
1138 ngx_http_upstream_main_conf_t *umcf; 1140 ngx_http_upstream_main_conf_t *umcf;
1207 } 1209 }
1208 } 1210 }
1209 } 1211 }
1210 } 1212 }
1211 1213
1214 c = r->connection;
1215
1212 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1216 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1213 1217
1214 if (u->pipe == NULL) { 1218 if (u->pipe == NULL) {
1215 1219
1216 if (u->input_filter == NULL) { 1220 if (u->input_filter == NULL) {
1229 if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) { 1233 if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
1230 ngx_http_upstream_finalize_request(r, u, 0); 1234 ngx_http_upstream_finalize_request(r, u, 0);
1231 return; 1235 return;
1232 } 1236 }
1233 1237
1238 if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
1239 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
1240
1241 tcp_nodelay = 1;
1242
1243 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
1244 (const void *) &tcp_nodelay, sizeof(int)) == -1)
1245 {
1246 ngx_connection_error(c, ngx_socket_errno,
1247 "setsockopt(TCP_NODELAY) failed");
1248 ngx_http_upstream_finalize_request(r, u, 0);
1249 return;
1250 }
1251
1252 c->tcp_nodelay = NGX_TCP_NODELAY_SET;
1253 }
1254
1234 size = u->buffer.last - u->buffer.pos; 1255 size = u->buffer.last - u->buffer.pos;
1235 1256
1236 if (size) { 1257 if (size) {
1237 u->buffer.last = u->buffer.pos; 1258 u->buffer.last = u->buffer.pos;
1238 1259
1239 if (u->input_filter(u->input_filter_ctx, size) == NGX_ERROR) { 1260 if (u->input_filter(u->input_filter_ctx, size) == NGX_ERROR) {
1240 ngx_http_upstream_finalize_request(r, u, 0); 1261 ngx_http_upstream_finalize_request(r, u, 0);
1241 return; 1262 return;
1242 } 1263 }
1243 1264
1244 ngx_http_upstream_process_non_buffered_body(r->connection->write); 1265 ngx_http_upstream_process_non_buffered_body(c->write);
1245 1266
1246 } else { 1267 } else {
1247 u->buffer.pos = u->buffer.start; 1268 u->buffer.pos = u->buffer.start;
1248 u->buffer.last = u->buffer.start; 1269 u->buffer.last = u->buffer.start;
1249 1270
1260 1281
1261 #if 0 1282 #if 0
1262 1283
1263 if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) { 1284 if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) {
1264 if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) { 1285 if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) {
1265 ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, 1286 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
1266 ngx_close_file_n " \"%s\" failed", 1287 ngx_close_file_n " \"%s\" failed",
1267 u->cache->ctx.file.name.data); 1288 u->cache->ctx.file.name.data);
1268 } 1289 }
1269 } 1290 }
1270 1291
1290 p->output_ctx = r; 1311 p->output_ctx = r;
1291 p->tag = u->output.tag; 1312 p->tag = u->output.tag;
1292 p->bufs = u->conf->bufs; 1313 p->bufs = u->conf->bufs;
1293 p->busy_size = u->conf->busy_buffers_size; 1314 p->busy_size = u->conf->busy_buffers_size;
1294 p->upstream = u->peer.connection; 1315 p->upstream = u->peer.connection;
1295 p->downstream = r->connection; 1316 p->downstream = c;
1296 p->pool = r->pool; 1317 p->pool = r->pool;
1297 p->log = r->connection->log; 1318 p->log = c->log;
1298 1319
1299 p->cachable = u->cachable; 1320 p->cachable = u->cachable;
1300 1321
1301 p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); 1322 p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
1302 if (p->temp_file == NULL) { 1323 if (p->temp_file == NULL) {
1303 ngx_http_upstream_finalize_request(r, u, 0); 1324 ngx_http_upstream_finalize_request(r, u, 0);
1304 return; 1325 return;
1305 } 1326 }
1306 1327
1307 p->temp_file->file.fd = NGX_INVALID_FILE; 1328 p->temp_file->file.fd = NGX_INVALID_FILE;
1308 p->temp_file->file.log = r->connection->log; 1329 p->temp_file->file.log = c->log;
1309 p->temp_file->path = u->conf->temp_path; 1330 p->temp_file->path = u->conf->temp_path;
1310 p->temp_file->pool = r->pool; 1331 p->temp_file->pool = r->pool;
1311 1332
1312 if (u->cachable) { 1333 if (u->cachable) {
1313 p->temp_file->persistent = 1; 1334 p->temp_file->persistent = 1;
1362 * because the writing a new data may interfere with sendfile() 1383 * because the writing a new data may interfere with sendfile()
1363 * that uses the same kernel file pages (at least on FreeBSD) 1384 * that uses the same kernel file pages (at least on FreeBSD)
1364 */ 1385 */
1365 1386
1366 p->cyclic_temp_file = 1; 1387 p->cyclic_temp_file = 1;
1367 r->connection->sendfile = 0; 1388 c->sendfile = 0;
1368 1389
1369 } else { 1390 } else {
1370 p->cyclic_temp_file = 0; 1391 p->cyclic_temp_file = 0;
1371 } 1392 }
1372 1393
1392 ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) 1413 ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
1393 { 1414 {
1394 size_t size; 1415 size_t size;
1395 ssize_t n; 1416 ssize_t n;
1396 ngx_buf_t *b; 1417 ngx_buf_t *b;
1418 ngx_int_t rc;
1397 ngx_uint_t do_write; 1419 ngx_uint_t do_write;
1398 ngx_connection_t *c; 1420 ngx_connection_t *c, *client;
1399 ngx_http_request_t *r; 1421 ngx_http_request_t *r;
1400 ngx_http_upstream_t *u; 1422 ngx_http_upstream_t *u;
1401 ngx_http_core_loc_conf_t *clcf; 1423 ngx_http_core_loc_conf_t *clcf;
1402 1424
1403 c = ev->data; 1425 c = ev->data;
1424 } 1446 }
1425 } 1447 }
1426 1448
1427 r = c->data; 1449 r = c->data;
1428 u = r->upstream; 1450 u = r->upstream;
1451 client = r->connection;
1429 1452
1430 b = &u->buffer; 1453 b = &u->buffer;
1431 1454
1432 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 1455 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1433 1456
1436 for ( ;; ) { 1459 for ( ;; ) {
1437 1460
1438 if (do_write) { 1461 if (do_write) {
1439 1462
1440 if (u->out_bufs || u->busy_bufs) { 1463 if (u->out_bufs || u->busy_bufs) {
1441 if (ngx_http_output_filter(r, u->out_bufs) == NGX_ERROR) { 1464 rc = ngx_http_output_filter(r, u->out_bufs);
1465
1466 if (client->destroyed) {
1467 return;
1468 }
1469
1470 if (rc == NGX_ERROR) {
1442 ngx_http_upstream_finalize_request(r, u, 0); 1471 ngx_http_upstream_finalize_request(r, u, 0);
1443 return; 1472 return;
1444 } 1473 }
1445 1474
1446 ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs, 1475 ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs,
1488 } 1517 }
1489 1518
1490 break; 1519 break;
1491 } 1520 }
1492 1521
1493 if (ngx_handle_write_event(r->connection->write, clcf->send_lowat) 1522 if (client->data == r) {
1494 == NGX_ERROR) 1523 if (ngx_handle_write_event(client->write, clcf->send_lowat)
1495 { 1524 == NGX_ERROR)
1496 ngx_http_upstream_finalize_request(r, u, 0); 1525 {
1497 return; 1526 ngx_http_upstream_finalize_request(r, u, 0);
1498 } 1527 return;
1499 1528 }
1500 if (r->connection->write->active) { 1529 }
1501 ngx_add_timer(r->connection->write, clcf->send_timeout); 1530
1502 1531 if (client->write->active) {
1503 } else if (r->connection->write->timer_set) { 1532 ngx_add_timer(client->write, clcf->send_timeout);
1504 ngx_del_timer(r->connection->write); 1533
1534 } else if (client->write->timer_set) {
1535 ngx_del_timer(client->write);
1505 } 1536 }
1506 1537
1507 if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) { 1538 if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) {
1508 ngx_http_upstream_finalize_request(r, u, 0); 1539 ngx_http_upstream_finalize_request(r, u, 0);
1509 return; 1540 return;
1510 } 1541 }
1511 1542
1512 if (u->peer.connection->read->active) { 1543 if (u->peer.connection->read->active) {
1513 ngx_add_timer(u->peer.connection->read, u->conf->read_timeout); 1544 ngx_add_timer(u->peer.connection->read, u->conf->read_timeout);
1514 1545
1515 } else if (r->connection->read->timer_set) { 1546 } else if (u->peer.connection->read->timer_set) {
1516 ngx_del_timer(r->connection->read); 1547 ngx_del_timer(u->peer.connection->read);
1517 } 1548 }
1518 } 1549 }
1519 1550
1520 1551
1521 static ngx_int_t 1552 static ngx_int_t
1575 1606
1576 static void 1607 static void
1577 ngx_http_upstream_process_body(ngx_event_t *ev) 1608 ngx_http_upstream_process_body(ngx_event_t *ev)
1578 { 1609 {
1579 ngx_event_pipe_t *p; 1610 ngx_event_pipe_t *p;
1580 ngx_connection_t *c; 1611 ngx_connection_t *c, *downstream;
1581 ngx_http_request_t *r; 1612 ngx_http_request_t *r;
1582 ngx_http_upstream_t *u; 1613 ngx_http_upstream_t *u;
1583 1614
1584 c = ev->data; 1615 c = ev->data;
1585 r = c->data; 1616 r = c->data;
1586 u = r->upstream; 1617 u = r->upstream;
1618 downstream = r->connection;
1587 1619
1588 if (ev->write) { 1620 if (ev->write) {
1589 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 1621 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1590 "http upstream process downstream"); 1622 "http upstream process downstream");
1591 c->log->action = "sending to client"; 1623 c->log->action = "sending to client";
1616 1648
1617 return; 1649 return;
1618 } 1650 }
1619 1651
1620 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { 1652 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
1653
1654 if (downstream->destroyed) {
1655 return;
1656 }
1657
1621 ngx_http_upstream_finalize_request(r, u, 0); 1658 ngx_http_upstream_finalize_request(r, u, 0);
1622 return; 1659 return;
1623 } 1660 }
1624 1661
1625 } else { 1662 } else {
1646 1683
1647 return; 1684 return;
1648 } 1685 }
1649 1686
1650 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { 1687 if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
1688
1689 if (downstream->destroyed) {
1690 return;
1691 }
1692
1651 ngx_http_upstream_finalize_request(r, u, 0); 1693 ngx_http_upstream_finalize_request(r, u, 0);
1652 return; 1694 return;
1653 } 1695 }
1654 } 1696 }
1655 1697
1759 default: 1801 default:
1760 status = NGX_HTTP_BAD_GATEWAY; 1802 status = NGX_HTTP_BAD_GATEWAY;
1761 } 1803 }
1762 } 1804 }
1763 1805
1764 if (r->connection->closed) { 1806 if (r->connection->error) {
1765 ngx_http_upstream_finalize_request(r, u, 1807 ngx_http_upstream_finalize_request(r, u,
1766 NGX_HTTP_CLIENT_CLOSED_REQUEST); 1808 NGX_HTTP_CLIENT_CLOSED_REQUEST);
1767 return; 1809 return;
1768 } 1810 }
1769 1811