<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>