Mercurial > hg > nginx-vendor-1-0
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 |