diff options
Diffstat (limited to 'src/http/ngx_http_upstream.c')
-rw-r--r-- | src/http/ngx_http_upstream.c | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index 37e979a9d..cfaca6e13 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -234,7 +234,7 @@ ngx_module_t ngx_http_upstream_module = { }; -static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = { +static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = { { ngx_string("upstream_status"), 0, NULL, ngx_http_upstream_log_status_getlen, ngx_http_upstream_log_status }, @@ -248,10 +248,10 @@ static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = { static ngx_http_variable_t ngx_http_upstream_vars[] = { { ngx_string("upstream_status"), - ngx_http_upstream_status_variable, 0, 0, 0 }, + ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, { ngx_string("upstream_response_time"), - ngx_http_upstream_response_time_variable, 0, 0, 0 }, + ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, { ngx_null_string, NULL, 0, 0, 0 } }; @@ -387,7 +387,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, c = r->connection; u = r->upstream; - if (c->closed) { + if (c->error) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; @@ -406,7 +406,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, } ev->eof = 1; - c->closed = 1; + c->error = 1; if (ev->kq_errno) { ev->error = 1; @@ -473,7 +473,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, } ev->eof = 1; - c->closed = 1; + c->error = 1; if (!u->cachable && u->peer.connection) { ngx_log_error(NGX_LOG_INFO, ev->log, err, @@ -1125,12 +1125,14 @@ ngx_http_upstream_process_header(ngx_event_t *rev) static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) { + int tcp_nodelay; ssize_t size; ngx_int_t rc; ngx_uint_t i, key; ngx_list_part_t *part; ngx_table_elt_t *h; ngx_event_pipe_t *p; + ngx_connection_t *c; ngx_pool_cleanup_t *cl; ngx_pool_cleanup_file_t *clf; ngx_http_core_loc_conf_t *clcf; @@ -1209,6 +1211,8 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) } } + c = r->connection; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (u->pipe == NULL) { @@ -1231,6 +1235,23 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } + if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + } + size = u->buffer.last - u->buffer.pos; if (size) { @@ -1241,7 +1262,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) return; } - ngx_http_upstream_process_non_buffered_body(r->connection->write); + ngx_http_upstream_process_non_buffered_body(c->write); } else { u->buffer.pos = u->buffer.start; @@ -1262,7 +1283,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) { if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ngx_close_file_n " \"%s\" failed", u->cache->ctx.file.name.data); } @@ -1292,9 +1313,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) p->bufs = u->conf->bufs; p->busy_size = u->conf->busy_buffers_size; p->upstream = u->peer.connection; - p->downstream = r->connection; + p->downstream = c; p->pool = r->pool; - p->log = r->connection->log; + p->log = c->log; p->cachable = u->cachable; @@ -1305,7 +1326,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) } p->temp_file->file.fd = NGX_INVALID_FILE; - p->temp_file->file.log = r->connection->log; + p->temp_file->file.log = c->log; p->temp_file->path = u->conf->temp_path; p->temp_file->pool = r->pool; @@ -1364,7 +1385,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) */ p->cyclic_temp_file = 1; - r->connection->sendfile = 0; + c->sendfile = 0; } else { p->cyclic_temp_file = 0; @@ -1394,8 +1415,9 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) size_t size; ssize_t n; ngx_buf_t *b; + ngx_int_t rc; ngx_uint_t do_write; - ngx_connection_t *c; + ngx_connection_t *c, *client; ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_http_core_loc_conf_t *clcf; @@ -1426,6 +1448,7 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) r = c->data; u = r->upstream; + client = r->connection; b = &u->buffer; @@ -1438,7 +1461,13 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) if (do_write) { if (u->out_bufs || u->busy_bufs) { - if (ngx_http_output_filter(r, u->out_bufs) == NGX_ERROR) { + rc = ngx_http_output_filter(r, u->out_bufs); + + if (client->destroyed) { + return; + } + + if (rc == NGX_ERROR) { ngx_http_upstream_finalize_request(r, u, 0); return; } @@ -1490,18 +1519,20 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) break; } - if (ngx_handle_write_event(r->connection->write, clcf->send_lowat) - == NGX_ERROR) - { - ngx_http_upstream_finalize_request(r, u, 0); - return; + if (client->data == r) { + if (ngx_handle_write_event(client->write, clcf->send_lowat) + == NGX_ERROR) + { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } } - if (r->connection->write->active) { - ngx_add_timer(r->connection->write, clcf->send_timeout); + if (client->write->active) { + ngx_add_timer(client->write, clcf->send_timeout); - } else if (r->connection->write->timer_set) { - ngx_del_timer(r->connection->write); + } else if (client->write->timer_set) { + ngx_del_timer(client->write); } if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) { @@ -1512,8 +1543,8 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev) if (u->peer.connection->read->active) { ngx_add_timer(u->peer.connection->read, u->conf->read_timeout); - } else if (r->connection->read->timer_set) { - ngx_del_timer(r->connection->read); + } else if (u->peer.connection->read->timer_set) { + ngx_del_timer(u->peer.connection->read); } } @@ -1577,13 +1608,14 @@ static void ngx_http_upstream_process_body(ngx_event_t *ev) { ngx_event_pipe_t *p; - ngx_connection_t *c; + ngx_connection_t *c, *downstream; ngx_http_request_t *r; ngx_http_upstream_t *u; c = ev->data; r = c->data; u = r->upstream; + downstream = r->connection; if (ev->write) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, @@ -1618,6 +1650,11 @@ ngx_http_upstream_process_body(ngx_event_t *ev) } if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { + + if (downstream->destroyed) { + return; + } + ngx_http_upstream_finalize_request(r, u, 0); return; } @@ -1648,6 +1685,11 @@ ngx_http_upstream_process_body(ngx_event_t *ev) } if (ngx_event_pipe(p, ev->write) == NGX_ABORT) { + + if (downstream->destroyed) { + return; + } + ngx_http_upstream_finalize_request(r, u, 0); return; } @@ -1761,7 +1803,7 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, } } - if (r->connection->closed) { + if (r->connection->error) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); return; |