[nginx] SPDY: removed state to check first SETTINGS frame.

Valentin Bartenev vbart at nginx.com
Wed Jan 22 03:10:10 UTC 2014


details:   http://hg.nginx.org/nginx/rev/2c6f82c0cec2
branches:  
changeset: 5526:2c6f82c0cec2
user:      Valentin Bartenev <vbart at nginx.com>
date:      Wed Jan 22 04:58:19 2014 +0400
description:
SPDY: removed state to check first SETTINGS frame.

That code was based on misunderstanding of spdy specification about
configuration applicability in the SETTINGS frames.  The original
interpretation was that configuration is assigned for the whole
SPDY connection, while it is only for the endpoint.

Moreover, the strange thing is that specification forbids multiple
entries in the SETTINGS frame with the same ID even if flags are
different.  As a result, Chrome sends two SETTINGS frames: one with
its own configuration, and another one with configuration stored
for a server (when the FLAG_SETTINGS_PERSIST_VALUE flags were used
by the server).

To simplify implementation we refuse to use the persistent settings
feature and thereby avoid all the complexity related with its proper
support.

diffstat:

 src/http/ngx_http_spdy.c |  73 +++++++++--------------------------------------
 1 files changed, 15 insertions(+), 58 deletions(-)

diffs (143 lines):

diff -r 206c56e23a96 -r 2c6f82c0cec2 src/http/ngx_http_spdy.c
--- a/src/http/ngx_http_spdy.c	Wed Jan 22 04:58:19 2014 +0400
+++ b/src/http/ngx_http_spdy.c	Wed Jan 22 04:58:19 2014 +0400
@@ -81,8 +81,6 @@ static void ngx_http_spdy_read_handler(n
 static void ngx_http_spdy_write_handler(ngx_event_t *wev);
 static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc);
 
-static u_char *ngx_http_spdy_state_detect_settings(
-    ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end);
 static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc,
     u_char *pos, u_char *end);
 static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc,
@@ -101,8 +99,10 @@ static u_char *ngx_http_spdy_state_ping(
     u_char *pos, u_char *end);
 static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc,
     u_char *pos, u_char *end);
+#if 0
 static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc,
     u_char *pos, u_char *end);
+#endif
 static u_char *ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc,
     u_char *pos, u_char *end);
 static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc,
@@ -235,7 +235,7 @@ ngx_http_spdy_init(ngx_event_t *rev)
     sc->connection = c;
     sc->http_connection = hc;
 
-    sc->handler = ngx_http_spdy_state_detect_settings;
+    sc->handler = ngx_http_spdy_state_head;
 
     sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
     sc->zstream_in.zfree = ngx_http_spdy_zfree;
@@ -297,6 +297,11 @@ ngx_http_spdy_init(ngx_event_t *rev)
         return;
     }
 
+    if (ngx_http_spdy_send_settings(sc) == NGX_ERROR) {
+        ngx_http_close_connection(c);
+        return;
+    }
+
     c->data = sc;
 
     rev->handler = ngx_http_spdy_read_handler;
@@ -610,38 +615,6 @@ ngx_http_spdy_handle_connection(ngx_http
 
 
 static u_char *
-ngx_http_spdy_state_detect_settings(ngx_http_spdy_connection_t *sc,
-    u_char *pos, u_char *end)
-{
-    if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) {
-        return ngx_http_spdy_state_save(sc, pos, end,
-                                        ngx_http_spdy_state_detect_settings);
-    }
-
-    /*
-     * Since this is the first frame in a buffer,
-     * then it is properly aligned
-     */
-
-    if (*(uint32_t *) pos == htonl(ngx_spdy_ctl_frame_head(NGX_SPDY_SETTINGS)))
-    {
-        sc->length = ngx_spdy_frame_length(htonl(((uint32_t *) pos)[1]));
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
-                       "spdy SETTINGS frame received, size: %uz", sc->length);
-
-        pos += NGX_SPDY_FRAME_HEADER_SIZE;
-
-        return ngx_http_spdy_state_settings(sc, pos, end);
-    }
-
-    ngx_http_spdy_send_settings(sc);
-
-    return ngx_http_spdy_state_head(sc, pos, end);
-}
-
-
-static u_char *
 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
     u_char *end)
 {
@@ -1395,13 +1368,12 @@ ngx_http_spdy_state_skip(ngx_http_spdy_c
 }
 
 
+#if 0
+
 static u_char *
 ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
     u_char *end)
 {
-    ngx_uint_t                 v;
-    ngx_http_spdy_srv_conf_t  *sscf;
-
     if (sc->entries == 0) {
 
         if (end - pos < NGX_SPDY_SETTINGS_NUM_SIZE) {
@@ -1432,29 +1404,15 @@ ngx_http_spdy_state_settings(ngx_http_sp
 
         sc->entries--;
 
-        if (pos[0] != NGX_SPDY_SETTINGS_MAX_STREAMS) {
-            pos += NGX_SPDY_SETTINGS_PAIR_SIZE;
-            sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE;
-            continue;
-        }
-
-        v = ngx_spdy_frame_parse_uint32(pos + NGX_SPDY_SETTINGS_IDF_SIZE);
-
-        sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
-                                            ngx_http_spdy_module);
-
-        if (v != sscf->concurrent_streams) {
-            ngx_http_spdy_send_settings(sc);
-        }
-
-        return ngx_http_spdy_state_skip(sc, pos, end);
+        pos += NGX_SPDY_SETTINGS_PAIR_SIZE;
+        sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE;
     }
 
-    ngx_http_spdy_send_settings(sc);
-
     return ngx_http_spdy_state_complete(sc, pos, end);
 }
 
+#endif
+
 
 static u_char *
 ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, u_char *pos,
@@ -1654,8 +1612,7 @@ ngx_http_spdy_send_settings(ngx_http_spd
 
     p = ngx_spdy_frame_aligned_write_uint32(p, 1);
     p = ngx_spdy_frame_aligned_write_uint32(p,
-                                            NGX_SPDY_SETTINGS_MAX_STREAMS << 24
-                                            | NGX_SPDY_SETTINGS_FLAG_PERSIST);
+                                          NGX_SPDY_SETTINGS_MAX_STREAMS << 24);
 
     sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
                                         ngx_http_spdy_module);



More information about the nginx-devel mailing list