| OLD | NEW |
| 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 <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <cstdint> | 11 #include <cstdint> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <memory> | 13 #include <memory> |
| 14 #include <string> | |
| 15 #include <tuple> | 14 #include <tuple> |
| 16 #include <vector> | 15 #include <vector> |
| 17 | 16 |
| 18 #include "base/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
| 19 #include "base/logging.h" | 18 #include "base/logging.h" |
| 20 #include "base/macros.h" | 19 #include "base/macros.h" |
| 21 #include "base/memory/ptr_util.h" | 20 #include "base/memory/ptr_util.h" |
| 22 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 23 #include "net/quic/core/quic_flags.h" | 22 #include "net/quic/core/quic_flags.h" |
| 24 #include "net/spdy/array_output_buffer.h" | 23 #include "net/spdy/array_output_buffer.h" |
| 25 #include "net/spdy/hpack/hpack_constants.h" | 24 #include "net/spdy/hpack/hpack_constants.h" |
| 26 #include "net/spdy/mock_spdy_framer_visitor.h" | 25 #include "net/spdy/mock_spdy_framer_visitor.h" |
| 27 #include "net/spdy/spdy_flags.h" | 26 #include "net/spdy/spdy_flags.h" |
| 28 #include "net/spdy/spdy_frame_builder.h" | 27 #include "net/spdy/spdy_frame_builder.h" |
| 29 #include "net/spdy/spdy_frame_reader.h" | 28 #include "net/spdy/spdy_frame_reader.h" |
| 30 #include "net/spdy/spdy_protocol.h" | 29 #include "net/spdy/spdy_protocol.h" |
| 31 #include "net/spdy/spdy_test_utils.h" | 30 #include "net/spdy/spdy_test_utils.h" |
| 32 #include "testing/gmock/include/gmock/gmock.h" | 31 #include "testing/gmock/include/gmock/gmock.h" |
| 33 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 34 #include "testing/platform_test.h" | 33 #include "testing/platform_test.h" |
| 35 | 34 |
| 36 using std::string; | |
| 37 using testing::_; | 35 using testing::_; |
| 38 | 36 |
| 39 namespace net { | 37 namespace net { |
| 40 | 38 |
| 41 namespace test { | 39 namespace test { |
| 42 | 40 |
| 43 namespace { | 41 namespace { |
| 44 | 42 |
| 45 const int64_t kSize = 64 * 1024; | 43 const int64_t kSize = 64 * 1024; |
| 46 char output_buffer[kSize] = ""; | 44 char output_buffer[kSize] = ""; |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 } | 462 } |
| 465 | 463 |
| 466 void OnAltSvc(SpdyStreamId stream_id, | 464 void OnAltSvc(SpdyStreamId stream_id, |
| 467 SpdyStringPiece origin, | 465 SpdyStringPiece origin, |
| 468 const SpdyAltSvcWireFormat::AlternativeServiceVector& | 466 const SpdyAltSvcWireFormat::AlternativeServiceVector& |
| 469 altsvc_vector) override { | 467 altsvc_vector) override { |
| 470 VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin | 468 VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin |
| 471 << "\", altsvc_vector)"; | 469 << "\", altsvc_vector)"; |
| 472 test_altsvc_ir_.set_stream_id(stream_id); | 470 test_altsvc_ir_.set_stream_id(stream_id); |
| 473 if (origin.length() > 0) { | 471 if (origin.length() > 0) { |
| 474 test_altsvc_ir_.set_origin(std::string(origin)); | 472 test_altsvc_ir_.set_origin(SpdyString(origin)); |
| 475 } | 473 } |
| 476 for (const SpdyAltSvcWireFormat::AlternativeService& altsvc : | 474 for (const SpdyAltSvcWireFormat::AlternativeService& altsvc : |
| 477 altsvc_vector) { | 475 altsvc_vector) { |
| 478 test_altsvc_ir_.add_altsvc(altsvc); | 476 test_altsvc_ir_.add_altsvc(altsvc); |
| 479 } | 477 } |
| 480 ++altsvc_count_; | 478 ++altsvc_count_; |
| 481 } | 479 } |
| 482 | 480 |
| 483 void OnPriority(SpdyStreamId stream_id, | 481 void OnPriority(SpdyStreamId stream_id, |
| 484 SpdyStreamId parent_stream_id, | 482 SpdyStreamId parent_stream_id, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 // OnFramePayload. | 636 // OnFramePayload. |
| 639 void OnFramePayload(const char* data, size_t len) override { | 637 void OnFramePayload(const char* data, size_t len) override { |
| 640 payload_.append(data, len); | 638 payload_.append(data, len); |
| 641 } | 639 } |
| 642 | 640 |
| 643 std::vector<std::pair<uint16_t, uint32_t>> settings_received_; | 641 std::vector<std::pair<uint16_t, uint32_t>> settings_received_; |
| 644 SpdyStreamId stream_id_ = 0; | 642 SpdyStreamId stream_id_ = 0; |
| 645 size_t length_ = 0; | 643 size_t length_ = 0; |
| 646 uint8_t type_ = 0; | 644 uint8_t type_ = 0; |
| 647 uint8_t flags_ = 0; | 645 uint8_t flags_ = 0; |
| 648 string payload_; | 646 SpdyString payload_; |
| 649 }; | 647 }; |
| 650 | 648 |
| 651 // Retrieves serialized headers from a HEADERS frame. | 649 // Retrieves serialized headers from a HEADERS frame. |
| 652 SpdyStringPiece GetSerializedHeaders(const SpdySerializedFrame& frame, | 650 SpdyStringPiece GetSerializedHeaders(const SpdySerializedFrame& frame, |
| 653 const SpdyFramer& framer) { | 651 const SpdyFramer& framer) { |
| 654 SpdyFrameReader reader(frame.data(), frame.size()); | 652 SpdyFrameReader reader(frame.data(), frame.size()); |
| 655 reader.Seek(3); // Seek past the frame length. | 653 reader.Seek(3); // Seek past the frame length. |
| 656 | 654 |
| 657 uint8_t serialized_type; | 655 uint8_t serialized_type; |
| 658 reader.ReadUInt8(&serialized_type); | 656 reader.ReadUInt8(&serialized_type); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 use_output_ = true; | 703 use_output_ = true; |
| 706 break; | 704 break; |
| 707 case NOT_USE: | 705 case NOT_USE: |
| 708 // TODO(yasong): remove this case after | 706 // TODO(yasong): remove this case after |
| 709 // FLAGS_chromium_http2_flag_remove_rewritelength deprecates. | 707 // FLAGS_chromium_http2_flag_remove_rewritelength deprecates. |
| 710 use_output_ = false; | 708 use_output_ = false; |
| 711 break; | 709 break; |
| 712 } | 710 } |
| 713 } | 711 } |
| 714 | 712 |
| 715 void CompareFrame(const string& description, | 713 void CompareFrame(const SpdyString& description, |
| 716 const SpdySerializedFrame& actual_frame, | 714 const SpdySerializedFrame& actual_frame, |
| 717 const unsigned char* expected, | 715 const unsigned char* expected, |
| 718 const int expected_len) { | 716 const int expected_len) { |
| 719 const unsigned char* actual = | 717 const unsigned char* actual = |
| 720 reinterpret_cast<const unsigned char*>(actual_frame.data()); | 718 reinterpret_cast<const unsigned char*>(actual_frame.data()); |
| 721 CompareCharArraysWithHexError(description, actual, actual_frame.size(), | 719 CompareCharArraysWithHexError(description, actual, actual_frame.size(), |
| 722 expected, expected_len); | 720 expected, expected_len); |
| 723 } | 721 } |
| 724 | 722 |
| 725 void CompareFrames(const string& description, | 723 void CompareFrames(const SpdyString& description, |
| 726 const SpdySerializedFrame& expected_frame, | 724 const SpdySerializedFrame& expected_frame, |
| 727 const SpdySerializedFrame& actual_frame) { | 725 const SpdySerializedFrame& actual_frame) { |
| 728 CompareCharArraysWithHexError( | 726 CompareCharArraysWithHexError( |
| 729 description, | 727 description, |
| 730 reinterpret_cast<const unsigned char*>(expected_frame.data()), | 728 reinterpret_cast<const unsigned char*>(expected_frame.data()), |
| 731 expected_frame.size(), | 729 expected_frame.size(), |
| 732 reinterpret_cast<const unsigned char*>(actual_frame.data()), | 730 reinterpret_cast<const unsigned char*>(actual_frame.data()), |
| 733 actual_frame.size()); | 731 actual_frame.size()); |
| 734 } | 732 } |
| 735 | 733 |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 | 1165 |
| 1168 // Test that if we receive a CONTINUATION with stream ID zero, we signal an | 1166 // Test that if we receive a CONTINUATION with stream ID zero, we signal an |
| 1169 // SPDY_INVALID_STREAM_ID. | 1167 // SPDY_INVALID_STREAM_ID. |
| 1170 TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) { | 1168 TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) { |
| 1171 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; | 1169 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; |
| 1172 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 1170 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 1173 framer.set_visitor(&visitor); | 1171 framer.set_visitor(&visitor); |
| 1174 | 1172 |
| 1175 SpdyContinuationIR continuation(0); | 1173 SpdyContinuationIR continuation(0); |
| 1176 auto some_nonsense_encoding = | 1174 auto some_nonsense_encoding = |
| 1177 base::MakeUnique<string>("some nonsense encoding"); | 1175 base::MakeUnique<SpdyString>("some nonsense encoding"); |
| 1178 continuation.take_encoding(std::move(some_nonsense_encoding)); | 1176 continuation.take_encoding(std::move(some_nonsense_encoding)); |
| 1179 continuation.set_end_headers(true); | 1177 continuation.set_end_headers(true); |
| 1180 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); | 1178 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); |
| 1181 if (use_output_) { | 1179 if (use_output_) { |
| 1182 ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_)); | 1180 ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_)); |
| 1183 frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); | 1181 frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); |
| 1184 } | 1182 } |
| 1185 | 1183 |
| 1186 // We shouldn't have to read the whole frame before we signal an error. | 1184 // We shouldn't have to read the whole frame before we signal an error. |
| 1187 EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); | 1185 EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 | 1259 |
| 1262 TEST_P(SpdyFramerTest, MultiValueHeader) { | 1260 TEST_P(SpdyFramerTest, MultiValueHeader) { |
| 1263 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); | 1261 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); |
| 1264 // Frame builder with plentiful buffer size. | 1262 // Frame builder with plentiful buffer size. |
| 1265 SpdyFrameBuilder frame(1024); | 1263 SpdyFrameBuilder frame(1024); |
| 1266 frame.BeginNewFrame(framer, SpdyFrameType::HEADERS, | 1264 frame.BeginNewFrame(framer, SpdyFrameType::HEADERS, |
| 1267 HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, 3); | 1265 HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, 3); |
| 1268 frame.WriteUInt32(0); // Priority exclusivity and dependent stream. | 1266 frame.WriteUInt32(0); // Priority exclusivity and dependent stream. |
| 1269 frame.WriteUInt8(255); // Priority weight. | 1267 frame.WriteUInt8(255); // Priority weight. |
| 1270 | 1268 |
| 1271 string value("value1\0value2", 13); | 1269 SpdyString value("value1\0value2", 13); |
| 1272 // TODO(jgraettinger): If this pattern appears again, move to test class. | 1270 // TODO(jgraettinger): If this pattern appears again, move to test class. |
| 1273 SpdyHeaderBlock header_set; | 1271 SpdyHeaderBlock header_set; |
| 1274 header_set["name"] = value; | 1272 header_set["name"] = value; |
| 1275 string buffer; | 1273 SpdyString buffer; |
| 1276 HpackEncoder encoder(ObtainHpackHuffmanTable()); | 1274 HpackEncoder encoder(ObtainHpackHuffmanTable()); |
| 1277 encoder.DisableCompression(); | 1275 encoder.DisableCompression(); |
| 1278 encoder.EncodeHeaderSet(header_set, &buffer); | 1276 encoder.EncodeHeaderSet(header_set, &buffer); |
| 1279 frame.WriteBytes(&buffer[0], buffer.size()); | 1277 frame.WriteBytes(&buffer[0], buffer.size()); |
| 1280 // write the length | 1278 // write the length |
| 1281 frame.OverwriteLength(framer, frame.length() - framer.GetFrameHeaderSize()); | 1279 frame.OverwriteLength(framer, frame.length() - framer.GetFrameHeaderSize()); |
| 1282 | 1280 |
| 1283 SpdySerializedFrame control_frame(frame.take()); | 1281 SpdySerializedFrame control_frame(frame.take()); |
| 1284 | 1282 |
| 1285 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 1283 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2470 0x03, // Name Len: 3 | 2468 0x03, // Name Len: 3 |
| 2471 0x66, 0x6f, 0x6f, // foo | 2469 0x66, 0x6f, 0x6f, // foo |
| 2472 0x03, // Value Len: 3 | 2470 0x03, // Value Len: 3 |
| 2473 0x62, 0x61, 0x72, // bar | 2471 0x62, 0x61, 0x72, // bar |
| 2474 }; | 2472 }; |
| 2475 // frame-format on | 2473 // frame-format on |
| 2476 | 2474 |
| 2477 SpdyHeaderBlock header_block; | 2475 SpdyHeaderBlock header_block; |
| 2478 header_block["bar"] = "foo"; | 2476 header_block["bar"] = "foo"; |
| 2479 header_block["foo"] = "bar"; | 2477 header_block["foo"] = "bar"; |
| 2480 auto buffer = base::MakeUnique<string>(); | 2478 auto buffer = base::MakeUnique<SpdyString>(); |
| 2481 HpackEncoder encoder(ObtainHpackHuffmanTable()); | 2479 HpackEncoder encoder(ObtainHpackHuffmanTable()); |
| 2482 encoder.DisableCompression(); | 2480 encoder.DisableCompression(); |
| 2483 encoder.EncodeHeaderSet(header_block, buffer.get()); | 2481 encoder.EncodeHeaderSet(header_block, buffer.get()); |
| 2484 | 2482 |
| 2485 SpdyContinuationIR continuation(42); | 2483 SpdyContinuationIR continuation(42); |
| 2486 continuation.take_encoding(std::move(buffer)); | 2484 continuation.take_encoding(std::move(buffer)); |
| 2487 continuation.set_end_headers(true); | 2485 continuation.set_end_headers(true); |
| 2488 | 2486 |
| 2489 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); | 2487 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); |
| 2490 if (use_output_) { | 2488 if (use_output_) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2585 0x78, 0x78, 0x78, 0x78, // xxxx | 2583 0x78, 0x78, 0x78, 0x78, // xxxx |
| 2586 0x78, 0x78, 0x78, 0x78, // xxxx | 2584 0x78, 0x78, 0x78, 0x78, // xxxx |
| 2587 0x78, 0x78, 0x78, 0x78, // xxxx | 2585 0x78, 0x78, 0x78, 0x78, // xxxx |
| 2588 0x78, 0x78, 0x78, 0x78, // xxxx | 2586 0x78, 0x78, 0x78, 0x78, // xxxx |
| 2589 0x78, // x | 2587 0x78, // x |
| 2590 }; | 2588 }; |
| 2591 // frame-format on | 2589 // frame-format on |
| 2592 | 2590 |
| 2593 SpdyPushPromiseIR push_promise(42, 57); | 2591 SpdyPushPromiseIR push_promise(42, 57); |
| 2594 push_promise.set_padding_len(1); | 2592 push_promise.set_padding_len(1); |
| 2595 string big_value(TestSpdyVisitor::sent_control_frame_max_size(), 'x'); | 2593 SpdyString big_value(TestSpdyVisitor::sent_control_frame_max_size(), 'x'); |
| 2596 push_promise.SetHeader("xxx", big_value); | 2594 push_promise.SetHeader("xxx", big_value); |
| 2597 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); | 2595 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); |
| 2598 if (use_output_) { | 2596 if (use_output_) { |
| 2599 ASSERT_TRUE(framer.SerializePushPromise(push_promise, &output_)); | 2597 ASSERT_TRUE(framer.SerializePushPromise(push_promise, &output_)); |
| 2600 frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); | 2598 frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); |
| 2601 } | 2599 } |
| 2602 | 2600 |
| 2603 // The entire frame should look like below: | 2601 // The entire frame should look like below: |
| 2604 // Name Length in Byte | 2602 // Name Length in Byte |
| 2605 // ------------------------------------------- Begin of PUSH_PROMISE frame | 2603 // ------------------------------------------- Begin of PUSH_PROMISE frame |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2735 } | 2733 } |
| 2736 | 2734 |
| 2737 TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { | 2735 TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { |
| 2738 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); | 2736 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); |
| 2739 SpdyHeadersIR headers(1); | 2737 SpdyHeadersIR headers(1); |
| 2740 headers.set_padding_len(256); | 2738 headers.set_padding_len(256); |
| 2741 | 2739 |
| 2742 // Exact payload length will change with HPACK, but this should be long | 2740 // Exact payload length will change with HPACK, but this should be long |
| 2743 // enough to cause an overflow. | 2741 // enough to cause an overflow. |
| 2744 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); | 2742 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); |
| 2745 string big_value(kBigValueSize, 'x'); | 2743 SpdyString big_value(kBigValueSize, 'x'); |
| 2746 headers.SetHeader("aa", big_value); | 2744 headers.SetHeader("aa", big_value); |
| 2747 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( | 2745 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( |
| 2748 &framer, headers, use_output_ ? &output_ : nullptr)); | 2746 &framer, headers, use_output_ ? &output_ : nullptr)); |
| 2749 EXPECT_GT(control_frame.size(), | 2747 EXPECT_GT(control_frame.size(), |
| 2750 TestSpdyVisitor::sent_control_frame_max_size()); | 2748 TestSpdyVisitor::sent_control_frame_max_size()); |
| 2751 | 2749 |
| 2752 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 2750 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| 2753 visitor.SimulateInFramer( | 2751 visitor.SimulateInFramer( |
| 2754 reinterpret_cast<unsigned char*>(control_frame.data()), | 2752 reinterpret_cast<unsigned char*>(control_frame.data()), |
| 2755 control_frame.size()); | 2753 control_frame.size()); |
| 2756 EXPECT_TRUE(visitor.header_buffer_valid_); | 2754 EXPECT_TRUE(visitor.header_buffer_valid_); |
| 2757 EXPECT_EQ(0, visitor.error_count_); | 2755 EXPECT_EQ(0, visitor.error_count_); |
| 2758 EXPECT_EQ(1, visitor.headers_frame_count_); | 2756 EXPECT_EQ(1, visitor.headers_frame_count_); |
| 2759 EXPECT_EQ(1, visitor.continuation_count_); | 2757 EXPECT_EQ(1, visitor.continuation_count_); |
| 2760 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 2758 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
| 2761 } | 2759 } |
| 2762 | 2760 |
| 2763 TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) { | 2761 TEST_P(SpdyFramerTest, MultipleContinuationFramesWithIterator) { |
| 2764 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); | 2762 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); |
| 2765 auto headers = base::MakeUnique<SpdyHeadersIR>(1); | 2763 auto headers = base::MakeUnique<SpdyHeadersIR>(1); |
| 2766 headers->set_padding_len(256); | 2764 headers->set_padding_len(256); |
| 2767 | 2765 |
| 2768 // Exact payload length will change with HPACK, but this should be long | 2766 // Exact payload length will change with HPACK, but this should be long |
| 2769 // enough to cause an overflow. | 2767 // enough to cause an overflow. |
| 2770 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); | 2768 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); |
| 2771 string big_valuex(kBigValueSize, 'x'); | 2769 SpdyString big_valuex(kBigValueSize, 'x'); |
| 2772 headers->SetHeader("aa", big_valuex); | 2770 headers->SetHeader("aa", big_valuex); |
| 2773 string big_valuez(kBigValueSize, 'z'); | 2771 SpdyString big_valuez(kBigValueSize, 'z'); |
| 2774 headers->SetHeader("bb", big_valuez); | 2772 headers->SetHeader("bb", big_valuez); |
| 2775 | 2773 |
| 2776 SpdyFramer::SpdyHeaderFrameIterator frame_it(&framer, std::move(headers)); | 2774 SpdyFramer::SpdyHeaderFrameIterator frame_it(&framer, std::move(headers)); |
| 2777 | 2775 |
| 2778 EXPECT_TRUE(frame_it.HasNextFrame()); | 2776 EXPECT_TRUE(frame_it.HasNextFrame()); |
| 2779 SpdySerializedFrame headers_frame(frame_it.NextFrame()); | 2777 SpdySerializedFrame headers_frame(frame_it.NextFrame()); |
| 2780 EXPECT_EQ(headers_frame.size(), | 2778 EXPECT_EQ(headers_frame.size(), |
| 2781 TestSpdyVisitor::sent_control_frame_max_size()); | 2779 TestSpdyVisitor::sent_control_frame_max_size()); |
| 2782 | 2780 |
| 2783 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 2781 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 } | 2820 } |
| 2823 | 2821 |
| 2824 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { | 2822 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { |
| 2825 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); | 2823 SpdyFramer framer(SpdyFramer::DISABLE_COMPRESSION); |
| 2826 SpdyPushPromiseIR push_promise(1, 2); | 2824 SpdyPushPromiseIR push_promise(1, 2); |
| 2827 push_promise.set_padding_len(256); | 2825 push_promise.set_padding_len(256); |
| 2828 | 2826 |
| 2829 // Exact payload length will change with HPACK, but this should be long | 2827 // Exact payload length will change with HPACK, but this should be long |
| 2830 // enough to cause an overflow. | 2828 // enough to cause an overflow. |
| 2831 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); | 2829 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); |
| 2832 string big_value(kBigValueSize, 'x'); | 2830 SpdyString big_value(kBigValueSize, 'x'); |
| 2833 push_promise.SetHeader("aa", big_value); | 2831 push_promise.SetHeader("aa", big_value); |
| 2834 SpdySerializedFrame control_frame(framer.SerializePushPromise(push_promise)); | 2832 SpdySerializedFrame control_frame(framer.SerializePushPromise(push_promise)); |
| 2835 if (use_output_) { | 2833 if (use_output_) { |
| 2836 ASSERT_TRUE(framer.SerializePushPromise(push_promise, &output_)); | 2834 ASSERT_TRUE(framer.SerializePushPromise(push_promise, &output_)); |
| 2837 control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); | 2835 control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false); |
| 2838 } | 2836 } |
| 2839 EXPECT_GT(control_frame.size(), | 2837 EXPECT_GT(control_frame.size(), |
| 2840 TestSpdyVisitor::sent_control_frame_max_size()); | 2838 TestSpdyVisitor::sent_control_frame_max_size()); |
| 2841 | 2839 |
| 2842 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 2840 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| 2843 visitor.SimulateInFramer( | 2841 visitor.SimulateInFramer( |
| 2844 reinterpret_cast<unsigned char*>(control_frame.data()), | 2842 reinterpret_cast<unsigned char*>(control_frame.data()), |
| 2845 control_frame.size()); | 2843 control_frame.size()); |
| 2846 EXPECT_TRUE(visitor.header_buffer_valid_); | 2844 EXPECT_TRUE(visitor.header_buffer_valid_); |
| 2847 EXPECT_EQ(0, visitor.error_count_); | 2845 EXPECT_EQ(0, visitor.error_count_); |
| 2848 EXPECT_EQ(1, visitor.push_promise_frame_count_); | 2846 EXPECT_EQ(1, visitor.push_promise_frame_count_); |
| 2849 EXPECT_EQ(1, visitor.continuation_count_); | 2847 EXPECT_EQ(1, visitor.continuation_count_); |
| 2850 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 2848 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
| 2851 } | 2849 } |
| 2852 | 2850 |
| 2853 // Check that the framer stops delivering header data chunks once the visitor | 2851 // Check that the framer stops delivering header data chunks once the visitor |
| 2854 // declares it doesn't want any more. This is important to guard against | 2852 // declares it doesn't want any more. This is important to guard against |
| 2855 // "zip bomb" types of attacks. | 2853 // "zip bomb" types of attacks. |
| 2856 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { | 2854 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { |
| 2857 const size_t kHeaderBufferChunks = 4; | 2855 const size_t kHeaderBufferChunks = 4; |
| 2858 const size_t kHeaderBufferSize = | 2856 const size_t kHeaderBufferSize = |
| 2859 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; | 2857 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; |
| 2860 const size_t kBigValueSize = kHeaderBufferSize * 2; | 2858 const size_t kBigValueSize = kHeaderBufferSize * 2; |
| 2861 string big_value(kBigValueSize, 'x'); | 2859 SpdyString big_value(kBigValueSize, 'x'); |
| 2862 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 2860 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 2863 SpdyHeadersIR headers(1); | 2861 SpdyHeadersIR headers(1); |
| 2864 headers.set_fin(true); | 2862 headers.set_fin(true); |
| 2865 headers.SetHeader("aa", big_value); | 2863 headers.SetHeader("aa", big_value); |
| 2866 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( | 2864 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( |
| 2867 &framer, headers, use_output_ ? &output_ : nullptr)); | 2865 &framer, headers, use_output_ ? &output_ : nullptr)); |
| 2868 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); | 2866 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); |
| 2869 visitor.set_header_buffer_size(kHeaderBufferSize); | 2867 visitor.set_header_buffer_size(kHeaderBufferSize); |
| 2870 visitor.SimulateInFramer( | 2868 visitor.SimulateInFramer( |
| 2871 reinterpret_cast<unsigned char*>(control_frame.data()), | 2869 reinterpret_cast<unsigned char*>(control_frame.data()), |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2892 const unsigned char kH2Len = static_cast<unsigned char>(less_than_min_length); | 2890 const unsigned char kH2Len = static_cast<unsigned char>(less_than_min_length); |
| 2893 const unsigned char kH2FrameData[] = { | 2891 const unsigned char kH2FrameData[] = { |
| 2894 0x00, 0x00, kH2Len, // Length: min length - 1 | 2892 0x00, 0x00, kH2Len, // Length: min length - 1 |
| 2895 0x07, // Type: GOAWAY | 2893 0x07, // Type: GOAWAY |
| 2896 0x00, // Flags: none | 2894 0x00, // Flags: none |
| 2897 0x00, 0x00, 0x00, 0x00, // Stream: 0 | 2895 0x00, 0x00, 0x00, 0x00, // Stream: 0 |
| 2898 0x00, 0x00, 0x00, 0x00, // Last: 0 | 2896 0x00, 0x00, 0x00, 0x00, // Last: 0 |
| 2899 0x00, 0x00, 0x00, // Truncated Status Field | 2897 0x00, 0x00, 0x00, // Truncated Status Field |
| 2900 }; | 2898 }; |
| 2901 const size_t pad_length = length + kFrameHeaderSize - sizeof(kH2FrameData); | 2899 const size_t pad_length = length + kFrameHeaderSize - sizeof(kH2FrameData); |
| 2902 string pad(pad_length, 'A'); | 2900 SpdyString pad(pad_length, 'A'); |
| 2903 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 2901 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| 2904 | 2902 |
| 2905 visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData)); | 2903 visitor.SimulateInFramer(kH2FrameData, sizeof(kH2FrameData)); |
| 2906 visitor.SimulateInFramer(reinterpret_cast<const unsigned char*>(pad.c_str()), | 2904 visitor.SimulateInFramer(reinterpret_cast<const unsigned char*>(pad.c_str()), |
| 2907 pad.length()); | 2905 pad.length()); |
| 2908 | 2906 |
| 2909 EXPECT_EQ(1, visitor.error_count_); // This generated an error. | 2907 EXPECT_EQ(1, visitor.error_count_); // This generated an error. |
| 2910 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, | 2908 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, |
| 2911 visitor.framer_.spdy_framer_error()) | 2909 visitor.framer_.spdy_framer_error()) |
| 2912 << SpdyFramer::SpdyFramerErrorToString( | 2910 << SpdyFramer::SpdyFramerErrorToString( |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3656 }; | 3654 }; |
| 3657 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); | 3655 TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION); |
| 3658 TestExtension extension; | 3656 TestExtension extension; |
| 3659 visitor.set_extension_visitor(&extension); | 3657 visitor.set_extension_visitor(&extension); |
| 3660 visitor.SimulateInFramer(unknown_frame, arraysize(unknown_frame)); | 3658 visitor.SimulateInFramer(unknown_frame, arraysize(unknown_frame)); |
| 3661 EXPECT_EQ(0, visitor.error_count_); | 3659 EXPECT_EQ(0, visitor.error_count_); |
| 3662 EXPECT_EQ(0x7fffffffu, extension.stream_id_); | 3660 EXPECT_EQ(0x7fffffffu, extension.stream_id_); |
| 3663 EXPECT_EQ(20u, extension.length_); | 3661 EXPECT_EQ(20u, extension.length_); |
| 3664 EXPECT_EQ(255, extension.type_); | 3662 EXPECT_EQ(255, extension.type_); |
| 3665 EXPECT_EQ(0xff, extension.flags_); | 3663 EXPECT_EQ(0xff, extension.flags_); |
| 3666 EXPECT_EQ(string(20, '\xff'), extension.payload_); | 3664 EXPECT_EQ(SpdyString(20, '\xff'), extension.payload_); |
| 3667 | 3665 |
| 3668 // Follow it up with a valid control frame to make sure we handle | 3666 // Follow it up with a valid control frame to make sure we handle |
| 3669 // subsequent frames correctly. | 3667 // subsequent frames correctly. |
| 3670 SpdySettingsIR settings_ir; | 3668 SpdySettingsIR settings_ir; |
| 3671 settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10); | 3669 settings_ir.AddSetting(SETTINGS_HEADER_TABLE_SIZE, 10); |
| 3672 SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir)); | 3670 SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir)); |
| 3673 visitor.SimulateInFramer( | 3671 visitor.SimulateInFramer( |
| 3674 reinterpret_cast<unsigned char*>(control_frame.data()), | 3672 reinterpret_cast<unsigned char*>(control_frame.data()), |
| 3675 control_frame.size()); | 3673 control_frame.size()); |
| 3676 EXPECT_EQ(0, visitor.error_count_); | 3674 EXPECT_EQ(0, visitor.error_count_); |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4600 // change the order and type of frames). | 4598 // change the order and type of frames). |
| 4601 SpdySerializedFrame frame1 = std::move(headers_frame); | 4599 SpdySerializedFrame frame1 = std::move(headers_frame); |
| 4602 SpdySerializedFrame frame2 = std::move(four_score_frame); | 4600 SpdySerializedFrame frame2 = std::move(four_score_frame); |
| 4603 | 4601 |
| 4604 const size_t frame1_size = frame1.size(); | 4602 const size_t frame1_size = frame1.size(); |
| 4605 const size_t frame2_size = frame2.size(); | 4603 const size_t frame2_size = frame2.size(); |
| 4606 | 4604 |
| 4607 VLOG(1) << "frame1_size = " << frame1_size; | 4605 VLOG(1) << "frame1_size = " << frame1_size; |
| 4608 VLOG(1) << "frame2_size = " << frame2_size; | 4606 VLOG(1) << "frame2_size = " << frame2_size; |
| 4609 | 4607 |
| 4610 string input_buffer; | 4608 SpdyString input_buffer; |
| 4611 input_buffer.append(frame1.data(), frame1_size); | 4609 input_buffer.append(frame1.data(), frame1_size); |
| 4612 input_buffer.append(frame2.data(), frame2_size); | 4610 input_buffer.append(frame2.data(), frame2_size); |
| 4613 | 4611 |
| 4614 const char* buf = input_buffer.data(); | 4612 const char* buf = input_buffer.data(); |
| 4615 const size_t buf_size = input_buffer.size(); | 4613 const size_t buf_size = input_buffer.size(); |
| 4616 | 4614 |
| 4617 VLOG(1) << "buf_size = " << buf_size; | 4615 VLOG(1) << "buf_size = " << buf_size; |
| 4618 | 4616 |
| 4619 size_t processed = framer.ProcessInput(buf, buf_size); | 4617 size_t processed = framer.ProcessInput(buf, buf_size); |
| 4620 EXPECT_EQ(buf_size, processed); | 4618 EXPECT_EQ(buf_size, processed); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4649 // change the order and type of frames). | 4647 // change the order and type of frames). |
| 4650 SpdySerializedFrame frame1 = std::move(four_score_frame); | 4648 SpdySerializedFrame frame1 = std::move(four_score_frame); |
| 4651 SpdySerializedFrame frame2 = std::move(headers_frame); | 4649 SpdySerializedFrame frame2 = std::move(headers_frame); |
| 4652 | 4650 |
| 4653 const size_t frame1_size = frame1.size(); | 4651 const size_t frame1_size = frame1.size(); |
| 4654 const size_t frame2_size = frame2.size(); | 4652 const size_t frame2_size = frame2.size(); |
| 4655 | 4653 |
| 4656 VLOG(1) << "frame1_size = " << frame1_size; | 4654 VLOG(1) << "frame1_size = " << frame1_size; |
| 4657 VLOG(1) << "frame2_size = " << frame2_size; | 4655 VLOG(1) << "frame2_size = " << frame2_size; |
| 4658 | 4656 |
| 4659 string input_buffer; | 4657 SpdyString input_buffer; |
| 4660 input_buffer.append(frame1.data(), frame1_size); | 4658 input_buffer.append(frame1.data(), frame1_size); |
| 4661 input_buffer.append(frame2.data(), frame2_size); | 4659 input_buffer.append(frame2.data(), frame2_size); |
| 4662 | 4660 |
| 4663 const char* buf = input_buffer.data(); | 4661 const char* buf = input_buffer.data(); |
| 4664 const size_t buf_size = input_buffer.size(); | 4662 const size_t buf_size = input_buffer.size(); |
| 4665 | 4663 |
| 4666 VLOG(1) << "buf_size = " << buf_size; | 4664 VLOG(1) << "buf_size = " << buf_size; |
| 4667 | 4665 |
| 4668 for (size_t first_size = 0; first_size <= buf_size; ++first_size) { | 4666 for (size_t first_size = 0; first_size <= buf_size; ++first_size) { |
| 4669 VLOG(1) << "first_size = " << first_size; | 4667 VLOG(1) << "first_size = " << first_size; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4703 | 4701 |
| 4704 EXPECT_EQ(1, visitor->data_frame_count_); | 4702 EXPECT_EQ(1, visitor->data_frame_count_); |
| 4705 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); | 4703 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); |
| 4706 EXPECT_EQ(0, visitor->headers_frame_count_); | 4704 EXPECT_EQ(0, visitor->headers_frame_count_); |
| 4707 } | 4705 } |
| 4708 } | 4706 } |
| 4709 | 4707 |
| 4710 } // namespace test | 4708 } // namespace test |
| 4711 | 4709 |
| 4712 } // namespace net | 4710 } // namespace net |
| OLD | NEW |