mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
SPDY: always push pending data.
This helps to avoid suboptimal behavior when a client waits for a control frame or more data to increase window size, but the frames have been delayed in the socket buffer. The delays can be caused by bad interaction between Nagle's algorithm on nginx side and delayed ACK on the client side or by TCP_CORK/TCP_NOPUSH if SPDY was working without SSL and sendfile() was used. The pushing code is now very similar to ngx_http_set_keepalive().
This commit is contained in:
parent
44586bf5ee
commit
0e853129ac
@ -662,6 +662,7 @@ ngx_http_spdy_write_handler(ngx_event_t *wev)
|
||||
ngx_int_t
|
||||
ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_chain_t *cl;
|
||||
ngx_event_t *wev;
|
||||
ngx_connection_t *c;
|
||||
@ -710,6 +711,44 @@ ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
||||
if (ngx_tcp_push(c->fd) == -1) {
|
||||
ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
||||
tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
|
||||
|
||||
} else {
|
||||
tcp_nodelay = 1;
|
||||
}
|
||||
|
||||
if (tcp_nodelay
|
||||
&& clcf->tcp_nodelay
|
||||
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int))
|
||||
== -1)
|
||||
{
|
||||
#if (NGX_SOLARIS)
|
||||
/* Solaris returns EINVAL if a socket has been shut down */
|
||||
c->log_error = NGX_ERROR_IGNORE_EINVAL;
|
||||
#endif
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
}
|
||||
|
||||
if (cl) {
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
|
||||
@ -3321,10 +3360,8 @@ ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
|
||||
void
|
||||
ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_event_t *ev;
|
||||
ngx_connection_t *c, *fc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_connection_t *fc;
|
||||
ngx_http_spdy_stream_t **index, *s;
|
||||
ngx_http_spdy_srv_conf_t *sscf;
|
||||
ngx_http_spdy_connection_t *sc;
|
||||
@ -3350,54 +3387,6 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
|
||||
{
|
||||
sc->connection->error = 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
c = sc->connection;
|
||||
|
||||
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
||||
if (ngx_tcp_push(c->fd) == -1) {
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
ngx_tcp_push_n " failed");
|
||||
c->error = 1;
|
||||
tcp_nodelay = 0;
|
||||
|
||||
} else {
|
||||
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
||||
tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
tcp_nodelay = 1;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(stream->request,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (tcp_nodelay
|
||||
&& clcf->tcp_nodelay
|
||||
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int))
|
||||
== -1)
|
||||
{
|
||||
#if (NGX_SOLARIS)
|
||||
/* Solaris returns EINVAL if a socket has been shut down */
|
||||
c->log_error = NGX_ERROR_IGNORE_EINVAL;
|
||||
#endif
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
c->error = 1;
|
||||
|
||||
} else {
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->stream == stream) {
|
||||
|
Loading…
Reference in New Issue
Block a user