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

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

Issue 290203003: HTTP/2 framer support for reading headers with padding, and for segments. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 911 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 size_t min_size = GetHeadersMinimumSize(); 922 size_t min_size = GetHeadersMinimumSize();
923 if (protocol_version() > SPDY3 && 923 if (protocol_version() > SPDY3 &&
924 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { 924 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
925 min_size += 4; 925 min_size += 4;
926 } 926 }
927 if (current_frame_length_ < min_size) { 927 if (current_frame_length_ < min_size) {
928 set_error(SPDY_INVALID_CONTROL_FRAME); 928 set_error(SPDY_INVALID_CONTROL_FRAME);
929 } else if (protocol_version() <= SPDY3 && 929 } else if (protocol_version() <= SPDY3 &&
930 current_frame_flags_ & ~CONTROL_FLAG_FIN) { 930 current_frame_flags_ & ~CONTROL_FLAG_FIN) {
931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
932 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 932 } else if (protocol_version() > SPDY3 &&
933 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | 933 current_frame_flags_ &
934 HEADERS_FLAG_END_HEADERS)) { 934 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
935 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT |
936 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
935 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 937 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
936 } 938 }
937 } 939 }
938 break; 940 break;
939 case WINDOW_UPDATE: 941 case WINDOW_UPDATE:
940 if (current_frame_length_ != GetWindowUpdateSize()) { 942 if (current_frame_length_ != GetWindowUpdateSize()) {
941 set_error(SPDY_INVALID_CONTROL_FRAME); 943 set_error(SPDY_INVALID_CONTROL_FRAME);
942 } else if (current_frame_flags_ != 0) { 944 } else if (current_frame_flags_ != 0) {
943 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 945 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
944 } 946 }
945 break; 947 break;
946 case BLOCKED: 948 case BLOCKED:
947 if (current_frame_length_ != GetBlockedSize() || 949 if (current_frame_length_ != GetBlockedSize() ||
948 protocol_version() <= SPDY3) { 950 protocol_version() <= SPDY3) {
949 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. 951 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4.
950 set_error(SPDY_INVALID_CONTROL_FRAME); 952 set_error(SPDY_INVALID_CONTROL_FRAME);
951 } else if (current_frame_flags_ != 0) { 953 } else if (current_frame_flags_ != 0) {
952 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 954 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
953 } 955 }
954 break; 956 break;
955 case PUSH_PROMISE: 957 case PUSH_PROMISE:
956 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 958 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
957 set_error(SPDY_INVALID_CONTROL_FRAME); 959 set_error(SPDY_INVALID_CONTROL_FRAME);
958 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { 960 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
959 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 961 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
960 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 962 } else if (protocol_version() > SPDY3 &&
961 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { 963 current_frame_flags_ &
964 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE |
965 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
962 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 966 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
963 } 967 }
964 break; 968 break;
965 case CONTINUATION: 969 case CONTINUATION:
966 if (current_frame_length_ < GetContinuationMinimumSize() || 970 if (current_frame_length_ < GetContinuationMinimumSize() ||
967 protocol_version() <= SPDY3) { 971 protocol_version() <= SPDY3) {
968 set_error(SPDY_INVALID_CONTROL_FRAME); 972 set_error(SPDY_INVALID_CONTROL_FRAME);
969 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { 973 } else if (current_frame_flags_ &
974 ~(HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PAD_LOW |
975 HEADERS_FLAG_PAD_HIGH)) {
970 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
971 } 977 }
972 break; 978 break;
973 case ALTSVC: 979 case ALTSVC:
974 if (current_frame_length_ <= GetAltSvcMinimumSize()) { 980 if (current_frame_length_ <= GetAltSvcMinimumSize()) {
975 set_error(SPDY_INVALID_CONTROL_FRAME); 981 set_error(SPDY_INVALID_CONTROL_FRAME);
976 } else if (current_frame_flags_ != 0) { 982 } else if (current_frame_flags_ != 0) {
977 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 983 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
978 } 984 }
979 break; 985 break;
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 priority, 1443 priority,
1438 current_frame_flags_ & CONTROL_FLAG_FIN, 1444 current_frame_flags_ & CONTROL_FLAG_FIN,
1439 false); // unidirectional 1445 false); // unidirectional
1440 } else { 1446 } else {
1441 visitor_->OnHeaders( 1447 visitor_->OnHeaders(
1442 current_frame_stream_id_, 1448 current_frame_stream_id_,
1443 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1449 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1444 expect_continuation_ == 0); 1450 expect_continuation_ == 0);
1445 } 1451 }
1446 } 1452 }
1447 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1453 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1448 break; 1454 break;
1449 case PUSH_PROMISE: 1455 case PUSH_PROMISE:
1450 { 1456 {
1451 DCHECK_LT(SPDY3, protocol_version()); 1457 DCHECK_LT(SPDY3, protocol_version());
1452 if (current_frame_stream_id_ == 0) { 1458 if (current_frame_stream_id_ == 0) {
1453 set_error(SPDY_INVALID_CONTROL_FRAME); 1459 set_error(SPDY_INVALID_CONTROL_FRAME);
1454 break; 1460 break;
1455 } 1461 }
1456 SpdyStreamId promised_stream_id = kInvalidStream; 1462 SpdyStreamId promised_stream_id = kInvalidStream;
1457 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1463 bool successful_read = reader.ReadUInt31(&promised_stream_id);
(...skipping 10 matching lines...) Expand all
1468 debug_visitor_->OnReceiveCompressedFrame( 1474 debug_visitor_->OnReceiveCompressedFrame(
1469 current_frame_stream_id_, 1475 current_frame_stream_id_,
1470 current_frame_type_, 1476 current_frame_type_,
1471 current_frame_length_); 1477 current_frame_length_);
1472 } 1478 }
1473 visitor_->OnPushPromise(current_frame_stream_id_, 1479 visitor_->OnPushPromise(current_frame_stream_id_,
1474 promised_stream_id, 1480 promised_stream_id,
1475 (current_frame_flags_ & 1481 (current_frame_flags_ &
1476 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0); 1482 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
1477 } 1483 }
1478 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1484 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1479 break; 1485 break;
1480 case CONTINUATION: 1486 case CONTINUATION:
1481 { 1487 {
1482 // Check to make sure the stream id of the current frame is 1488 // Check to make sure the stream id of the current frame is
1483 // the same as that of the preceding frame. 1489 // the same as that of the preceding frame.
1484 // If we're at this point we should already know that 1490 // If we're at this point we should already know that
1485 // expect_continuation_ != 0, so this doubles as a check 1491 // expect_continuation_ != 0, so this doubles as a check
1486 // that current_frame_stream_id != 0. 1492 // that current_frame_stream_id != 0.
1487 if (current_frame_stream_id_ != expect_continuation_) { 1493 if (current_frame_stream_id_ != expect_continuation_) {
1488 set_error(SPDY_INVALID_CONTROL_FRAME); 1494 set_error(SPDY_INVALID_CONTROL_FRAME);
1489 break; 1495 break;
1490 } 1496 }
1491 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { 1497 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) {
1492 expect_continuation_ = 0; 1498 expect_continuation_ = 0;
1493 } 1499 }
1494 if (debug_visitor_) { 1500 if (debug_visitor_) {
1495 debug_visitor_->OnReceiveCompressedFrame( 1501 debug_visitor_->OnReceiveCompressedFrame(
1496 current_frame_stream_id_, 1502 current_frame_stream_id_,
1497 current_frame_type_, 1503 current_frame_type_,
1498 current_frame_length_); 1504 current_frame_length_);
1499 } 1505 }
1500 visitor_->OnContinuation(current_frame_stream_id_, 1506 visitor_->OnContinuation(current_frame_stream_id_,
1501 (current_frame_flags_ & 1507 (current_frame_flags_ &
1502 HEADERS_FLAG_END_HEADERS) != 0); 1508 HEADERS_FLAG_END_HEADERS) != 0);
1503 } 1509 }
1504 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1510 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
1505 break; 1511 break;
1506 default: 1512 default:
1507 DCHECK(false); 1513 DCHECK(false);
1508 } 1514 }
1509 } 1515 }
1510 return original_len - len; 1516 return original_len - len;
1511 } 1517 }
1512 1518
1513 // Does not buffer the control payload. Instead, either passes directly to the 1519 // Does not buffer the control payload. Instead, either passes directly to the
1514 // visitor or decompresses and then passes directly to the visitor, via 1520 // visitor or decompresses and then passes directly to the visitor, via
1515 // IncrementallyDeliverControlFrameHeaderData() or 1521 // IncrementallyDeliverControlFrameHeaderData() or
1516 // IncrementallyDecompressControlFrameHeaderData() respectively. 1522 // IncrementallyDecompressControlFrameHeaderData() respectively.
1517 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, 1523 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
1518 size_t data_len, 1524 size_t data_len,
1519 bool is_hpack_header_block) { 1525 bool is_hpack_header_block) {
1520 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_); 1526 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
1521 1527
1522 bool processed_successfully = true; 1528 bool processed_successfully = true;
1523 if (current_frame_type_ != SYN_STREAM && 1529 if (current_frame_type_ != SYN_STREAM &&
1524 current_frame_type_ != SYN_REPLY && 1530 current_frame_type_ != SYN_REPLY &&
1525 current_frame_type_ != HEADERS && 1531 current_frame_type_ != HEADERS &&
1526 current_frame_type_ != PUSH_PROMISE && 1532 current_frame_type_ != PUSH_PROMISE &&
1527 current_frame_type_ != CONTINUATION) { 1533 current_frame_type_ != CONTINUATION) {
1528 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; 1534 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
1529 } 1535 }
1530 size_t process_bytes = std::min(data_len, remaining_data_length_); 1536 size_t process_bytes = std::min(
1537 data_len, remaining_data_length_ - remaining_padding_payload_length_);
1531 if (is_hpack_header_block) { 1538 if (is_hpack_header_block) {
1532 if (!GetHpackDecoder()->HandleControlFrameHeadersData( 1539 if (!GetHpackDecoder()->HandleControlFrameHeadersData(
1533 current_frame_stream_id_, data, process_bytes)) { 1540 current_frame_stream_id_, data, process_bytes)) {
1534 // TODO(jgraettinger): Finer-grained HPACK error codes. 1541 // TODO(jgraettinger): Finer-grained HPACK error codes.
1535 set_error(SPDY_DECOMPRESS_FAILURE); 1542 set_error(SPDY_DECOMPRESS_FAILURE);
1536 processed_successfully = false; 1543 processed_successfully = false;
1537 } 1544 }
1538 } else if (process_bytes > 0) { 1545 } else if (process_bytes > 0) {
1539 if (enable_compression_ && protocol_version() <= SPDY3) { 1546 if (enable_compression_ && protocol_version() <= SPDY3) {
1540 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1547 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1541 current_frame_stream_id_, data, process_bytes); 1548 current_frame_stream_id_, data, process_bytes);
1542 } else { 1549 } else {
1543 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1550 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1544 current_frame_stream_id_, data, process_bytes); 1551 current_frame_stream_id_, data, process_bytes);
1545 } 1552 }
1546 } 1553 }
1547 remaining_data_length_ -= process_bytes; 1554 remaining_data_length_ -= process_bytes;
1548 1555
1549 // Handle the case that there is no futher data in this frame. 1556 // Handle the case that there is no futher data in this frame.
1550 if (remaining_data_length_ == 0 && processed_successfully) { 1557 if (remaining_data_length_ == remaining_padding_payload_length_ &&
1558 processed_successfully) {
1551 if (expect_continuation_ == 0) { 1559 if (expect_continuation_ == 0) {
1552 if (is_hpack_header_block) { 1560 if (is_hpack_header_block) {
1553 if (!GetHpackDecoder()->HandleControlFrameHeadersComplete( 1561 if (!GetHpackDecoder()->HandleControlFrameHeadersComplete(
1554 current_frame_stream_id_)) { 1562 current_frame_stream_id_)) {
1555 set_error(SPDY_DECOMPRESS_FAILURE); 1563 set_error(SPDY_DECOMPRESS_FAILURE);
1556 processed_successfully = false; 1564 processed_successfully = false;
1557 } else { 1565 } else {
1558 // TODO(jgraettinger): To be removed with migration to 1566 // TODO(jgraettinger): To be removed with migration to
1559 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3 1567 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
1560 // block, delivered via reentrant call to 1568 // block, delivered via reentrant call to
1561 // ProcessControlFrameHeaderBlock(). 1569 // ProcessControlFrameHeaderBlock().
1562 DeliverHpackBlockAsSpdy3Block(); 1570 DeliverHpackBlockAsSpdy3Block();
1563 return process_bytes; 1571 return process_bytes;
1564 } 1572 }
1565 } else { 1573 } else {
1566 // The complete header block has been delivered. We send a zero-length 1574 // The complete header block has been delivered. We send a zero-length
1567 // OnControlFrameHeaderData() to indicate this. 1575 // OnControlFrameHeaderData() to indicate this.
1568 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0); 1576 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
1569 } 1577 }
1570 // If this is a FIN, tell the caller.
1571 if ((current_frame_flags_ & CONTROL_FLAG_FIN) || end_stream_when_done_) {
1572 end_stream_when_done_ = false;
1573 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1574 }
1575 } 1578 }
1576 if (processed_successfully) 1579 if (processed_successfully) {
1577 CHANGE_STATE(SPDY_AUTO_RESET); 1580 CHANGE_STATE(SPDY_CONSUME_PADDING);
1581 }
1578 } 1582 }
1579 1583
1580 // Handle error. 1584 // Handle error.
1581 if (!processed_successfully) { 1585 if (!processed_successfully) {
1582 return data_len; 1586 return data_len;
1583 } 1587 }
1584 1588
1585 // Return amount processed. 1589 // Return amount processed.
1586 return process_bytes; 1590 return process_bytes;
1587 } 1591 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 if (remaining_data_length_ == 0) { 1641 if (remaining_data_length_ == 0) {
1638 visitor_->OnSettingsEnd(); 1642 visitor_->OnSettingsEnd();
1639 CHANGE_STATE(SPDY_AUTO_RESET); 1643 CHANGE_STATE(SPDY_AUTO_RESET);
1640 } 1644 }
1641 1645
1642 return processed_bytes; 1646 return processed_bytes;
1643 } 1647 }
1644 1648
1645 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { 1649 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1646 DCHECK_LT(SPDY3, protocol_version()); 1650 DCHECK_LT(SPDY3, protocol_version());
1647 DCHECK_EQ(0u, remaining_data_length_); 1651 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
1648 1652
1649 const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block(); 1653 const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block();
1650 if (block.empty()) { 1654 if (block.empty()) {
1651 // Special-case this to make tests happy. 1655 // Special-case this to make tests happy.
1652 ProcessControlFrameHeaderBlock(NULL, 0, false); 1656 ProcessControlFrameHeaderBlock(NULL, 0, false);
1653 return; 1657 return;
1654 } 1658 }
1655 SpdyFrameBuilder builder( 1659 SpdyFrameBuilder builder(
1656 GetSerializedLength(protocol_version(), &block), 1660 GetSerializedLength(protocol_version(), &block),
1657 SPDY3); 1661 SPDY3);
1658 1662
1659 SerializeNameValueBlockWithoutCompression(&builder, block); 1663 SerializeNameValueBlockWithoutCompression(&builder, block);
1660 scoped_ptr<SpdyFrame> frame(builder.take()); 1664 scoped_ptr<SpdyFrame> frame(builder.take());
1661 1665
1666 // Preserve padding length, and reset it after the re-entrant call.
1667 size_t remaining_padding = remaining_padding_payload_length_;
1668
1669 remaining_padding_payload_length_ = 0;
1662 remaining_data_length_ = frame->size(); 1670 remaining_data_length_ = frame->size();
1671
1663 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); 1672 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
1673
1674 remaining_padding_payload_length_ = remaining_padding;
1675 remaining_data_length_ = remaining_padding;
1664 } 1676 }
1665 1677
1666 bool SpdyFramer::ProcessSetting(const char* data) { 1678 bool SpdyFramer::ProcessSetting(const char* data) {
1667 int id_field; 1679 int id_field;
1668 SpdySettingsIds id; 1680 SpdySettingsIds id;
1669 uint8 flags = 0; 1681 uint8 flags = 0;
1670 uint32 value; 1682 uint32 value;
1671 1683
1672 // Extract fields. 1684 // Extract fields.
1673 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. 1685 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 --len; 2088 --len;
2077 --remaining_padding_length_fields_; 2089 --remaining_padding_length_fields_;
2078 --remaining_data_length_; 2090 --remaining_data_length_;
2079 } 2091 }
2080 2092
2081 if (remaining_padding_length_fields_ == 0) { 2093 if (remaining_padding_length_fields_ == 0) {
2082 if (remaining_padding_payload_length_ > remaining_data_length_) { 2094 if (remaining_padding_payload_length_ > remaining_data_length_) {
2083 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 2095 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
2084 return 0; 2096 return 0;
2085 } 2097 }
2086 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 2098 if (current_frame_type_ == DATA) {
2099 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
2100 } else {
2101 DCHECK(current_frame_type_ == HEADERS ||
2102 current_frame_type_ == PUSH_PROMISE ||
2103 current_frame_type_ == CONTINUATION ||
2104 current_frame_type_ == SYN_STREAM ||
2105 current_frame_type_ == SYN_REPLY)
2106 << current_frame_type_;
2107 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
2108 }
2087 } 2109 }
2088 return original_len - len; 2110 return original_len - len;
2089 } 2111 }
2090 2112
2091 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { 2113 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
2092 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); 2114 DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
2093 2115
2094 size_t original_len = len; 2116 size_t original_len = len;
2095 if (remaining_padding_payload_length_ > 0) { 2117 if (remaining_padding_payload_length_ > 0) {
2096 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); 2118 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
2097 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); 2119 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
2098 // The visitor needs to know about padding so it can send window updates. 2120 if (current_frame_type_ == DATA && amount_to_discard > 0) {
2099 // Communicate the padding to the visitor through a NULL data pointer, with 2121 // The visitor needs to know about padding so it can send window updates.
2100 // a nonzero size. 2122 // Communicate the padding to the visitor through a NULL data pointer,
2101 if (amount_to_discard) { 2123 // with a nonzero size.
2102 visitor_->OnStreamFrameData( 2124 visitor_->OnStreamFrameData(
2103 current_frame_stream_id_, NULL, amount_to_discard, false); 2125 current_frame_stream_id_, NULL, amount_to_discard, false);
2104 } 2126 }
2105 data += amount_to_discard; 2127 data += amount_to_discard;
2106 len -= amount_to_discard; 2128 len -= amount_to_discard;
2107 remaining_padding_payload_length_ -= amount_to_discard; 2129 remaining_padding_payload_length_ -= amount_to_discard;
2108 remaining_data_length_ -= amount_to_discard; 2130 remaining_data_length_ -= amount_to_discard;
2109 } 2131 }
2110 2132
2111 if (remaining_data_length_ == 0) { 2133 if (remaining_data_length_ == 0) {
2112 // If the FIN flag is set, and there is no more data in this data frame, 2134 // If the FIN flag is set, or this ends a header block which set FIN,
2113 // inform the visitor of EOF via a 0-length data frame. 2135 // inform the visitor of EOF via a 0-length data frame.
2114 if (current_frame_flags_ & DATA_FLAG_FIN) { 2136 if (expect_continuation_ == 0 &&
2137 ((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 ||
2138 end_stream_when_done_)) {
2139 end_stream_when_done_ = false;
2115 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 2140 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
2116 } 2141 }
2117
2118 CHANGE_STATE(SPDY_AUTO_RESET); 2142 CHANGE_STATE(SPDY_AUTO_RESET);
2119 } 2143 }
2120 return original_len - len; 2144 return original_len - len;
2121 } 2145 }
2122 2146
2123 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 2147 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
2124 size_t original_len = len; 2148 size_t original_len = len;
2125 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) { 2149 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
2126 size_t amount_to_forward = std::min( 2150 size_t amount_to_forward = std::min(
2127 remaining_data_length_ - remaining_padding_payload_length_, len); 2151 remaining_data_length_ - remaining_padding_payload_length_, len);
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 builder->Seek(compressed_size); 3234 builder->Seek(compressed_size);
3211 builder->RewriteLength(*this); 3235 builder->RewriteLength(*this);
3212 3236
3213 pre_compress_bytes.Add(uncompressed_len); 3237 pre_compress_bytes.Add(uncompressed_len);
3214 post_compress_bytes.Add(compressed_size); 3238 post_compress_bytes.Add(compressed_size);
3215 3239
3216 compressed_frames.Increment(); 3240 compressed_frames.Increment();
3217 } 3241 }
3218 3242
3219 } // namespace net 3243 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698