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