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;