<div dir="ltr">Hi,<div><br></div><div style>Could you please take a look at the following patch.</div><div style>In this patch I tried to fix handling for tcp_nodelay and tcp_nopush.</div><div style>This patch is only applicable for SPDY over TCP connection (but not for SPDY over SSL).</div>
<div style><br></div><div style><div># HG changeset patch</div><div># User <a href="mailto:ykirpichev@gmail.com">ykirpichev@gmail.com</a></div><div># Date 1371726192 -14400</div><div># Branch fix_spdy_nopush_nodelay</div>
<div># Node ID 71c426451cbe308c8a96cce175d34aeca39a266a</div><div># Parent  982678c5c270f93a0c21ab6eb23cb123c0dc3df0</div><div>Fix spdy tcp_nodelay and tcp_nopush optioins handling</div><div><br></div><div>diff -r 982678c5c270 -r 71c426451cbe src/http/ngx_http_request.c</div>
<div>--- a/src/http/ngx_http_request.c<span class="" style="white-space:pre">   </span>Wed Jun 12 00:41:24 2013 +0900</div><div>+++ b/src/http/ngx_http_request.c<span class="" style="white-space:pre">    </span>Thu Jun 20 15:03:12 2013 +0400</div>
<div>@@ -314,6 +314,13 @@</div><div> </div><div> #if (NGX_HTTP_SPDY)</div><div>     if (hc->addr_conf->spdy) {</div><div>+        ngx_http_core_loc_conf_t   *clcf;</div><div>+</div><div>+        clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,</div>
<div>+                                            ngx_http_core_module);</div><div>+</div><div>+        c->tcp_nodelay = clcf->tcp_nodelay ? NGX_TCP_NODELAY_UNSET : NGX_TCP_NODELAY_DISABLED;</div><div>+        c->tcp_nopush = clcf->tcp_nopush ? NGX_TCP_NOPUSH_UNSET : NGX_TCP_NOPUSH_DISABLED;</div>
<div>         rev->handler = ngx_http_spdy_init;</div><div>     }</div><div> #endif</div><div>diff -r 982678c5c270 -r 71c426451cbe 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>Thu Jun 20 15:03:12 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,51 @@</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>+    // 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>+        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>+        } </div><div>+</div><div>+        if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)</div>
<div>+        {</div><div>+            int tcp_nodelay = 1;</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 style>BR/ Yury</div></div></div>