SPDY: fix tcp_nodelay and tcp_nopush handling
Yury Kirpichev
ykirpichev at gmail.com
Thu Jun 20 11:08:38 UTC 2013
Hi,
Could you please take a look at the following patch.
In this patch I tried to fix handling for tcp_nodelay and tcp_nopush.
This patch is only applicable for SPDY over TCP connection (but not for
SPDY over SSL).
# HG changeset patch
# User ykirpichev at gmail.com
# Date 1371726192 -14400
# Branch fix_spdy_nopush_nodelay
# Node ID 71c426451cbe308c8a96cce175d34aeca39a266a
# Parent 982678c5c270f93a0c21ab6eb23cb123c0dc3df0
Fix spdy tcp_nodelay and tcp_nopush optioins handling
diff -r 982678c5c270 -r 71c426451cbe src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c Wed Jun 12 00:41:24 2013 +0900
+++ b/src/http/ngx_http_request.c Thu Jun 20 15:03:12 2013 +0400
@@ -314,6 +314,13 @@
#if (NGX_HTTP_SPDY)
if (hc->addr_conf->spdy) {
+ ngx_http_core_loc_conf_t *clcf;
+
+ clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,
+ ngx_http_core_module);
+
+ c->tcp_nodelay = clcf->tcp_nodelay ? NGX_TCP_NODELAY_UNSET :
NGX_TCP_NODELAY_DISABLED;
+ c->tcp_nopush = clcf->tcp_nopush ? NGX_TCP_NOPUSH_UNSET :
NGX_TCP_NOPUSH_DISABLED;
rev->handler = ngx_http_spdy_init;
}
#endif
diff -r 982678c5c270 -r 71c426451cbe src/http/ngx_http_spdy.c
--- a/src/http/ngx_http_spdy.c Wed Jun 12 00:41:24 2013 +0900
+++ b/src/http/ngx_http_spdy.c Thu Jun 20 15:03:12 2013 +0400
@@ -154,6 +154,8 @@
static void *ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size);
static void ngx_http_spdy_zfree(void *opaque, void *address);
+static ngx_int_t
+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t
*hc);
static const u_char ngx_http_spdy_dict[] =
@@ -378,6 +380,11 @@
sc->blocked = 0;
+ if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {
+ ngx_http_spdy_finalize_connection(sc,
NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
if (sc->processing) {
if (rev->timer_set) {
ngx_del_timer(rev);
@@ -447,6 +454,11 @@
return;
}
+ if (ngx_http_spdy_restore_nopush(c, sc->http_connection) != NGX_OK) {
+ ngx_http_spdy_finalize_connection(sc,
NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
ngx_http_spdy_handle_connection(sc);
}
@@ -2880,3 +2892,51 @@
"spdy zfree: %p", address);
#endif
}
+
+static ngx_int_t
+ngx_http_spdy_restore_nopush(ngx_connection_t *c, ngx_http_connection_t
*hc)
+{
+ // It is better to use NGX_SPDY_WRITE_BUFFERED here, but
+ // it is defined in ngx_http_spdy_filter_module.c
+ // So, just use !c->buffered
+ if (!c->buffered && !c->error) {
+ //no buffered data, so, we should clean nopush if needed
+ if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+ if (ngx_tcp_push(c->fd) == -1) {
+ ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n "
failed");
+ return NGX_ERROR;
+ }
+
+ c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
+ }
+
+ if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
+ {
+ int tcp_nodelay = 1;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
+
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) &tcp_nodelay, sizeof(int))
+ == -1)
+ {
+#if (NGX_SOLARIS)
+ /* Solaris returns EINVAL if a socket has been shut down */
+ c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(TCP_NODELAY) failed");
+
+ c->log_error = NGX_ERROR_INFO;
+ return NGX_ERROR;
+ }
+
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
BR/ Yury
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20130620/1ac4a6a9/attachment.html>
More information about the nginx-devel
mailing list