<div dir="ltr">Hi,<div><br></div><div style>Please disregard v3 version of patch. I've found that it does not fix the problem in case if some data was buffered and afterwards was sent by "write" handler.</div>
<div style><br></div><div style>Here is new version:</div><div style><div># HG changeset patch</div><div># User <a href="mailto:ykirpichev@yandex-team.ru">ykirpichev@yandex-team.ru</a></div><div># Date 1371458549 -14400</div>
<div># Branch nopush_fix</div><div># Node ID 3d463c13dadd70b3f74cbc037938c624db348cc0</div><div># Parent 982678c5c270f93a0c21ab6eb23cb123c0dc3df0</div><div>SPDY: fix nopush cleanup</div><div><br></div><div>diff -r 982678c5c270 -r 3d463c13dadd src/http/ngx_http_spdy.c</div>
<div>--- a/src/http/ngx_http_spdy.c<span class="" style="white-space:pre"> </span>Wed Jun 12 00:41:24 2013 +0900</div><div>+++ b/src/http/ngx_http_spdy.c<span class="" style="white-space:pre"> </span>Mon Jun 17 12:42:29 2013 +0400</div>
<div>@@ -154,6 +154,8 @@</div><div> </div><div> static void *ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size);</div><div> static void ngx_http_spdy_zfree(void *opaque, void *address);</div><div>+static ngx_int_t</div>
<div>+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t *hc);</div><div> </div><div> </div><div> static const u_char ngx_http_spdy_dict[] =</div><div>@@ -378,6 +380,11 @@</div><div> </div><div> sc->blocked = 0;</div>
<div> </div><div>+ if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {</div><div>+ ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);</div><div>+ return;</div><div>
+ }</div><div>+</div><div> if (sc->processing) {</div><div> if (rev->timer_set) {</div><div> ngx_del_timer(rev);</div><div>@@ -447,6 +454,11 @@</div><div> return;</div><div> }</div>
<div> </div><div>+ if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {</div><div>+ ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);</div><div>+ return;</div><div>
+ }</div><div>+</div><div> ngx_http_spdy_handle_connection(sc);</div><div> }</div><div> </div><div>@@ -2880,3 +2892,61 @@</div><div> "spdy zfree: %p", address);</div><div> #endif</div><div>
}</div><div>+</div><div>+static ngx_int_t</div><div>+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t *hc)</div><div>+{</div><div>+ int tcp_nodelay;</div><div>+ ngx_http_core_loc_conf_t *clcf;</div>
<div>+</div><div>+ // It is better to use NGX_SPDY_WRITE_BUFFERED here, but</div><div>+ // it is defined in ngx_http_spdy_filter_module.c</div><div>+ // So, just use !c->buffered</div><div>+ if (!c->buffered && !c->error) {</div>
<div>+ //no buffered data, so, we should clean nopush if needed</div><div>+ clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,</div><div>+ ngx_http_core_module);</div>
<div>+</div><div>+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {</div><div>+ if (ngx_tcp_push(c->fd) == -1) {</div><div>+ ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");</div>
<div>+ return NGX_ERROR;</div><div>+ }</div><div>+</div><div>+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;</div><div>+ tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;</div>
<div>+</div><div>+ } else {</div><div>+ tcp_nodelay = 1;</div><div>+ }</div><div>+</div><div>+ if (tcp_nodelay</div><div>+ && clcf->tcp_nodelay</div><div>+ && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)</div>
<div>+ {</div><div>+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");</div><div>+</div><div>+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,</div><div>+ (const void *) &tcp_nodelay, sizeof(int))</div>
<div>+ == -1)</div><div>+ {</div><div>+#if (NGX_SOLARIS)</div><div>+ /* Solaris returns EINVAL if a socket has been shut down */</div><div>+ c->log_error = NGX_ERROR_IGNORE_EINVAL;</div>
<div>+#endif</div><div>+</div><div>+ ngx_connection_error(c, ngx_socket_errno,</div><div>+ "setsockopt(TCP_NODELAY) failed");</div><div>+</div><div>+ c->log_error = NGX_ERROR_INFO;</div>
<div>+ return NGX_ERROR;</div><div>+ }</div><div>+</div><div>+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;</div><div>+ }</div><div>+ }</div><div>+</div><div>+ return NGX_OK;</div>
<div>+}</div><div>+</div><div>+</div><div><br></div></div></div>