Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 5526:2c6f82c0cec2
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.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Wed, 22 Jan 2014 04:58:19 +0400 |
parents | 206c56e23a96 |
children | f3f7b72ca6e9 |
comparison
equal
deleted
inserted
replaced
5525:206c56e23a96 | 5526:2c6f82c0cec2 |
---|---|
79 | 79 |
80 static void ngx_http_spdy_read_handler(ngx_event_t *rev); | 80 static void ngx_http_spdy_read_handler(ngx_event_t *rev); |
81 static void ngx_http_spdy_write_handler(ngx_event_t *wev); | 81 static void ngx_http_spdy_write_handler(ngx_event_t *wev); |
82 static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc); | 82 static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc); |
83 | 83 |
84 static u_char *ngx_http_spdy_state_detect_settings( | |
85 ngx_http_spdy_connection_t *sc, u_char *pos, u_char *end); | |
86 static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, | 84 static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, |
87 u_char *pos, u_char *end); | 85 u_char *pos, u_char *end); |
88 static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, | 86 static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, |
89 u_char *pos, u_char *end); | 87 u_char *pos, u_char *end); |
90 static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, | 88 static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, |
99 u_char *pos, u_char *end); | 97 u_char *pos, u_char *end); |
100 static u_char *ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, | 98 static u_char *ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, |
101 u_char *pos, u_char *end); | 99 u_char *pos, u_char *end); |
102 static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, | 100 static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, |
103 u_char *pos, u_char *end); | 101 u_char *pos, u_char *end); |
102 #if 0 | |
104 static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, | 103 static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, |
105 u_char *pos, u_char *end); | 104 u_char *pos, u_char *end); |
105 #endif | |
106 static u_char *ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, | 106 static u_char *ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, |
107 u_char *pos, u_char *end); | 107 u_char *pos, u_char *end); |
108 static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, | 108 static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, |
109 u_char *pos, u_char *end); | 109 u_char *pos, u_char *end); |
110 static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc, | 110 static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc, |
233 } | 233 } |
234 | 234 |
235 sc->connection = c; | 235 sc->connection = c; |
236 sc->http_connection = hc; | 236 sc->http_connection = hc; |
237 | 237 |
238 sc->handler = ngx_http_spdy_state_detect_settings; | 238 sc->handler = ngx_http_spdy_state_head; |
239 | 239 |
240 sc->zstream_in.zalloc = ngx_http_spdy_zalloc; | 240 sc->zstream_in.zalloc = ngx_http_spdy_zalloc; |
241 sc->zstream_in.zfree = ngx_http_spdy_zfree; | 241 sc->zstream_in.zfree = ngx_http_spdy_zfree; |
242 sc->zstream_in.opaque = sc; | 242 sc->zstream_in.opaque = sc; |
243 | 243 |
295 if (sc->streams_index == NULL) { | 295 if (sc->streams_index == NULL) { |
296 ngx_http_close_connection(c); | 296 ngx_http_close_connection(c); |
297 return; | 297 return; |
298 } | 298 } |
299 | 299 |
300 if (ngx_http_spdy_send_settings(sc) == NGX_ERROR) { | |
301 ngx_http_close_connection(c); | |
302 return; | |
303 } | |
304 | |
300 c->data = sc; | 305 c->data = sc; |
301 | 306 |
302 rev->handler = ngx_http_spdy_read_handler; | 307 rev->handler = ngx_http_spdy_read_handler; |
303 c->write->handler = ngx_http_spdy_write_handler; | 308 c->write->handler = ngx_http_spdy_write_handler; |
304 | 309 |
604 if (c->write->timer_set) { | 609 if (c->write->timer_set) { |
605 ngx_del_timer(c->write); | 610 ngx_del_timer(c->write); |
606 } | 611 } |
607 | 612 |
608 ngx_add_timer(c->read, sscf->keepalive_timeout); | 613 ngx_add_timer(c->read, sscf->keepalive_timeout); |
609 } | |
610 | |
611 | |
612 static u_char * | |
613 ngx_http_spdy_state_detect_settings(ngx_http_spdy_connection_t *sc, | |
614 u_char *pos, u_char *end) | |
615 { | |
616 if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) { | |
617 return ngx_http_spdy_state_save(sc, pos, end, | |
618 ngx_http_spdy_state_detect_settings); | |
619 } | |
620 | |
621 /* | |
622 * Since this is the first frame in a buffer, | |
623 * then it is properly aligned | |
624 */ | |
625 | |
626 if (*(uint32_t *) pos == htonl(ngx_spdy_ctl_frame_head(NGX_SPDY_SETTINGS))) | |
627 { | |
628 sc->length = ngx_spdy_frame_length(htonl(((uint32_t *) pos)[1])); | |
629 | |
630 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, | |
631 "spdy SETTINGS frame received, size: %uz", sc->length); | |
632 | |
633 pos += NGX_SPDY_FRAME_HEADER_SIZE; | |
634 | |
635 return ngx_http_spdy_state_settings(sc, pos, end); | |
636 } | |
637 | |
638 ngx_http_spdy_send_settings(sc); | |
639 | |
640 return ngx_http_spdy_state_head(sc, pos, end); | |
641 } | 614 } |
642 | 615 |
643 | 616 |
644 static u_char * | 617 static u_char * |
645 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos, | 618 ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos, |
1393 | 1366 |
1394 return ngx_http_spdy_state_complete(sc, pos + sc->length, end); | 1367 return ngx_http_spdy_state_complete(sc, pos + sc->length, end); |
1395 } | 1368 } |
1396 | 1369 |
1397 | 1370 |
1371 #if 0 | |
1372 | |
1398 static u_char * | 1373 static u_char * |
1399 ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos, | 1374 ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos, |
1400 u_char *end) | 1375 u_char *end) |
1401 { | 1376 { |
1402 ngx_uint_t v; | |
1403 ngx_http_spdy_srv_conf_t *sscf; | |
1404 | |
1405 if (sc->entries == 0) { | 1377 if (sc->entries == 0) { |
1406 | 1378 |
1407 if (end - pos < NGX_SPDY_SETTINGS_NUM_SIZE) { | 1379 if (end - pos < NGX_SPDY_SETTINGS_NUM_SIZE) { |
1408 return ngx_http_spdy_state_save(sc, pos, end, | 1380 return ngx_http_spdy_state_save(sc, pos, end, |
1409 ngx_http_spdy_state_settings); | 1381 ngx_http_spdy_state_settings); |
1430 ngx_http_spdy_state_settings); | 1402 ngx_http_spdy_state_settings); |
1431 } | 1403 } |
1432 | 1404 |
1433 sc->entries--; | 1405 sc->entries--; |
1434 | 1406 |
1435 if (pos[0] != NGX_SPDY_SETTINGS_MAX_STREAMS) { | 1407 pos += NGX_SPDY_SETTINGS_PAIR_SIZE; |
1436 pos += NGX_SPDY_SETTINGS_PAIR_SIZE; | 1408 sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE; |
1437 sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE; | 1409 } |
1438 continue; | |
1439 } | |
1440 | |
1441 v = ngx_spdy_frame_parse_uint32(pos + NGX_SPDY_SETTINGS_IDF_SIZE); | |
1442 | |
1443 sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, | |
1444 ngx_http_spdy_module); | |
1445 | |
1446 if (v != sscf->concurrent_streams) { | |
1447 ngx_http_spdy_send_settings(sc); | |
1448 } | |
1449 | |
1450 return ngx_http_spdy_state_skip(sc, pos, end); | |
1451 } | |
1452 | |
1453 ngx_http_spdy_send_settings(sc); | |
1454 | 1410 |
1455 return ngx_http_spdy_state_complete(sc, pos, end); | 1411 return ngx_http_spdy_state_complete(sc, pos, end); |
1456 } | 1412 } |
1413 | |
1414 #endif | |
1457 | 1415 |
1458 | 1416 |
1459 static u_char * | 1417 static u_char * |
1460 ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, u_char *pos, | 1418 ngx_http_spdy_state_noop(ngx_http_spdy_connection_t *sc, u_char *pos, |
1461 u_char *end) | 1419 u_char *end) |
1652 NGX_SPDY_SETTINGS_NUM_SIZE | 1610 NGX_SPDY_SETTINGS_NUM_SIZE |
1653 + NGX_SPDY_SETTINGS_PAIR_SIZE); | 1611 + NGX_SPDY_SETTINGS_PAIR_SIZE); |
1654 | 1612 |
1655 p = ngx_spdy_frame_aligned_write_uint32(p, 1); | 1613 p = ngx_spdy_frame_aligned_write_uint32(p, 1); |
1656 p = ngx_spdy_frame_aligned_write_uint32(p, | 1614 p = ngx_spdy_frame_aligned_write_uint32(p, |
1657 NGX_SPDY_SETTINGS_MAX_STREAMS << 24 | 1615 NGX_SPDY_SETTINGS_MAX_STREAMS << 24); |
1658 | NGX_SPDY_SETTINGS_FLAG_PERSIST); | |
1659 | 1616 |
1660 sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, | 1617 sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx, |
1661 ngx_http_spdy_module); | 1618 ngx_http_spdy_module); |
1662 | 1619 |
1663 p = ngx_spdy_frame_aligned_write_uint32(p, sscf->concurrent_streams); | 1620 p = ngx_spdy_frame_aligned_write_uint32(p, sscf->concurrent_streams); |