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 |