Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(992)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 664803003: Update from chromium a8e7c94b1b79a0948d05a1fcfff53391d22ce37a (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/metrics/stats_counters.h" 9 #include "base/metrics/stats_counters.h"
10 #include "base/third_party/valgrind/memcheck.h" 10 #include "base/third_party/valgrind/memcheck.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // initialized lazily to avoid static initializers. 63 // initialized lazily to avoid static initializers.
64 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; 64 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
65 65
66 // Used to indicate no flags in a SPDY flags field. 66 // Used to indicate no flags in a SPDY flags field.
67 const uint8 kNoFlags = 0; 67 const uint8 kNoFlags = 0;
68 68
69 // Wire sizes of priority payloads. 69 // Wire sizes of priority payloads.
70 const size_t kPriorityDependencyPayloadSize = 4; 70 const size_t kPriorityDependencyPayloadSize = 4;
71 const size_t kPriorityWeightPayloadSize = 1; 71 const size_t kPriorityWeightPayloadSize = 1;
72 72
73 // Wire size of pad length field.
74 const size_t kPadLengthFieldSize = 1;
75
73 } // namespace 76 } // namespace
74 77
75 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1); 78 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1);
76 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 79 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
77 // The size of the control frame buffer. Must be >= the minimum size of the 80 // The size of the control frame buffer. Must be >= the minimum size of the
78 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for 81 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
79 // calculation details. 82 // calculation details.
80 const size_t SpdyFramer::kControlFrameBufferSize = 19; 83 const size_t SpdyFramer::kControlFrameBufferSize = 19;
81 84
82 #ifdef DEBUG_SPDY_STATE_CHANGES 85 #ifdef DEBUG_SPDY_STATE_CHANGES
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 case SPDY_ERROR: 375 case SPDY_ERROR:
373 return "ERROR"; 376 return "ERROR";
374 case SPDY_AUTO_RESET: 377 case SPDY_AUTO_RESET:
375 return "AUTO_RESET"; 378 return "AUTO_RESET";
376 case SPDY_RESET: 379 case SPDY_RESET:
377 return "RESET"; 380 return "RESET";
378 case SPDY_READING_COMMON_HEADER: 381 case SPDY_READING_COMMON_HEADER:
379 return "READING_COMMON_HEADER"; 382 return "READING_COMMON_HEADER";
380 case SPDY_CONTROL_FRAME_PAYLOAD: 383 case SPDY_CONTROL_FRAME_PAYLOAD:
381 return "CONTROL_FRAME_PAYLOAD"; 384 return "CONTROL_FRAME_PAYLOAD";
382 case SPDY_READ_PADDING_LENGTH: 385 case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
383 return "SPDY_READ_PADDING_LENGTH"; 386 return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
384 case SPDY_CONSUME_PADDING: 387 case SPDY_CONSUME_PADDING:
385 return "SPDY_CONSUME_PADDING"; 388 return "SPDY_CONSUME_PADDING";
386 case SPDY_IGNORE_REMAINING_PAYLOAD: 389 case SPDY_IGNORE_REMAINING_PAYLOAD:
387 return "IGNORE_REMAINING_PAYLOAD"; 390 return "IGNORE_REMAINING_PAYLOAD";
388 case SPDY_FORWARD_STREAM_FRAME: 391 case SPDY_FORWARD_STREAM_FRAME:
389 return "FORWARD_STREAM_FRAME"; 392 return "FORWARD_STREAM_FRAME";
390 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 393 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
391 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 394 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
392 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 395 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
393 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 396 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 break; 597 break;
595 } 598 }
596 599
597 case SPDY_CONTROL_FRAME_PAYLOAD: { 600 case SPDY_CONTROL_FRAME_PAYLOAD: {
598 size_t bytes_read = ProcessControlFramePayload(data, len); 601 size_t bytes_read = ProcessControlFramePayload(data, len);
599 len -= bytes_read; 602 len -= bytes_read;
600 data += bytes_read; 603 data += bytes_read;
601 break; 604 break;
602 } 605 }
603 606
604 case SPDY_READ_PADDING_LENGTH: { 607 case SPDY_READ_DATA_FRAME_PADDING_LENGTH: {
605 size_t bytes_read = ProcessFramePaddingLength(data, len); 608 size_t bytes_read = ProcessDataFramePaddingLength(data, len);
606 len -= bytes_read; 609 len -= bytes_read;
607 data += bytes_read; 610 data += bytes_read;
608 break; 611 break;
609 } 612 }
610 613
611 case SPDY_CONSUME_PADDING: { 614 case SPDY_CONSUME_PADDING: {
612 size_t bytes_read = ProcessFramePadding(data, len); 615 size_t bytes_read = ProcessFramePadding(data, len);
613 len -= bytes_read; 616 len -= bytes_read;
614 data += bytes_read; 617 data += bytes_read;
615 break; 618 break;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 valid_data_flags = DATA_FLAG_FIN; 805 valid_data_flags = DATA_FLAG_FIN;
803 } 806 }
804 807
805 if (current_frame_flags_ & ~valid_data_flags) { 808 if (current_frame_flags_ & ~valid_data_flags) {
806 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 809 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
807 } else { 810 } else {
808 visitor_->OnDataFrameHeader(current_frame_stream_id_, 811 visitor_->OnDataFrameHeader(current_frame_stream_id_,
809 remaining_data_length_, 812 remaining_data_length_,
810 current_frame_flags_ & DATA_FLAG_FIN); 813 current_frame_flags_ & DATA_FLAG_FIN);
811 if (remaining_data_length_ > 0) { 814 if (remaining_data_length_ > 0) {
812 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); 815 CHANGE_STATE(SPDY_READ_DATA_FRAME_PADDING_LENGTH);
813 } else { 816 } else {
814 // Empty data frame. 817 // Empty data frame.
815 if (current_frame_flags_ & DATA_FLAG_FIN) { 818 if (current_frame_flags_ & DATA_FLAG_FIN) {
816 visitor_->OnStreamFrameData( 819 visitor_->OnStreamFrameData(
817 current_frame_stream_id_, NULL, 0, true); 820 current_frame_stream_id_, NULL, 0, true);
818 } 821 }
819 CHANGE_STATE(SPDY_AUTO_RESET); 822 CHANGE_STATE(SPDY_AUTO_RESET);
820 } 823 }
821 } 824 }
822 } else { 825 } else {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 break; 1079 break;
1077 case SYN_REPLY: 1080 case SYN_REPLY:
1078 syn_frame_processed_ = true; 1081 syn_frame_processed_ = true;
1079 frame_size_without_variable_data = GetSynReplyMinimumSize(); 1082 frame_size_without_variable_data = GetSynReplyMinimumSize();
1080 break; 1083 break;
1081 case SETTINGS: 1084 case SETTINGS:
1082 frame_size_without_variable_data = GetSettingsMinimumSize(); 1085 frame_size_without_variable_data = GetSettingsMinimumSize();
1083 break; 1086 break;
1084 case HEADERS: 1087 case HEADERS:
1085 frame_size_without_variable_data = GetHeadersMinimumSize(); 1088 frame_size_without_variable_data = GetHeadersMinimumSize();
1086 if (protocol_version() > SPDY3 && 1089 if (protocol_version() > SPDY3) {
1087 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { 1090 if (current_frame_flags_ & HEADERS_FLAG_PADDED) {
1091 frame_size_without_variable_data += kPadLengthFieldSize;
1092 }
1093 if (current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
1088 frame_size_without_variable_data += 1094 frame_size_without_variable_data +=
1089 kPriorityDependencyPayloadSize + 1095 kPriorityDependencyPayloadSize +
1090 kPriorityWeightPayloadSize; 1096 kPriorityWeightPayloadSize;
1097 }
1091 } 1098 }
1092 break; 1099 break;
1093 case PUSH_PROMISE: 1100 case PUSH_PROMISE:
1094 frame_size_without_variable_data = GetPushPromiseMinimumSize(); 1101 frame_size_without_variable_data = GetPushPromiseMinimumSize();
1102 if (protocol_version() > SPDY3 &&
1103 current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
1104 frame_size_without_variable_data += kPadLengthFieldSize;
1105 }
1095 break; 1106 break;
1096 case CONTINUATION: 1107 case CONTINUATION:
1097 frame_size_without_variable_data = GetContinuationMinimumSize(); 1108 frame_size_without_variable_data = GetContinuationMinimumSize();
1098 break; 1109 break;
1099 default: 1110 default:
1100 frame_size_without_variable_data = -1; 1111 frame_size_without_variable_data = -1;
1101 break; 1112 break;
1102 } 1113 }
1103 1114
1104 if ((frame_size_without_variable_data == -1) && 1115 if ((frame_size_without_variable_data == -1) &&
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 if (protocol_version() <= SPDY2) { 1461 if (protocol_version() <= SPDY2) {
1451 // SPDY 2 had two unused bytes here. Seek past them. 1462 // SPDY 2 had two unused bytes here. Seek past them.
1452 reader.Seek(2); 1463 reader.Seek(2);
1453 } 1464 }
1454 if (protocol_version() > SPDY3 && 1465 if (protocol_version() > SPDY3 &&
1455 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && 1466 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
1456 current_frame_type_ == HEADERS) { 1467 current_frame_type_ == HEADERS) {
1457 expect_continuation_ = current_frame_stream_id_; 1468 expect_continuation_ = current_frame_stream_id_;
1458 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; 1469 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
1459 } 1470 }
1471 if (protocol_version() > SPDY3 &&
1472 current_frame_flags_ & HEADERS_FLAG_PADDED) {
1473 uint8 pad_payload_len = 0;
1474 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1475 successful_read = reader.ReadUInt8(&pad_payload_len);
1476 DCHECK(successful_read);
1477 remaining_padding_payload_length_ = pad_payload_len;
1478 }
1460 const bool has_priority = 1479 const bool has_priority =
1461 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; 1480 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
1462 uint32 priority = 0; 1481 uint32 priority = 0;
1463 if (protocol_version() > SPDY3 && has_priority) { 1482 if (protocol_version() > SPDY3 && has_priority) {
1464 // TODO(jgraettinger): Process dependency rather than ignoring it. 1483 // TODO(jgraettinger): Process dependency rather than ignoring it.
1465 reader.Seek(kPriorityDependencyPayloadSize); 1484 reader.Seek(kPriorityDependencyPayloadSize);
1466 uint8 weight = 0; 1485 uint8 weight = 0;
1467 successful_read = reader.ReadUInt8(&weight); 1486 successful_read = reader.ReadUInt8(&weight);
1468 if (successful_read) { 1487 if (successful_read) {
1469 priority = MapWeightToPriority(weight); 1488 priority = MapWeightToPriority(weight);
(...skipping 25 matching lines...) Expand all
1495 priority, 1514 priority,
1496 current_frame_flags_ & CONTROL_FLAG_FIN, 1515 current_frame_flags_ & CONTROL_FLAG_FIN,
1497 false); // unidirectional 1516 false); // unidirectional
1498 } else { 1517 } else {
1499 visitor_->OnHeaders( 1518 visitor_->OnHeaders(
1500 current_frame_stream_id_, 1519 current_frame_stream_id_,
1501 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1520 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1502 expect_continuation_ == 0); 1521 expect_continuation_ == 0);
1503 } 1522 }
1504 } 1523 }
1505 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); 1524 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1506 break; 1525 break;
1507 case PUSH_PROMISE: 1526 case PUSH_PROMISE:
1508 { 1527 {
1509 DCHECK_LT(SPDY3, protocol_version()); 1528 DCHECK_LT(SPDY3, protocol_version());
1510 if (current_frame_stream_id_ == 0) { 1529 if (current_frame_stream_id_ == 0) {
1511 set_error(SPDY_INVALID_CONTROL_FRAME); 1530 set_error(SPDY_INVALID_CONTROL_FRAME);
1512 break; 1531 break;
1513 } 1532 }
1533 bool successful_read = true;
1534 if (protocol_version() > SPDY3 &&
1535 current_frame_flags_ & PUSH_PROMISE_FLAG_PADDED) {
1536 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1537 uint8 pad_payload_len = 0;
1538 successful_read = reader.ReadUInt8(&pad_payload_len);
1539 DCHECK(successful_read);
1540 remaining_padding_payload_length_ = pad_payload_len;
1541 }
1542 }
1543 {
1514 SpdyStreamId promised_stream_id = kInvalidStream; 1544 SpdyStreamId promised_stream_id = kInvalidStream;
1515 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1545 bool successful_read = reader.ReadUInt31(&promised_stream_id);
1516 DCHECK(successful_read); 1546 DCHECK(successful_read);
1517 DCHECK(reader.IsDoneReading()); 1547 DCHECK(reader.IsDoneReading());
1518 if (promised_stream_id == 0) { 1548 if (promised_stream_id == 0) {
1519 set_error(SPDY_INVALID_CONTROL_FRAME); 1549 set_error(SPDY_INVALID_CONTROL_FRAME);
1520 break; 1550 break;
1521 } 1551 }
1522 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) { 1552 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) {
1523 expect_continuation_ = current_frame_stream_id_; 1553 expect_continuation_ = current_frame_stream_id_;
1524 } 1554 }
1525 if (debug_visitor_) { 1555 if (debug_visitor_) {
1526 debug_visitor_->OnReceiveCompressedFrame( 1556 debug_visitor_->OnReceiveCompressedFrame(
1527 current_frame_stream_id_, 1557 current_frame_stream_id_,
1528 current_frame_type_, 1558 current_frame_type_,
1529 current_frame_length_); 1559 current_frame_length_);
1530 } 1560 }
1531 visitor_->OnPushPromise(current_frame_stream_id_, 1561 visitor_->OnPushPromise(current_frame_stream_id_,
1532 promised_stream_id, 1562 promised_stream_id,
1533 (current_frame_flags_ & 1563 (current_frame_flags_ &
1534 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); 1564 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
1535 } 1565 }
1536 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); 1566 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1537 break; 1567 break;
1538 case CONTINUATION: 1568 case CONTINUATION:
1539 { 1569 {
1540 // Check to make sure the stream id of the current frame is 1570 // Check to make sure the stream id of the current frame is
1541 // the same as that of the preceding frame. 1571 // the same as that of the preceding frame.
1542 // If we're at this point we should already know that 1572 // If we're at this point we should already know that
1543 // expect_continuation_ != 0, so this doubles as a check 1573 // expect_continuation_ != 0, so this doubles as a check
1544 // that current_frame_stream_id != 0. 1574 // that current_frame_stream_id != 0.
1545 if (current_frame_stream_id_ != expect_continuation_) { 1575 if (current_frame_stream_id_ != expect_continuation_) {
1546 set_error(SPDY_INVALID_CONTROL_FRAME); 1576 set_error(SPDY_INVALID_CONTROL_FRAME);
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 StringPiece(altsvc_scratch_.host.get(), 2143 StringPiece(altsvc_scratch_.host.get(),
2114 altsvc_scratch_.host_len), 2144 altsvc_scratch_.host_len),
2115 StringPiece(altsvc_scratch_.origin.get(), 2145 StringPiece(altsvc_scratch_.origin.get(),
2116 altsvc_scratch_.origin_len)); 2146 altsvc_scratch_.origin_len));
2117 CHANGE_STATE(SPDY_AUTO_RESET); 2147 CHANGE_STATE(SPDY_AUTO_RESET);
2118 } 2148 }
2119 2149
2120 return processed_bytes; 2150 return processed_bytes;
2121 } 2151 }
2122 2152
2123 // TODO(raullenchai): ProcessFramePaddingLength should be able to deal with 2153 size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) {
2124 // HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051). 2154 DCHECK_EQ(SPDY_READ_DATA_FRAME_PADDING_LENGTH, state_);
2125 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { 2155 DCHECK_EQ(0u, remaining_padding_payload_length_);
2126 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); 2156 DCHECK_EQ(DATA, current_frame_type_);
2127 DCHECK_EQ(remaining_padding_payload_length_, 0u);
2128 2157
2129 size_t original_len = len; 2158 size_t original_len = len;
2130 if (current_frame_flags_ & DATA_FLAG_PADDED) { 2159 if (current_frame_flags_ & DATA_FLAG_PADDED) {
2131 if (len != 0) { 2160 if (len != 0) {
2132 if (remaining_data_length_ < 1) { 2161 if (remaining_data_length_ < 1) {
2133 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 2162 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
2134 return 0; 2163 return 0;
2135 } 2164 }
2136 2165
2137 remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data); 2166 remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data);
2138 ++data; 2167 ++data;
2139 --len; 2168 --len;
2140 --remaining_data_length_; 2169 --remaining_data_length_;
2141 } else { 2170 } else {
2142 // We don't have the data available for parsing the pad length field. Keep 2171 // We don't have the data available for parsing the pad length field. Keep
2143 // waiting. 2172 // waiting.
2144 return 0; 2173 return 0;
2145 } 2174 }
2146 } 2175 }
2147 2176
2148 if (remaining_padding_payload_length_ > remaining_data_length_) { 2177 if (remaining_padding_payload_length_ > remaining_data_length_) {
2149 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 2178 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
2150 return 0; 2179 return 0;
2151 } 2180 }
2152 if (current_frame_type_ == DATA) { 2181 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
2153 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
2154 } else {
2155 DCHECK(current_frame_type_ == HEADERS ||
2156 current_frame_type_ == PUSH_PROMISE ||
2157 current_frame_type_ == SYN_STREAM ||
2158 current_frame_type_ == SYN_REPLY)
2159 << current_frame_type_;
2160 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
2161 }
2162 return original_len - len; 2182 return original_len - len;
2163 } 2183 }
2164 2184
2165 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { 2185 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
2166 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); 2186 DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
2167 2187
2168 size_t original_len = len; 2188 size_t original_len = len;
2169 if (remaining_padding_payload_length_ > 0) { 2189 if (remaining_padding_payload_length_ > 0) {
2170 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); 2190 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
2171 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); 2191 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2599 uint8 flags = 0; 2619 uint8 flags = 0;
2600 if (headers.fin()) { 2620 if (headers.fin()) {
2601 flags |= CONTROL_FLAG_FIN; 2621 flags |= CONTROL_FLAG_FIN;
2602 } 2622 }
2603 if (protocol_version() > SPDY3) { 2623 if (protocol_version() > SPDY3) {
2604 // This will get overwritten if we overflow into a CONTINUATION frame. 2624 // This will get overwritten if we overflow into a CONTINUATION frame.
2605 flags |= HEADERS_FLAG_END_HEADERS; 2625 flags |= HEADERS_FLAG_END_HEADERS;
2606 if (headers.has_priority()) { 2626 if (headers.has_priority()) {
2607 flags |= HEADERS_FLAG_PRIORITY; 2627 flags |= HEADERS_FLAG_PRIORITY;
2608 } 2628 }
2629 if (headers.padded()) {
2630 flags |= HEADERS_FLAG_PADDED;
2631 }
2609 } 2632 }
2610 2633
2611 // The size of this frame, including variable-length name-value block. 2634 // The size of this frame, including padding (if there is any)
2635 // and variable-length name-value block.
2612 size_t size = GetHeadersMinimumSize(); 2636 size_t size = GetHeadersMinimumSize();
2613 2637
2638 if (protocol_version() > SPDY3 && headers.padded()) {
2639 size += kPadLengthFieldSize;
2640 size += headers.padding_payload_len();
2641 }
2642
2614 uint32 priority = headers.priority(); 2643 uint32 priority = headers.priority();
2615 if (headers.has_priority()) { 2644 if (headers.has_priority()) {
2616 if (priority > GetLowestPriority()) { 2645 if (priority > GetLowestPriority()) {
2617 DLOG(DFATAL) << "Priority out-of-bounds."; 2646 DLOG(DFATAL) << "Priority out-of-bounds.";
2618 priority = GetLowestPriority(); 2647 priority = GetLowestPriority();
2619 } 2648 }
2620 size += 5; 2649 size += 5;
2621 } 2650 }
2622 2651
2623 string hpack_encoding; 2652 string hpack_encoding;
(...skipping 24 matching lines...) Expand all
2648 HEADERS, 2677 HEADERS,
2649 flags, 2678 flags,
2650 headers.stream_id()); 2679 headers.stream_id());
2651 } 2680 }
2652 if (protocol_version() <= SPDY2) { 2681 if (protocol_version() <= SPDY2) {
2653 builder.WriteUInt16(0); // Unused. 2682 builder.WriteUInt16(0); // Unused.
2654 } 2683 }
2655 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 2684 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2656 2685
2657 if (protocol_version() > SPDY3) { 2686 if (protocol_version() > SPDY3) {
2687 int padding_payload_len = 0;
2688 if (headers.padded()) {
2689 builder.WriteUInt8(headers.padding_payload_len());
2690 padding_payload_len = headers.padding_payload_len();
2691 }
2658 if (headers.has_priority()) { 2692 if (headers.has_priority()) {
2659 // TODO(jgraettinger): Plumb priorities and stream dependencies. 2693 // TODO(jgraettinger): Plumb priorities and stream dependencies.
2660 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. 2694 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID.
2661 builder.WriteUInt8(MapPriorityToWeight(priority)); 2695 builder.WriteUInt8(MapPriorityToWeight(priority));
2662 } 2696 }
2663 WritePayloadWithContinuation(&builder, 2697 WritePayloadWithContinuation(&builder,
2664 hpack_encoding, 2698 hpack_encoding,
2665 headers.stream_id(), 2699 headers.stream_id(),
2666 HEADERS); 2700 HEADERS,
2701 padding_payload_len);
2667 } else { 2702 } else {
2668 SerializeNameValueBlock(&builder, headers); 2703 SerializeNameValueBlock(&builder, headers);
2669 } 2704 }
2670 2705
2671 if (debug_visitor_) { 2706 if (debug_visitor_) {
2672 // SPDY4 uses HPACK for header compression. However, continue to 2707 // SPDY4 uses HPACK for header compression. However, continue to
2673 // use GetSerializedLength() for an apples-to-apples comparision of 2708 // use GetSerializedLength() for an apples-to-apples comparision of
2674 // compression performance between HPACK and SPDY w/ deflate. 2709 // compression performance between HPACK and SPDY w/ deflate.
2675 const size_t payload_len = 2710 const size_t payload_len =
2676 GetSerializedLength(protocol_version(), 2711 GetSerializedLength(protocol_version(),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2710 2745
2711 SpdyFrame* SpdyFramer::SerializePushPromise( 2746 SpdyFrame* SpdyFramer::SerializePushPromise(
2712 const SpdyPushPromiseIR& push_promise) { 2747 const SpdyPushPromiseIR& push_promise) {
2713 DCHECK_LT(SPDY3, protocol_version()); 2748 DCHECK_LT(SPDY3, protocol_version());
2714 uint8 flags = 0; 2749 uint8 flags = 0;
2715 // This will get overwritten if we overflow into a CONTINUATION frame. 2750 // This will get overwritten if we overflow into a CONTINUATION frame.
2716 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2751 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2717 // The size of this frame, including variable-length name-value block. 2752 // The size of this frame, including variable-length name-value block.
2718 size_t size = GetPushPromiseMinimumSize(); 2753 size_t size = GetPushPromiseMinimumSize();
2719 2754
2755 if (push_promise.padded()) {
2756 flags |= PUSH_PROMISE_FLAG_PADDED;
2757 size += kPadLengthFieldSize;
2758 size += push_promise.padding_payload_len();
2759 }
2760
2720 string hpack_encoding; 2761 string hpack_encoding;
2721 if (enable_compression_) { 2762 if (enable_compression_) {
2722 GetHpackEncoder()->EncodeHeaderSet( 2763 GetHpackEncoder()->EncodeHeaderSet(
2723 push_promise.name_value_block(), &hpack_encoding); 2764 push_promise.name_value_block(), &hpack_encoding);
2724 } else { 2765 } else {
2725 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( 2766 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
2726 push_promise.name_value_block(), &hpack_encoding); 2767 push_promise.name_value_block(), &hpack_encoding);
2727 } 2768 }
2728 size += hpack_encoding.size(); 2769 size += hpack_encoding.size();
2729 if (size > GetHeaderFragmentMaxSize()) { 2770 if (size > GetHeaderFragmentMaxSize()) {
2730 size += GetNumberRequiredContinuationFrames(size) * 2771 size += GetNumberRequiredContinuationFrames(size) *
2731 GetContinuationMinimumSize(); 2772 GetContinuationMinimumSize();
2732 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2773 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2733 } 2774 }
2734 2775
2735 SpdyFrameBuilder builder(size, protocol_version()); 2776 SpdyFrameBuilder builder(size, protocol_version());
2736 builder.BeginNewFrame(*this, 2777 builder.BeginNewFrame(*this,
2737 PUSH_PROMISE, 2778 PUSH_PROMISE,
2738 flags, 2779 flags,
2739 push_promise.stream_id()); 2780 push_promise.stream_id());
2740 builder.WriteUInt32(push_promise.promised_stream_id()); 2781 int padding_payload_len = 0;
2741 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); 2782 if (push_promise.padded()) {
2783 builder.WriteUInt8(push_promise.padding_payload_len());
2784 builder.WriteUInt32(push_promise.promised_stream_id());
2785 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize,
2786 builder.length());
2787
2788 padding_payload_len = push_promise.padding_payload_len();
2789 } else {
2790 builder.WriteUInt32(push_promise.promised_stream_id());
2791 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
2792 }
2742 2793
2743 WritePayloadWithContinuation(&builder, 2794 WritePayloadWithContinuation(&builder,
2744 hpack_encoding, 2795 hpack_encoding,
2745 push_promise.stream_id(), 2796 push_promise.stream_id(),
2746 PUSH_PROMISE); 2797 PUSH_PROMISE,
2798 padding_payload_len);
2747 2799
2748 if (debug_visitor_) { 2800 if (debug_visitor_) {
2749 // SPDY4 uses HPACK for header compression. However, continue to 2801 // SPDY4 uses HPACK for header compression. However, continue to
2750 // use GetSerializedLength() for an apples-to-apples comparision of 2802 // use GetSerializedLength() for an apples-to-apples comparision of
2751 // compression performance between HPACK and SPDY w/ deflate. 2803 // compression performance between HPACK and SPDY w/ deflate.
2752 const size_t payload_len = 2804 const size_t payload_len =
2753 GetSerializedLength(protocol_version(), 2805 GetSerializedLength(protocol_version(),
2754 &(push_promise.name_value_block())); 2806 &(push_promise.name_value_block()));
2755 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), 2807 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
2756 PUSH_PROMISE, 2808 PUSH_PROMISE,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2916 const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize(); 2968 const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
2917 DCHECK_GT(protocol_version(), SPDY3); 2969 DCHECK_GT(protocol_version(), SPDY3);
2918 DCHECK_GT(size, kMaxControlFrameSize); 2970 DCHECK_GT(size, kMaxControlFrameSize);
2919 size_t overflow = size - kMaxControlFrameSize; 2971 size_t overflow = size - kMaxControlFrameSize;
2920 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1; 2972 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
2921 } 2973 }
2922 2974
2923 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, 2975 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2924 const string& hpack_encoding, 2976 const string& hpack_encoding,
2925 SpdyStreamId stream_id, 2977 SpdyStreamId stream_id,
2926 SpdyFrameType type) { 2978 SpdyFrameType type,
2979 int padding_payload_len) {
2927 const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize(); 2980 const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
2928 2981
2929 // In addition to the prefix, fixed_field_size includes the size of
2930 // any fields that come before the variable-length name/value block.
2931 size_t fixed_field_size = 0;
2932 uint8 end_flag = 0; 2982 uint8 end_flag = 0;
2933 uint8 flags = 0; 2983 uint8 flags = 0;
2934 if (type == HEADERS) { 2984 if (type == HEADERS) {
2935 fixed_field_size = GetHeadersMinimumSize();
2936 end_flag = HEADERS_FLAG_END_HEADERS; 2985 end_flag = HEADERS_FLAG_END_HEADERS;
2937 } else if (type == PUSH_PROMISE) { 2986 } else if (type == PUSH_PROMISE) {
2938 fixed_field_size = GetPushPromiseMinimumSize();
2939 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2987 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2940 } else { 2988 } else {
2941 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " 2989 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
2942 << FrameTypeToString(type); 2990 << FrameTypeToString(type);
2943 } 2991 }
2944 2992
2945 // Write as much of the payload as possible into the initial frame. 2993 // Write all the padding payload and as much of the data payload as possible
2946 size_t bytes_remaining = hpack_encoding.size() - 2994 // into the initial frame.
2947 std::min(hpack_encoding.size(), 2995 size_t bytes_remaining = 0;
2948 kMaxControlFrameSize - fixed_field_size); 2996 bytes_remaining = hpack_encoding.size() -
2997 std::min(hpack_encoding.size(),
2998 kMaxControlFrameSize - builder->length() -
2999 padding_payload_len);
2949 builder->WriteBytes(&hpack_encoding[0], 3000 builder->WriteBytes(&hpack_encoding[0],
2950 hpack_encoding.size() - bytes_remaining); 3001 hpack_encoding.size() - bytes_remaining);
2951 3002 if (padding_payload_len > 0) {
3003 string padding = string(padding_payload_len, 0);
3004 builder->WriteBytes(padding.data(), padding.length());
3005 }
2952 if (bytes_remaining > 0) { 3006 if (bytes_remaining > 0) {
2953 builder->OverwriteLength(*this, 3007 builder->OverwriteLength(*this,
2954 kMaxControlFrameSize - GetControlFrameHeaderSize()); 3008 kMaxControlFrameSize - GetControlFrameHeaderSize());
2955 } 3009 }
2956 3010
2957 // Tack on CONTINUATION frames for the overflow. 3011 // Tack on CONTINUATION frames for the overflow.
2958 while (bytes_remaining > 0) { 3012 while (bytes_remaining > 0) {
2959 size_t bytes_to_write = std::min(bytes_remaining, 3013 size_t bytes_to_write = std::min(bytes_remaining,
2960 kMaxControlFrameSize - 3014 kMaxControlFrameSize -
2961 GetContinuationMinimumSize()); 3015 GetContinuationMinimumSize());
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
3240 builder->Seek(compressed_size); 3294 builder->Seek(compressed_size);
3241 builder->RewriteLength(*this); 3295 builder->RewriteLength(*this);
3242 3296
3243 pre_compress_bytes.Add(uncompressed_len); 3297 pre_compress_bytes.Add(uncompressed_len);
3244 post_compress_bytes.Add(compressed_size); 3298 post_compress_bytes.Add(compressed_size);
3245 3299
3246 compressed_frames.Increment(); 3300 compressed_frames.Increment();
3247 } 3301 }
3248 3302
3249 } // namespace net 3303 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698