| 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 <tuple> | 14 #include <tuple> |
| 15 #include <utility> |
| 15 #include <vector> | 16 #include <vector> |
| 16 | 17 |
| 17 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 19 #include "base/macros.h" | 20 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" | 21 #include "base/memory/ptr_util.h" |
| 21 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 22 #include "net/quic/core/quic_flags.h" | 23 #include "net/quic/core/quic_flags.h" |
| 23 #include "net/spdy/array_output_buffer.h" | 24 #include "net/spdy/array_output_buffer.h" |
| 24 #include "net/spdy/hpack/hpack_constants.h" | 25 #include "net/spdy/hpack/hpack_constants.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 DecompressionVisitor() : finished_(false) {} | 84 DecompressionVisitor() : finished_(false) {} |
| 84 | 85 |
| 85 const SpdyFrameIR& GetFrame() const { | 86 const SpdyFrameIR& GetFrame() const { |
| 86 CHECK(finished_); | 87 CHECK(finished_); |
| 87 return *frame_; | 88 return *frame_; |
| 88 } | 89 } |
| 89 | 90 |
| 90 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | 91 SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
| 91 SpdyStreamId stream_id) override { | 92 SpdyStreamId stream_id) override { |
| 92 if (headers_handler_ == nullptr) { | 93 if (headers_handler_ == nullptr) { |
| 93 headers_handler_.reset(new TestHeadersHandler); | 94 headers_handler_ = base::MakeUnique<TestHeadersHandler>(); |
| 94 } | 95 } |
| 95 return headers_handler_.get(); | 96 return headers_handler_.get(); |
| 96 } | 97 } |
| 97 | 98 |
| 98 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | 99 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { |
| 99 CHECK(!finished_); | 100 CHECK(!finished_); |
| 100 frame_->set_header_block(headers_handler_->decoded_block().Clone()); | 101 frame_->set_header_block(headers_handler_->decoded_block().Clone()); |
| 101 finished_ = true; | 102 finished_ = true; |
| 102 if (end_headers) { | 103 if (end_headers) { |
| 103 headers_handler_.reset(); | 104 headers_handler_.reset(); |
| 104 } | 105 } |
| 105 } | 106 } |
| 106 | 107 |
| 107 void OnHeaders(SpdyStreamId stream_id, | 108 void OnHeaders(SpdyStreamId stream_id, |
| 108 bool has_priority, | 109 bool has_priority, |
| 109 int weight, | 110 int weight, |
| 110 SpdyStreamId parent_stream_id, | 111 SpdyStreamId parent_stream_id, |
| 111 bool exclusive, | 112 bool exclusive, |
| 112 bool fin, | 113 bool fin, |
| 113 bool end) override { | 114 bool end) override { |
| 114 SpdyHeadersIR* headers = new SpdyHeadersIR(stream_id); | 115 auto headers = base::MakeUnique<SpdyHeadersIR>(stream_id); |
| 115 headers->set_has_priority(has_priority); | 116 headers->set_has_priority(has_priority); |
| 116 headers->set_weight(weight); | 117 headers->set_weight(weight); |
| 117 headers->set_parent_stream_id(parent_stream_id); | 118 headers->set_parent_stream_id(parent_stream_id); |
| 118 headers->set_exclusive(exclusive); | 119 headers->set_exclusive(exclusive); |
| 119 headers->set_fin(fin); | 120 headers->set_fin(fin); |
| 120 frame_.reset(headers); | 121 frame_ = std::move(headers); |
| 121 } | 122 } |
| 122 | 123 |
| 123 void OnPushPromise(SpdyStreamId stream_id, | 124 void OnPushPromise(SpdyStreamId stream_id, |
| 124 SpdyStreamId promised_stream_id, | 125 SpdyStreamId promised_stream_id, |
| 125 bool end) override { | 126 bool end) override { |
| 126 SpdyPushPromiseIR* push_promise = | 127 frame_ = |
| 127 new SpdyPushPromiseIR(stream_id, promised_stream_id); | 128 base::MakeUnique<SpdyPushPromiseIR>(stream_id, promised_stream_id); |
| 128 frame_.reset(push_promise); | |
| 129 } | 129 } |
| 130 | 130 |
| 131 // TODO(birenroy): Add support for CONTINUATION. | 131 // TODO(birenroy): Add support for CONTINUATION. |
| 132 void OnContinuation(SpdyStreamId stream_id, bool end) override { | 132 void OnContinuation(SpdyStreamId stream_id, bool end) override { |
| 133 LOG(FATAL); | 133 LOG(FATAL); |
| 134 } | 134 } |
| 135 | 135 |
| 136 // All other methods just LOG(FATAL). | 136 // All other methods just LOG(FATAL). |
| 137 void OnError(SpdyFramer* framer) override { LOG(FATAL); } | 137 void OnError(SpdyFramer* framer) override { LOG(FATAL); } |
| 138 void OnDataFrameHeader(SpdyStreamId stream_id, | 138 void OnDataFrameHeader(SpdyStreamId stream_id, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); | 189 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); |
| 190 }; | 190 }; |
| 191 | 191 |
| 192 private: | 192 private: |
| 193 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); | 193 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); |
| 194 }; | 194 }; |
| 195 | 195 |
| 196 MATCHER_P(IsFrameUnionOf, frame_list, "") { | 196 MATCHER_P(IsFrameUnionOf, frame_list, "") { |
| 197 size_t size_verified = 0; | 197 size_t size_verified = 0; |
| 198 for (const auto& frame : *frame_list) { | 198 for (const auto& frame : *frame_list) { |
| 199 if (arg.size() >= size_verified + frame.size()) { | 199 if (arg.size() < size_verified + frame.size()) { |
| 200 if (!memcmp(arg.data() + size_verified, frame.data(), frame.size())) { | |
| 201 size_verified += frame.size(); | |
| 202 } else { | |
| 203 CompareCharArraysWithHexError( | |
| 204 "Header serialization methods should be equivalent: ", | |
| 205 reinterpret_cast<unsigned char*>(arg.data() + size_verified), | |
| 206 frame.size(), reinterpret_cast<unsigned char*>(frame.data()), | |
| 207 frame.size()); | |
| 208 return false; | |
| 209 } | |
| 210 } else { | |
| 211 LOG(FATAL) << "Incremental header serialization should not lead to a " | 200 LOG(FATAL) << "Incremental header serialization should not lead to a " |
| 212 << "higher total frame length than non-incremental method."; | 201 << "higher total frame length than non-incremental method."; |
| 213 return false; | 202 return false; |
| 214 } | 203 } |
| 204 if (memcmp(arg.data() + size_verified, frame.data(), frame.size())) { |
| 205 CompareCharArraysWithHexError( |
| 206 "Header serialization methods should be equivalent: ", |
| 207 reinterpret_cast<unsigned char*>(arg.data() + size_verified), |
| 208 frame.size(), reinterpret_cast<unsigned char*>(frame.data()), |
| 209 frame.size()); |
| 210 return false; |
| 211 } |
| 212 size_verified += frame.size(); |
| 215 } | 213 } |
| 216 return size_verified == arg.size(); | 214 return size_verified == arg.size(); |
| 217 } | 215 } |
| 218 | 216 |
| 219 class SpdyFramerPeer { | 217 class SpdyFramerPeer { |
| 220 public: | 218 public: |
| 221 static size_t ControlFrameBufferSize() { | 219 static size_t ControlFrameBufferSize() { |
| 222 return SpdyFramer::kControlFrameBufferSize; | 220 return SpdyFramer::kControlFrameBufferSize; |
| 223 } | 221 } |
| 224 static size_t GetNumberRequiredContinuationFrames(SpdyFramer* framer, | 222 static size_t GetNumberRequiredContinuationFrames(SpdyFramer* framer, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 last_push_promise_promised_stream_(0), | 317 last_push_promise_promised_stream_(0), |
| 320 data_bytes_(0), | 318 data_bytes_(0), |
| 321 fin_frame_count_(0), | 319 fin_frame_count_(0), |
| 322 fin_flag_count_(0), | 320 fin_flag_count_(0), |
| 323 end_of_stream_count_(0), | 321 end_of_stream_count_(0), |
| 324 control_frame_header_data_count_(0), | 322 control_frame_header_data_count_(0), |
| 325 zero_length_control_frame_header_data_count_(0), | 323 zero_length_control_frame_header_data_count_(0), |
| 326 data_frame_count_(0), | 324 data_frame_count_(0), |
| 327 last_payload_len_(0), | 325 last_payload_len_(0), |
| 328 last_frame_len_(0), | 326 last_frame_len_(0), |
| 329 header_buffer_(new char[kDefaultHeaderBufferSize]), | 327 header_buffer_(kDefaultHeaderBufferSize), |
| 330 header_buffer_length_(0), | 328 header_buffer_length_(0), |
| 331 header_buffer_size_(kDefaultHeaderBufferSize), | |
| 332 header_stream_id_(static_cast<SpdyStreamId>(-1)), | 329 header_stream_id_(static_cast<SpdyStreamId>(-1)), |
| 333 header_control_type_(SpdyFrameType::DATA), | 330 header_control_type_(SpdyFrameType::DATA), |
| 334 header_buffer_valid_(false) {} | 331 header_buffer_valid_(false) {} |
| 335 | 332 |
| 336 void OnError(SpdyFramer* f) override { | 333 void OnError(SpdyFramer* f) override { |
| 337 VLOG(1) << "SpdyFramer Error: " | 334 VLOG(1) << "SpdyFramer Error: " |
| 338 << SpdyFramer::SpdyFramerErrorToString(f->spdy_framer_error()); | 335 << SpdyFramer::SpdyFramerErrorToString(f->spdy_framer_error()); |
| 339 ++error_count_; | 336 ++error_count_; |
| 340 } | 337 } |
| 341 | 338 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 366 | 363 |
| 367 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | 364 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { |
| 368 VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; | 365 VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; |
| 369 EXPECT_EQ(header_stream_id_, stream_id); | 366 EXPECT_EQ(header_stream_id_, stream_id); |
| 370 data_bytes_ += len; | 367 data_bytes_ += len; |
| 371 } | 368 } |
| 372 | 369 |
| 373 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | 370 SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
| 374 SpdyStreamId stream_id) override { | 371 SpdyStreamId stream_id) override { |
| 375 if (headers_handler_ == nullptr) { | 372 if (headers_handler_ == nullptr) { |
| 376 headers_handler_.reset(new TestHeadersHandler); | 373 headers_handler_ = base::MakeUnique<TestHeadersHandler>(); |
| 377 } | 374 } |
| 378 return headers_handler_.get(); | 375 return headers_handler_.get(); |
| 379 } | 376 } |
| 380 | 377 |
| 381 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | 378 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { |
| 382 CHECK(headers_handler_ != nullptr); | 379 CHECK(headers_handler_ != nullptr); |
| 383 headers_ = headers_handler_->decoded_block().Clone(); | 380 headers_ = headers_handler_->decoded_block().Clone(); |
| 384 header_bytes_received_ = headers_handler_->header_bytes_parsed(); | 381 header_bytes_received_ = headers_handler_->header_bytes_parsed(); |
| 385 if (end_headers) { | 382 if (end_headers) { |
| 386 headers_handler_.reset(); | 383 headers_handler_.reset(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 void OnAltSvc(SpdyStreamId stream_id, | 461 void OnAltSvc(SpdyStreamId stream_id, |
| 465 SpdyStringPiece origin, | 462 SpdyStringPiece origin, |
| 466 const SpdyAltSvcWireFormat::AlternativeServiceVector& | 463 const SpdyAltSvcWireFormat::AlternativeServiceVector& |
| 467 altsvc_vector) override { | 464 altsvc_vector) override { |
| 468 VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin | 465 VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin |
| 469 << "\", altsvc_vector)"; | 466 << "\", altsvc_vector)"; |
| 470 test_altsvc_ir_.set_stream_id(stream_id); | 467 test_altsvc_ir_.set_stream_id(stream_id); |
| 471 if (origin.length() > 0) { | 468 if (origin.length() > 0) { |
| 472 test_altsvc_ir_.set_origin(SpdyString(origin)); | 469 test_altsvc_ir_.set_origin(SpdyString(origin)); |
| 473 } | 470 } |
| 474 for (const SpdyAltSvcWireFormat::AlternativeService& altsvc : | 471 for (const auto& altsvc : altsvc_vector) { |
| 475 altsvc_vector) { | |
| 476 test_altsvc_ir_.add_altsvc(altsvc); | 472 test_altsvc_ir_.add_altsvc(altsvc); |
| 477 } | 473 } |
| 478 ++altsvc_count_; | 474 ++altsvc_count_; |
| 479 } | 475 } |
| 480 | 476 |
| 481 void OnPriority(SpdyStreamId stream_id, | 477 void OnPriority(SpdyStreamId stream_id, |
| 482 SpdyStreamId parent_stream_id, | 478 SpdyStreamId parent_stream_id, |
| 483 int weight, | 479 int weight, |
| 484 bool exclusive) override { | 480 bool exclusive) override { |
| 485 VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id << ", " | 481 VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id << ", " |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 input_ptr += bytes_processed; | 524 input_ptr += bytes_processed; |
| 529 } | 525 } |
| 530 } | 526 } |
| 531 | 527 |
| 532 void InitHeaderStreaming(SpdyFrameType header_control_type, | 528 void InitHeaderStreaming(SpdyFrameType header_control_type, |
| 533 SpdyStreamId stream_id) { | 529 SpdyStreamId stream_id) { |
| 534 if (!IsDefinedFrameType(SerializeFrameType(header_control_type))) { | 530 if (!IsDefinedFrameType(SerializeFrameType(header_control_type))) { |
| 535 DLOG(FATAL) << "Attempted to init header streaming with " | 531 DLOG(FATAL) << "Attempted to init header streaming with " |
| 536 << "invalid control frame type: " << header_control_type; | 532 << "invalid control frame type: " << header_control_type; |
| 537 } | 533 } |
| 538 memset(header_buffer_.get(), 0, header_buffer_size_); | 534 std::fill(header_buffer_.begin(), header_buffer_.end(), 0); |
| 539 header_buffer_length_ = 0; | 535 header_buffer_length_ = 0; |
| 540 header_stream_id_ = stream_id; | 536 header_stream_id_ = stream_id; |
| 541 header_control_type_ = header_control_type; | 537 header_control_type_ = header_control_type; |
| 542 header_buffer_valid_ = true; | 538 header_buffer_valid_ = true; |
| 543 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); | 539 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 544 } | 540 } |
| 545 | 541 |
| 546 void set_extension_visitor(ExtensionVisitorInterface* extension) { | 542 void set_extension_visitor(ExtensionVisitorInterface* extension) { |
| 547 framer_.set_extension_visitor(extension); | 543 framer_.set_extension_visitor(extension); |
| 548 } | 544 } |
| 549 | 545 |
| 550 // Override the default buffer size (16K). Call before using the framer! | 546 // Override the default buffer size (16K). Call before using the framer! |
| 551 void set_header_buffer_size(size_t header_buffer_size) { | 547 void set_header_buffer_size(size_t header_buffer_size) { |
| 552 header_buffer_size_ = header_buffer_size; | 548 header_buffer_.resize(header_buffer_size); |
| 553 header_buffer_.reset(new char[header_buffer_size]); | |
| 554 } | 549 } |
| 555 | 550 |
| 556 // Largest control frame that the SPDY implementation sends, including the | 551 // Largest control frame that the SPDY implementation sends, including the |
| 557 // size of the header. | 552 // size of the header. |
| 558 static size_t sent_control_frame_max_size() { | 553 static size_t sent_control_frame_max_size() { |
| 559 return SpdyFramer::kMaxControlFrameSize; | 554 return SpdyFramer::kMaxControlFrameSize; |
| 560 } | 555 } |
| 561 | 556 |
| 562 // Largest control frame that the SPDY implementation is willing to receive, | 557 // Largest control frame that the SPDY implementation is willing to receive, |
| 563 // excluding the size of the header. | 558 // excluding the size of the header. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 593 int fin_flag_count_; // The count of frames with the FIN flag set. | 588 int fin_flag_count_; // The count of frames with the FIN flag set. |
| 594 int end_of_stream_count_; // The count of zero-length data frames. | 589 int end_of_stream_count_; // The count of zero-length data frames. |
| 595 int control_frame_header_data_count_; // The count of chunks received. | 590 int control_frame_header_data_count_; // The count of chunks received. |
| 596 // The count of zero-length control frame header data chunks received. | 591 // The count of zero-length control frame header data chunks received. |
| 597 int zero_length_control_frame_header_data_count_; | 592 int zero_length_control_frame_header_data_count_; |
| 598 int data_frame_count_; | 593 int data_frame_count_; |
| 599 size_t last_payload_len_; | 594 size_t last_payload_len_; |
| 600 size_t last_frame_len_; | 595 size_t last_frame_len_; |
| 601 | 596 |
| 602 // Header block streaming state: | 597 // Header block streaming state: |
| 603 std::unique_ptr<char[]> header_buffer_; | 598 std::vector<char> header_buffer_; |
| 604 size_t header_buffer_length_; | 599 size_t header_buffer_length_; |
| 605 size_t header_buffer_size_; | |
| 606 size_t header_bytes_received_; | 600 size_t header_bytes_received_; |
| 607 SpdyStreamId header_stream_id_; | 601 SpdyStreamId header_stream_id_; |
| 608 SpdyFrameType header_control_type_; | 602 SpdyFrameType header_control_type_; |
| 609 bool header_buffer_valid_; | 603 bool header_buffer_valid_; |
| 610 std::unique_ptr<TestHeadersHandler> headers_handler_; | 604 std::unique_ptr<TestHeadersHandler> headers_handler_; |
| 611 SpdyHeaderBlock headers_; | 605 SpdyHeaderBlock headers_; |
| 612 bool header_has_priority_; | 606 bool header_has_priority_; |
| 613 SpdyStreamId header_parent_stream_id_; | 607 SpdyStreamId header_parent_stream_id_; |
| 614 bool header_exclusive_; | 608 bool header_exclusive_; |
| 615 }; | 609 }; |
| (...skipping 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2863 headers.SetHeader("aa", big_value); | 2857 headers.SetHeader("aa", big_value); |
| 2864 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( | 2858 SpdySerializedFrame control_frame(SpdyFramerPeer::SerializeHeaders( |
| 2865 &framer, headers, use_output_ ? &output_ : nullptr)); | 2859 &framer, headers, use_output_ ? &output_ : nullptr)); |
| 2866 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); | 2860 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); |
| 2867 visitor.set_header_buffer_size(kHeaderBufferSize); | 2861 visitor.set_header_buffer_size(kHeaderBufferSize); |
| 2868 visitor.SimulateInFramer( | 2862 visitor.SimulateInFramer( |
| 2869 reinterpret_cast<unsigned char*>(control_frame.data()), | 2863 reinterpret_cast<unsigned char*>(control_frame.data()), |
| 2870 control_frame.size()); | 2864 control_frame.size()); |
| 2871 // It's up to the visitor to ignore extraneous header data; the framer | 2865 // It's up to the visitor to ignore extraneous header data; the framer |
| 2872 // won't throw an error. | 2866 // won't throw an error. |
| 2873 EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_size_); | 2867 EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_.size()); |
| 2874 EXPECT_EQ(1, visitor.end_of_stream_count_); | 2868 EXPECT_EQ(1, visitor.end_of_stream_count_); |
| 2875 } | 2869 } |
| 2876 | 2870 |
| 2877 TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) { | 2871 TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) { |
| 2878 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 2872 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 2879 // Create a GoAway frame that has a few extra bytes at the end. | 2873 // Create a GoAway frame that has a few extra bytes at the end. |
| 2880 // We create enough overhead to overflow the framer's control frame buffer. | 2874 // We create enough overhead to overflow the framer's control frame buffer. |
| 2881 ASSERT_LE(SpdyFramerPeer::ControlFrameBufferSize(), 250u); | 2875 ASSERT_LE(SpdyFramerPeer::ControlFrameBufferSize(), 250u); |
| 2882 const size_t length = SpdyFramerPeer::ControlFrameBufferSize() + 1; | 2876 const size_t length = SpdyFramerPeer::ControlFrameBufferSize() + 1; |
| 2883 | 2877 |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4027 SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex | 4021 SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex |
| 4028 << static_cast<int>(flags)); | 4022 << static_cast<int>(flags)); |
| 4029 | 4023 |
| 4030 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; | 4024 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; |
| 4031 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 4025 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 4032 framer.set_visitor(&visitor); | 4026 framer.set_visitor(&visitor); |
| 4033 | 4027 |
| 4034 SpdySerializedFrame frame(framer.SerializePing(SpdyPingIR(42))); | 4028 SpdySerializedFrame frame(framer.SerializePing(SpdyPingIR(42))); |
| 4035 SetFrameFlags(&frame, flags); | 4029 SetFrameFlags(&frame, flags); |
| 4036 | 4030 |
| 4037 if (flags & PING_FLAG_ACK) { | 4031 EXPECT_CALL(visitor, OnPing(42, flags & PING_FLAG_ACK)); |
| 4038 EXPECT_CALL(visitor, OnPing(42, true)); | |
| 4039 } else { | |
| 4040 EXPECT_CALL(visitor, OnPing(42, false)); | |
| 4041 } | |
| 4042 | 4032 |
| 4043 framer.ProcessInput(frame.data(), frame.size()); | 4033 framer.ProcessInput(frame.data(), frame.size()); |
| 4044 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 4034 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
| 4045 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.spdy_framer_error()) | 4035 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.spdy_framer_error()) |
| 4046 << SpdyFramer::SpdyFramerErrorToString(framer.spdy_framer_error()); | 4036 << SpdyFramer::SpdyFramerErrorToString(framer.spdy_framer_error()); |
| 4047 } while (++flags != 0); | 4037 } while (++flags != 0); |
| 4048 } | 4038 } |
| 4049 | 4039 |
| 4050 TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) { | 4040 TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) { |
| 4051 uint8_t flags = 0; | 4041 uint8_t flags = 0; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4384 EXPECT_EQ(1, visitor.altsvc_count_); | 4374 EXPECT_EQ(1, visitor.altsvc_count_); |
| 4385 ASSERT_EQ(2u, visitor.test_altsvc_ir_.altsvc_vector().size()); | 4375 ASSERT_EQ(2u, visitor.test_altsvc_ir_.altsvc_vector().size()); |
| 4386 EXPECT_TRUE(visitor.test_altsvc_ir_.altsvc_vector()[0] == altsvc1); | 4376 EXPECT_TRUE(visitor.test_altsvc_ir_.altsvc_vector()[0] == altsvc1); |
| 4387 EXPECT_TRUE(visitor.test_altsvc_ir_.altsvc_vector()[1] == altsvc2); | 4377 EXPECT_TRUE(visitor.test_altsvc_ir_.altsvc_vector()[1] == altsvc2); |
| 4388 } | 4378 } |
| 4389 | 4379 |
| 4390 // While RFC7838 Section 4 says that an ALTSVC frame on stream 0 with empty | 4380 // While RFC7838 Section 4 says that an ALTSVC frame on stream 0 with empty |
| 4391 // origin MUST be ignored, it is not implemented at the framer level: instead, | 4381 // origin MUST be ignored, it is not implemented at the framer level: instead, |
| 4392 // such frames are passed on to the consumer. | 4382 // such frames are passed on to the consumer. |
| 4393 TEST_P(SpdyFramerTest, ReadAltSvcFrame) { | 4383 TEST_P(SpdyFramerTest, ReadAltSvcFrame) { |
| 4394 struct { | 4384 constexpr struct { |
| 4395 uint32_t stream_id; | 4385 uint32_t stream_id; |
| 4396 const char* origin; | 4386 const char* origin; |
| 4397 } test_cases[] = {{0, ""}, | 4387 } test_cases[] = {{0, ""}, |
| 4398 {1, ""}, | 4388 {1, ""}, |
| 4399 {0, "https://www.example.com"}, | 4389 {0, "https://www.example.com"}, |
| 4400 {1, "https://www.example.com"}}; | 4390 {1, "https://www.example.com"}}; |
| 4401 for (auto test_case : test_cases) { | 4391 for (const auto& test_case : test_cases) { |
| 4402 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 4392 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 4403 SpdyAltSvcIR altsvc_ir(test_case.stream_id); | 4393 SpdyAltSvcIR altsvc_ir(test_case.stream_id); |
| 4404 SpdyAltSvcWireFormat::AlternativeService altsvc( | 4394 SpdyAltSvcWireFormat::AlternativeService altsvc( |
| 4405 "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()); | 4395 "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()); |
| 4406 altsvc_ir.add_altsvc(altsvc); | 4396 altsvc_ir.add_altsvc(altsvc); |
| 4407 altsvc_ir.set_origin(test_case.origin); | 4397 altsvc_ir.set_origin(test_case.origin); |
| 4408 SpdySerializedFrame frame(framer.SerializeAltSvc(altsvc_ir)); | 4398 SpdySerializedFrame frame(framer.SerializeAltSvc(altsvc_ir)); |
| 4409 | 4399 |
| 4410 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); | 4400 TestSpdyVisitor visitor(SpdyFramer::ENABLE_COMPRESSION); |
| 4411 framer.set_visitor(&visitor); | 4401 framer.set_visitor(&visitor); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4571 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_SIZE, | 4561 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_SIZE, |
| 4572 visitor.framer_.spdy_framer_error()) | 4562 visitor.framer_.spdy_framer_error()) |
| 4573 << SpdyFramer::SpdyFramerErrorToString( | 4563 << SpdyFramer::SpdyFramerErrorToString( |
| 4574 visitor.framer_.spdy_framer_error()); | 4564 visitor.framer_.spdy_framer_error()); |
| 4575 } | 4565 } |
| 4576 | 4566 |
| 4577 // Test that SpdyFramer processes, by default, all passed input in one call | 4567 // Test that SpdyFramer processes, by default, all passed input in one call |
| 4578 // to ProcessInput (i.e. will not be calling set_process_single_input_frame()). | 4568 // to ProcessInput (i.e. will not be calling set_process_single_input_frame()). |
| 4579 TEST_P(SpdyFramerTest, ProcessAllInput) { | 4569 TEST_P(SpdyFramerTest, ProcessAllInput) { |
| 4580 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 4570 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 4581 std::unique_ptr<TestSpdyVisitor> visitor( | 4571 auto visitor = |
| 4582 new TestSpdyVisitor(SpdyFramer::DISABLE_COMPRESSION)); | 4572 base::MakeUnique<TestSpdyVisitor>(SpdyFramer::DISABLE_COMPRESSION); |
| 4583 framer.set_visitor(visitor.get()); | 4573 framer.set_visitor(visitor.get()); |
| 4584 | 4574 |
| 4585 // Create two input frames. | 4575 // Create two input frames. |
| 4586 SpdyHeadersIR headers(1); | 4576 SpdyHeadersIR headers(1); |
| 4587 headers.SetHeader("alpha", "beta"); | 4577 headers.SetHeader("alpha", "beta"); |
| 4588 headers.SetHeader("gamma", "charlie"); | 4578 headers.SetHeader("gamma", "charlie"); |
| 4589 headers.SetHeader("cookie", "key1=value1; key2=value2"); | 4579 headers.SetHeader("cookie", "key1=value1; key2=value2"); |
| 4590 SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders( | 4580 SpdySerializedFrame headers_frame(SpdyFramerPeer::SerializeHeaders( |
| 4591 &framer, headers, use_output_ ? &output_ : nullptr)); | 4581 &framer, headers, use_output_ ? &output_ : nullptr)); |
| 4592 | 4582 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4622 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); | 4612 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); |
| 4623 } | 4613 } |
| 4624 | 4614 |
| 4625 // Test that SpdyFramer stops after processing a full frame if | 4615 // Test that SpdyFramer stops after processing a full frame if |
| 4626 // process_single_input_frame is set. Input to ProcessInput has two frames, but | 4616 // process_single_input_frame is set. Input to ProcessInput has two frames, but |
| 4627 // only processes the first when we give it the first frame split at any point, | 4617 // only processes the first when we give it the first frame split at any point, |
| 4628 // or give it more than one frame in the input buffer. | 4618 // or give it more than one frame in the input buffer. |
| 4629 TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { | 4619 TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { |
| 4630 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); | 4620 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); |
| 4631 framer.set_process_single_input_frame(true); | 4621 framer.set_process_single_input_frame(true); |
| 4632 std::unique_ptr<TestSpdyVisitor> visitor; | |
| 4633 | 4622 |
| 4634 // Create two input frames. | 4623 // Create two input frames. |
| 4635 const char four_score[] = "Four score and ..."; | 4624 const char four_score[] = "Four score and ..."; |
| 4636 SpdyDataIR four_score_ir(1, four_score); | 4625 SpdyDataIR four_score_ir(1, four_score); |
| 4637 SpdySerializedFrame four_score_frame(framer.SerializeData(four_score_ir)); | 4626 SpdySerializedFrame four_score_frame(framer.SerializeData(four_score_ir)); |
| 4638 | 4627 |
| 4639 SpdyHeadersIR headers(2); | 4628 SpdyHeadersIR headers(2); |
| 4640 headers.SetHeader("alpha", "beta"); | 4629 headers.SetHeader("alpha", "beta"); |
| 4641 headers.SetHeader("gamma", "charlie"); | 4630 headers.SetHeader("gamma", "charlie"); |
| 4642 headers.SetHeader("cookie", "key1=value1; key2=value2"); | 4631 headers.SetHeader("cookie", "key1=value1; key2=value2"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4658 input_buffer.append(frame1.data(), frame1_size); | 4647 input_buffer.append(frame1.data(), frame1_size); |
| 4659 input_buffer.append(frame2.data(), frame2_size); | 4648 input_buffer.append(frame2.data(), frame2_size); |
| 4660 | 4649 |
| 4661 const char* buf = input_buffer.data(); | 4650 const char* buf = input_buffer.data(); |
| 4662 const size_t buf_size = input_buffer.size(); | 4651 const size_t buf_size = input_buffer.size(); |
| 4663 | 4652 |
| 4664 VLOG(1) << "buf_size = " << buf_size; | 4653 VLOG(1) << "buf_size = " << buf_size; |
| 4665 | 4654 |
| 4666 for (size_t first_size = 0; first_size <= buf_size; ++first_size) { | 4655 for (size_t first_size = 0; first_size <= buf_size; ++first_size) { |
| 4667 VLOG(1) << "first_size = " << first_size; | 4656 VLOG(1) << "first_size = " << first_size; |
| 4668 visitor.reset(new TestSpdyVisitor(SpdyFramer::DISABLE_COMPRESSION)); | 4657 auto visitor = |
| 4658 base::MakeUnique<TestSpdyVisitor>(SpdyFramer::DISABLE_COMPRESSION); |
| 4669 framer.set_visitor(visitor.get()); | 4659 framer.set_visitor(visitor.get()); |
| 4670 | 4660 |
| 4671 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 4661 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
| 4672 | 4662 |
| 4673 size_t processed_first = framer.ProcessInput(buf, first_size); | 4663 size_t processed_first = framer.ProcessInput(buf, first_size); |
| 4674 if (first_size < frame1_size) { | 4664 if (first_size < frame1_size) { |
| 4675 EXPECT_EQ(first_size, processed_first); | 4665 EXPECT_EQ(first_size, processed_first); |
| 4676 | 4666 |
| 4677 if (first_size == 0) { | 4667 if (first_size == 0) { |
| 4678 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 4668 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4701 | 4691 |
| 4702 EXPECT_EQ(1, visitor->data_frame_count_); | 4692 EXPECT_EQ(1, visitor->data_frame_count_); |
| 4703 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); | 4693 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); |
| 4704 EXPECT_EQ(0, visitor->headers_frame_count_); | 4694 EXPECT_EQ(0, visitor->headers_frame_count_); |
| 4705 } | 4695 } |
| 4706 } | 4696 } |
| 4707 | 4697 |
| 4708 } // namespace test | 4698 } // namespace test |
| 4709 | 4699 |
| 4710 } // namespace net | 4700 } // namespace net |
| OLD | NEW |