Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 6078:7ea6f5140ed9 stable-1.6
SPDY: push pending data while closing a stream as with keepalive.
This helps to avoid delays in sending the last chunk of data because
of bad interaction between Nagle's algorithm on nginx side and
delayed ACK on the client side.
Delays could also be caused by TCP_CORK/TCP_NOPUSH if SPDY was
working without SSL and sendfile() was used.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 21 Nov 2014 22:51:49 +0300 |
parents | b6240baead00 |
children |
comparison
equal
deleted
inserted
replaced
6077:0395f788b080 | 6078:7ea6f5140ed9 |
---|---|
3154 | 3154 |
3155 | 3155 |
3156 void | 3156 void |
3157 ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) | 3157 ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc) |
3158 { | 3158 { |
3159 int tcp_nodelay; | |
3159 ngx_event_t *ev; | 3160 ngx_event_t *ev; |
3160 ngx_connection_t *fc; | 3161 ngx_connection_t *c, *fc; |
3162 ngx_http_core_loc_conf_t *clcf; | |
3161 ngx_http_spdy_stream_t **index, *s; | 3163 ngx_http_spdy_stream_t **index, *s; |
3162 ngx_http_spdy_srv_conf_t *sscf; | 3164 ngx_http_spdy_srv_conf_t *sscf; |
3163 ngx_http_spdy_connection_t *sc; | 3165 ngx_http_spdy_connection_t *sc; |
3164 | 3166 |
3165 sc = stream->connection; | 3167 sc = stream->connection; |
3180 NGX_SPDY_INTERNAL_ERROR, | 3182 NGX_SPDY_INTERNAL_ERROR, |
3181 stream->priority) | 3183 stream->priority) |
3182 != NGX_OK) | 3184 != NGX_OK) |
3183 { | 3185 { |
3184 sc->connection->error = 1; | 3186 sc->connection->error = 1; |
3187 } | |
3188 | |
3189 } else { | |
3190 c = sc->connection; | |
3191 | |
3192 if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { | |
3193 if (ngx_tcp_push(c->fd) == -1) { | |
3194 ngx_connection_error(c, ngx_socket_errno, | |
3195 ngx_tcp_push_n " failed"); | |
3196 c->error = 1; | |
3197 tcp_nodelay = 0; | |
3198 | |
3199 } else { | |
3200 c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; | |
3201 tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; | |
3202 } | |
3203 | |
3204 } else { | |
3205 tcp_nodelay = 1; | |
3206 } | |
3207 | |
3208 clcf = ngx_http_get_module_loc_conf(stream->request, | |
3209 ngx_http_core_module); | |
3210 | |
3211 if (tcp_nodelay | |
3212 && clcf->tcp_nodelay | |
3213 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) | |
3214 { | |
3215 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); | |
3216 | |
3217 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, | |
3218 (const void *) &tcp_nodelay, sizeof(int)) | |
3219 == -1) | |
3220 { | |
3221 #if (NGX_SOLARIS) | |
3222 /* Solaris returns EINVAL if a socket has been shut down */ | |
3223 c->log_error = NGX_ERROR_IGNORE_EINVAL; | |
3224 #endif | |
3225 | |
3226 ngx_connection_error(c, ngx_socket_errno, | |
3227 "setsockopt(TCP_NODELAY) failed"); | |
3228 | |
3229 c->log_error = NGX_ERROR_INFO; | |
3230 c->error = 1; | |
3231 | |
3232 } else { | |
3233 c->tcp_nodelay = NGX_TCP_NODELAY_SET; | |
3234 } | |
3185 } | 3235 } |
3186 } | 3236 } |
3187 | 3237 |
3188 if (sc->stream == stream) { | 3238 if (sc->stream == stream) { |
3189 sc->stream = NULL; | 3239 sc->stream = NULL; |