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> |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 public: | 53 public: |
54 // Decompress a single frame using the decompression context held by | 54 // Decompress a single frame using the decompression context held by |
55 // the SpdyFramer. The implemention is meant for use only in tests | 55 // the SpdyFramer. The implemention is meant for use only in tests |
56 // and will CHECK fail if the input is anything other than a single, | 56 // and will CHECK fail if the input is anything other than a single, |
57 // well-formed compressed frame. | 57 // well-formed compressed frame. |
58 // | 58 // |
59 // Returns a new decompressed SpdySerializedFrame. | 59 // Returns a new decompressed SpdySerializedFrame. |
60 template <class SpdyFrameType> | 60 template <class SpdyFrameType> |
61 static SpdySerializedFrame DecompressFrame(SpdyFramer* framer, | 61 static SpdySerializedFrame DecompressFrame(SpdyFramer* framer, |
62 const SpdyFrameType& frame) { | 62 const SpdyFrameType& frame) { |
63 NewDecompressionVisitor visitor; | 63 DecompressionVisitor visitor(framer->protocol_version()); |
64 framer->set_visitor(&visitor); | 64 framer->set_visitor(&visitor); |
65 CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size())); | 65 CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size())); |
66 CHECK_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer->state()); | 66 CHECK_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer->state()); |
67 framer->set_visitor(nullptr); | 67 framer->set_visitor(NULL); |
68 SpdyFramer serializer(framer->protocol_version()); | 68 |
69 serializer.set_enable_compression(false); | 69 char* buffer = visitor.ReleaseBuffer(); |
70 return serializer.SerializeFrame(visitor.GetFrame()); | 70 CHECK(buffer != NULL); |
| 71 SpdySerializedFrame decompressed_frame(buffer, visitor.size(), true); |
| 72 SetFrameLength(&decompressed_frame, |
| 73 visitor.size() - framer->GetControlFrameHeaderSize(), |
| 74 framer->protocol_version()); |
| 75 return decompressed_frame; |
71 } | 76 } |
72 | 77 |
73 class NewDecompressionVisitor : public SpdyFramerVisitorInterface { | 78 class DecompressionVisitor : public SpdyFramerVisitorInterface { |
74 public: | 79 public: |
75 NewDecompressionVisitor() : finished_(false) {} | 80 explicit DecompressionVisitor(SpdyMajorVersion version) |
| 81 : version_(version), size_(0), finished_(false) {} |
76 | 82 |
77 const SpdyFrameIR& GetFrame() const { | 83 void ResetBuffer() { |
78 CHECK(finished_); | 84 CHECK(buffer_.get() == NULL); |
79 return *frame_; | 85 CHECK_EQ(0u, size_); |
| 86 CHECK(!finished_); |
| 87 buffer_.reset(new char[kMaxDecompressedSize]); |
80 } | 88 } |
81 | 89 |
82 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | |
83 SpdyStreamId stream_id) override { | |
84 if (headers_handler_ == nullptr) { | |
85 headers_handler_.reset(new TestHeadersHandler); | |
86 } | |
87 return headers_handler_.get(); | |
88 } | |
89 | |
90 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | |
91 CHECK(!finished_); | |
92 frame_->set_header_block(headers_handler_->decoded_block()); | |
93 finished_ = true; | |
94 if (end_headers) { | |
95 headers_handler_.reset(); | |
96 } | |
97 } | |
98 | |
99 void OnSynStream(SpdyStreamId stream_id, | |
100 SpdyStreamId associated_stream_id, | |
101 SpdyPriority priority, | |
102 bool fin, | |
103 bool unidirectional) override { | |
104 SpdySynStreamIR* syn_stream = new SpdySynStreamIR(stream_id); | |
105 syn_stream->set_associated_to_stream_id(associated_stream_id); | |
106 syn_stream->set_priority(priority); | |
107 syn_stream->set_fin(fin); | |
108 syn_stream->set_unidirectional(unidirectional); | |
109 frame_.reset(syn_stream); | |
110 } | |
111 | |
112 void OnSynReply(SpdyStreamId stream_id, bool fin) override { | |
113 SpdyHeadersIR* headers = new SpdyHeadersIR(stream_id); | |
114 headers->set_fin(fin); | |
115 frame_.reset(headers); | |
116 } | |
117 | |
118 void OnHeaders(SpdyStreamId stream_id, | |
119 bool has_priority, | |
120 SpdyPriority priority, | |
121 SpdyStreamId parent_stream_id, | |
122 bool exclusive, | |
123 bool fin, | |
124 bool end) override { | |
125 SpdyHeadersIR* headers = new SpdyHeadersIR(stream_id); | |
126 headers->set_has_priority(has_priority); | |
127 headers->set_priority(priority); | |
128 headers->set_parent_stream_id(parent_stream_id); | |
129 headers->set_exclusive(exclusive); | |
130 headers->set_fin(fin); | |
131 frame_.reset(headers); | |
132 } | |
133 | |
134 void OnPushPromise(SpdyStreamId stream_id, | |
135 SpdyStreamId promised_stream_id, | |
136 bool end) override { | |
137 SpdyPushPromiseIR* push_promise = | |
138 new SpdyPushPromiseIR(stream_id, promised_stream_id); | |
139 frame_.reset(push_promise); | |
140 } | |
141 | |
142 // TODO(birenroy): Add support for CONTINUATION. | |
143 void OnContinuation(SpdyStreamId stream_id, bool end) override { | |
144 LOG(FATAL); | |
145 } | |
146 | |
147 // All other methods just LOG(FATAL). | |
148 void OnError(SpdyFramer* framer) override { LOG(FATAL); } | 90 void OnError(SpdyFramer* framer) override { LOG(FATAL); } |
149 void OnDataFrameHeader(SpdyStreamId stream_id, | 91 void OnDataFrameHeader(SpdyStreamId stream_id, |
150 size_t length, | 92 size_t length, |
151 bool fin) override { | 93 bool fin) override { |
152 LOG(FATAL) << "Unexpected data frame header"; | 94 LOG(FATAL) << "Unexpected data frame header"; |
153 } | 95 } |
154 void OnStreamFrameData(SpdyStreamId stream_id, | 96 void OnStreamFrameData(SpdyStreamId stream_id, |
155 const char* data, | 97 const char* data, |
156 size_t len) override { | 98 size_t len) override { |
157 LOG(FATAL); | 99 LOG(FATAL); |
158 } | 100 } |
159 | 101 |
160 void OnStreamEnd(SpdyStreamId stream_id) override { LOG(FATAL); } | 102 void OnStreamEnd(SpdyStreamId stream_id) override { LOG(FATAL); } |
161 | 103 |
162 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | 104 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { |
163 LOG(FATAL); | 105 LOG(FATAL); |
164 } | 106 } |
165 | 107 |
166 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | |
167 const char* header_data, | |
168 size_t len) override { | |
169 LOG(FATAL); | |
170 return true; | |
171 } | |
172 | |
173 void OnRstStream(SpdyStreamId stream_id, | |
174 SpdyRstStreamStatus status) override { | |
175 LOG(FATAL); | |
176 } | |
177 void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override { | |
178 LOG(FATAL); | |
179 } | |
180 void OnPing(SpdyPingId unique_id, bool is_ack) override { LOG(FATAL); } | |
181 void OnSettingsEnd() override { LOG(FATAL); } | |
182 void OnGoAway(SpdyStreamId last_accepted_stream_id, | |
183 SpdyGoAwayStatus status) override { | |
184 LOG(FATAL); | |
185 } | |
186 | |
187 void OnWindowUpdate(SpdyStreamId stream_id, | |
188 int delta_window_size) override { | |
189 LOG(FATAL); | |
190 } | |
191 | |
192 void OnPriority(SpdyStreamId stream_id, | |
193 SpdyStreamId parent_stream_id, | |
194 uint8_t weight, | |
195 bool exclusive) override { | |
196 // Do nothing. | |
197 } | |
198 | |
199 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { | |
200 LOG(FATAL); | |
201 return false; | |
202 } | |
203 | |
204 private: | |
205 std::unique_ptr<TestHeadersHandler> headers_handler_; | |
206 std::unique_ptr<SpdyFrameWithHeaderBlockIR> frame_; | |
207 bool finished_; | |
208 | |
209 DISALLOW_COPY_AND_ASSIGN(NewDecompressionVisitor); | |
210 }; | |
211 | |
212 class DecompressionVisitor : public SpdyFramerVisitorInterface { | |
213 public: | |
214 explicit DecompressionVisitor(SpdyMajorVersion version) | |
215 : version_(version), size_(0), finished_(false) {} | |
216 | |
217 void ResetBuffer() { | |
218 CHECK(buffer_.get() == NULL); | |
219 CHECK_EQ(0u, size_); | |
220 CHECK(!finished_); | |
221 buffer_.reset(new char[kMaxDecompressedSize]); | |
222 } | |
223 | |
224 void OnError(SpdyFramer* framer) override { LOG(FATAL); } | |
225 void OnDataFrameHeader(SpdyStreamId stream_id, | |
226 size_t length, | |
227 bool fin) override { | |
228 LOG(FATAL) << "Unexpected data frame header"; | |
229 } | |
230 void OnStreamFrameData(SpdyStreamId stream_id, | |
231 const char* data, | |
232 size_t len) override { | |
233 LOG(FATAL); | |
234 } | |
235 | |
236 void OnStreamEnd(SpdyStreamId stream_id) override { LOG(FATAL); } | |
237 | |
238 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | |
239 LOG(FATAL); | |
240 } | |
241 | |
242 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | 108 SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
243 SpdyStreamId stream_id) override { | 109 SpdyStreamId stream_id) override { |
244 LOG(FATAL) << "Not implemented."; | 110 LOG(FATAL); |
245 return nullptr; | 111 return nullptr; |
246 } | 112 } |
247 | 113 |
248 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | 114 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { |
249 LOG(FATAL) << "Not implemented."; | 115 LOG(FATAL); |
250 } | 116 } |
251 | 117 |
252 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | 118 bool OnControlFrameHeaderData(SpdyStreamId stream_id, |
253 const char* header_data, | 119 const char* header_data, |
254 size_t len) override { | 120 size_t len) override { |
255 CHECK(buffer_.get() != NULL); | 121 CHECK(buffer_.get() != NULL); |
256 CHECK_GE(kMaxDecompressedSize, size_ + len); | 122 CHECK_GE(kMaxDecompressedSize, size_ + len); |
257 CHECK(!finished_); | 123 CHECK(!finished_); |
258 if (len != 0) { | 124 if (len != 0) { |
259 memcpy(buffer_.get() + size_, header_data, len); | 125 memcpy(buffer_.get() + size_, header_data, len); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 return buffer_.release(); | 233 return buffer_.release(); |
368 } | 234 } |
369 | 235 |
370 size_t size() const { | 236 size_t size() const { |
371 CHECK(finished_); | 237 CHECK(finished_); |
372 return size_; | 238 return size_; |
373 } | 239 } |
374 | 240 |
375 private: | 241 private: |
376 SpdyMajorVersion version_; | 242 SpdyMajorVersion version_; |
377 TestHeadersHandler* headers_handler_; | |
378 std::unique_ptr<char[]> buffer_; | 243 std::unique_ptr<char[]> buffer_; |
379 size_t size_; | 244 size_t size_; |
380 bool finished_; | 245 bool finished_; |
381 | 246 |
382 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); | 247 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); |
383 }; | 248 }; |
384 | 249 |
385 private: | 250 private: |
386 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); | 251 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); |
387 }; | 252 }; |
388 | 253 |
389 class SpdyFramerPeer { | |
390 public: | |
391 static size_t ControlFrameBufferSize() { | |
392 return SpdyFramer::kControlFrameBufferSize; | |
393 } | |
394 static size_t GetNumberRequiredContinuationFrames(SpdyFramer* framer, | |
395 size_t size) { | |
396 return framer->GetNumberRequiredContinuationFrames(size); | |
397 } | |
398 static void SetError(SpdyFramer* framer, SpdyFramer::SpdyError error) { | |
399 framer->set_error(error); | |
400 } | |
401 }; | |
402 | |
403 class TestSpdyVisitor : public SpdyFramerVisitorInterface, | 254 class TestSpdyVisitor : public SpdyFramerVisitorInterface, |
404 public SpdyFramerDebugVisitorInterface { | 255 public SpdyFramerDebugVisitorInterface { |
405 public: | 256 public: |
406 // This is larger than our max frame size because header blocks that | 257 // This is larger than our max frame size because header blocks that |
407 // are too long can spill over into CONTINUATION frames. | 258 // are too long can spill over into CONTINUATION frames. |
408 static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024; | 259 static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024; |
409 | 260 |
410 explicit TestSpdyVisitor(SpdyMajorVersion version) | 261 explicit TestSpdyVisitor(SpdyMajorVersion version) |
411 : framer_(version), | 262 : framer_(version), |
412 use_compression_(false), | 263 use_compression_(false), |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 } | 328 } |
478 | 329 |
479 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | 330 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { |
480 VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; | 331 VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; |
481 EXPECT_EQ(header_stream_id_, stream_id); | 332 EXPECT_EQ(header_stream_id_, stream_id); |
482 data_bytes_ += len; | 333 data_bytes_ += len; |
483 } | 334 } |
484 | 335 |
485 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | 336 SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
486 SpdyStreamId stream_id) override { | 337 SpdyStreamId stream_id) override { |
487 if (headers_handler_ == nullptr) { | 338 LOG(FATAL) << "OnHeaderFrameStart(" << stream_id << ")"; |
488 headers_handler_.reset(new TestHeadersHandler); | 339 return nullptr; |
489 } | |
490 return headers_handler_.get(); | |
491 } | 340 } |
492 | 341 |
493 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | 342 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { |
494 CHECK(headers_handler_ != nullptr); | 343 LOG(FATAL) << "OnHeaderFrameEnd(" << stream_id << ", " << end_headers |
495 headers_ = headers_handler_->decoded_block(); | 344 << ")"; |
496 header_bytes_received_ = headers_handler_->header_bytes_parsed(); | |
497 if (end_headers) { | |
498 headers_handler_.reset(); | |
499 } | |
500 } | 345 } |
501 | 346 |
502 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | 347 bool OnControlFrameHeaderData(SpdyStreamId stream_id, |
503 const char* header_data, | 348 const char* header_data, |
504 size_t len) override { | 349 size_t len) override { |
505 VLOG(1) << "OnControlFrameHeaderData(" << stream_id << ", data, " << len | 350 VLOG(1) << "OnControlFrameHeaderData(" << stream_id << ", data, " << len |
506 << ")"; | 351 << ")"; |
507 ++control_frame_header_data_count_; | 352 ++control_frame_header_data_count_; |
508 CHECK_EQ(header_stream_id_, stream_id); | 353 CHECK_EQ(header_stream_id_, stream_id); |
509 if (len == 0) { | 354 if (len == 0) { |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 // The count of zero-length control frame header data chunks received. | 624 // The count of zero-length control frame header data chunks received. |
780 int zero_length_control_frame_header_data_count_; | 625 int zero_length_control_frame_header_data_count_; |
781 int data_frame_count_; | 626 int data_frame_count_; |
782 size_t last_payload_len_; | 627 size_t last_payload_len_; |
783 size_t last_frame_len_; | 628 size_t last_frame_len_; |
784 | 629 |
785 // Header block streaming state: | 630 // Header block streaming state: |
786 std::unique_ptr<char[]> header_buffer_; | 631 std::unique_ptr<char[]> header_buffer_; |
787 size_t header_buffer_length_; | 632 size_t header_buffer_length_; |
788 size_t header_buffer_size_; | 633 size_t header_buffer_size_; |
789 size_t header_bytes_received_; | |
790 SpdyStreamId header_stream_id_; | 634 SpdyStreamId header_stream_id_; |
791 SpdyFrameType header_control_type_; | 635 SpdyFrameType header_control_type_; |
792 bool header_buffer_valid_; | 636 bool header_buffer_valid_; |
793 std::unique_ptr<TestHeadersHandler> headers_handler_; | |
794 SpdyHeaderBlock headers_; | 637 SpdyHeaderBlock headers_; |
795 bool header_has_priority_; | 638 bool header_has_priority_; |
796 SpdyStreamId header_parent_stream_id_; | 639 SpdyStreamId header_parent_stream_id_; |
797 bool header_exclusive_; | 640 bool header_exclusive_; |
798 }; | 641 }; |
799 | 642 |
| 643 class SpdyFramerPeer { |
| 644 public: |
| 645 static size_t ControlFrameBufferSize() { |
| 646 return SpdyFramer::kControlFrameBufferSize; |
| 647 } |
| 648 static size_t GetNumberRequiredContinuationFrames(SpdyFramer* framer, |
| 649 size_t size) { |
| 650 return framer->GetNumberRequiredContinuationFrames(size); |
| 651 } |
| 652 }; |
| 653 |
800 // Retrieves serialized headers from a HEADERS or SYN_STREAM frame. | 654 // Retrieves serialized headers from a HEADERS or SYN_STREAM frame. |
801 StringPiece GetSerializedHeaders(const SpdySerializedFrame& frame, | 655 StringPiece GetSerializedHeaders(const SpdySerializedFrame& frame, |
802 const SpdyFramer& framer) { | 656 const SpdyFramer& framer) { |
803 SpdyFrameReader reader(frame.data(), frame.size()); | 657 SpdyFrameReader reader(frame.data(), frame.size()); |
804 if (framer.protocol_version() == SPDY3) { | 658 if (framer.protocol_version() == SPDY3) { |
805 reader.Seek(2); // Seek past the frame length. | 659 reader.Seek(2); // Seek past the frame length. |
806 } else { | 660 } else { |
807 reader.Seek(3); // Seek past the frame length. | 661 reader.Seek(3); // Seek past the frame length. |
808 } | 662 } |
809 SpdyFrameType frame_type; | 663 SpdyFrameType frame_type; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 headers.set_priority(1); | 741 headers.set_priority(1); |
888 headers.SetHeader("cookie", | 742 headers.SetHeader("cookie", |
889 "=; key=value; ; = ; foo; bar=; ; = ; k2=v2 ; ="); | 743 "=; key=value; ; = ; foo; bar=; ; = ; k2=v2 ; ="); |
890 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); | 744 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); |
891 | 745 |
892 TestSpdyVisitor visitor(spdy_version_); | 746 TestSpdyVisitor visitor(spdy_version_); |
893 visitor.use_compression_ = true; | 747 visitor.use_compression_ = true; |
894 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), | 748 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), |
895 frame.size()); | 749 frame.size()); |
896 | 750 |
897 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 751 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
898 EXPECT_NE(headers.header_block(), visitor.headers_); | 752 EXPECT_NE(headers.header_block(), visitor.headers_); |
899 EXPECT_EQ(1u, visitor.headers_.size()); | 753 EXPECT_EQ(1u, visitor.headers_.size()); |
900 EXPECT_EQ("key=value; foo; bar=; k2=v2 ", visitor.headers_["cookie"]); | 754 EXPECT_EQ("key=value; foo; bar=; k2=v2 ", visitor.headers_["cookie"]); |
901 } | 755 } |
902 | 756 |
903 // Test that we can encode and decode a SpdyHeaderBlock in serialized form. | 757 // Test that we can encode and decode a SpdyHeaderBlock in serialized form. |
904 TEST_P(SpdyFramerTest, HeaderBlockInBuffer) { | 758 TEST_P(SpdyFramerTest, HeaderBlockInBuffer) { |
905 SpdyFramer framer(spdy_version_); | 759 SpdyFramer framer(spdy_version_); |
906 framer.set_enable_compression(false); | 760 framer.set_enable_compression(false); |
907 | 761 |
908 // Encode the header block into a Headers frame. | 762 // Encode the header block into a Headers frame. |
909 SpdyHeadersIR headers(1); | 763 SpdyHeadersIR headers(1); |
910 headers.set_priority(1); | 764 headers.set_priority(1); |
911 headers.SetHeader("alpha", "beta"); | 765 headers.SetHeader("alpha", "beta"); |
912 headers.SetHeader("gamma", "charlie"); | 766 headers.SetHeader("gamma", "charlie"); |
913 headers.SetHeader("cookie", "key1=value1; key2=value2"); | 767 headers.SetHeader("cookie", "key1=value1; key2=value2"); |
914 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); | 768 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); |
915 | 769 |
916 TestSpdyVisitor visitor(spdy_version_); | 770 TestSpdyVisitor visitor(spdy_version_); |
917 visitor.use_compression_ = false; | 771 visitor.use_compression_ = false; |
918 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), | 772 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), |
919 frame.size()); | 773 frame.size()); |
920 | 774 |
921 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 775 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
922 EXPECT_EQ(headers.header_block(), visitor.headers_); | 776 EXPECT_EQ(headers.header_block(), visitor.headers_); |
923 } | 777 } |
924 | 778 |
925 // Test that if there's not a full frame, we fail to parse it. | 779 // Test that if there's not a full frame, we fail to parse it. |
926 TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) { | 780 TEST_P(SpdyFramerTest, UndersizedHeaderBlockInBuffer) { |
927 SpdyFramer framer(spdy_version_); | 781 SpdyFramer framer(spdy_version_); |
928 framer.set_enable_compression(false); | 782 framer.set_enable_compression(false); |
929 | 783 |
930 // Encode the header block into a Headers frame. | 784 // Encode the header block into a Headers frame. |
931 SpdyHeadersIR headers(1); | 785 SpdyHeadersIR headers(1); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 0x08, // Flags (PADDED) | 928 0x08, // Flags (PADDED) |
1075 0x00, 0x00, 0x00, 0x01, // Stream id | 929 0x00, 0x00, 0x00, 0x01, // Stream id |
1076 0xFF, // Padding length (here larger than length) | 930 0xFF, // Padding length (here larger than length) |
1077 0x00, 0x00, 0x00, 0x00, // Arbitrary data payload | 931 0x00, 0x00, 0x00, 0x00, // Arbitrary data payload |
1078 }; | 932 }; |
1079 | 933 |
1080 SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData), | 934 SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData), |
1081 sizeof(kH2FrameData), false); | 935 sizeof(kH2FrameData), false); |
1082 | 936 |
1083 EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); | 937 EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); |
1084 EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1); | |
1085 EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); | 938 EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); |
1086 EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); | 939 EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); |
1087 EXPECT_TRUE(framer.HasError()); | 940 EXPECT_TRUE(framer.HasError()); |
1088 EXPECT_EQ(SpdyFramer::SPDY_INVALID_PADDING, framer.error_code()) | 941 EXPECT_EQ(SpdyFramer::SPDY_INVALID_PADDING, framer.error_code()) |
1089 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 942 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
1090 } | 943 } |
1091 | 944 |
1092 // Test that if we receive a HEADERS frame with padding length not larger | 945 // Test that if we receive a HEADERS frame with padding length not larger |
1093 // than the payload length, we do not set an error of SPDY_INVALID_PADDING | 946 // than the payload length, we do not set an error of SPDY_INVALID_PADDING |
1094 TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) { | 947 TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) { |
(...skipping 11 matching lines...) Expand all Loading... |
1106 0x01, // Type (HEADERS) | 959 0x01, // Type (HEADERS) |
1107 0x08, // Flags (PADDED) | 960 0x08, // Flags (PADDED) |
1108 0x00, 0x00, 0x00, 0x01, // Stream id | 961 0x00, 0x00, 0x00, 0x01, // Stream id |
1109 0x04, // Padding length | 962 0x04, // Padding length |
1110 0x00, 0x00, 0x00, 0x00, // Padding | 963 0x00, 0x00, 0x00, 0x00, // Padding |
1111 }; | 964 }; |
1112 | 965 |
1113 SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); | 966 SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); |
1114 | 967 |
1115 EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); | 968 EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); |
1116 EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1); | 969 |
1117 EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); | 970 EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); |
1118 EXPECT_FALSE(framer.HasError()); | 971 EXPECT_FALSE(framer.HasError()); |
1119 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 972 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
1120 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 973 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
1121 } | 974 } |
1122 | 975 |
1123 // Test that if we receive a SYN_REPLY with stream ID zero, we signal an error | 976 // Test that if we receive a SYN_REPLY with stream ID zero, we signal an error |
1124 // (but don't crash). | 977 // (but don't crash). |
1125 TEST_P(SpdyFramerTest, SynReplyWithStreamIdZero) { | 978 TEST_P(SpdyFramerTest, SynReplyWithStreamIdZero) { |
1126 if (!IsSpdy3()) { | 979 if (!IsSpdy3()) { |
(...skipping 2524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3651 headers_ir.SetHeader("alpha", "beta"); | 3504 headers_ir.SetHeader("alpha", "beta"); |
3652 headers_ir.SetHeader("gamma", "delta"); | 3505 headers_ir.SetHeader("gamma", "delta"); |
3653 SpdyHeaderBlock headers = headers_ir.header_block(); | 3506 SpdyHeaderBlock headers = headers_ir.header_block(); |
3654 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir)); | 3507 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir)); |
3655 TestSpdyVisitor visitor(spdy_version_); | 3508 TestSpdyVisitor visitor(spdy_version_); |
3656 visitor.use_compression_ = true; | 3509 visitor.use_compression_ = true; |
3657 visitor.SimulateInFramer( | 3510 visitor.SimulateInFramer( |
3658 reinterpret_cast<unsigned char*>(control_frame.data()), | 3511 reinterpret_cast<unsigned char*>(control_frame.data()), |
3659 control_frame.size()); | 3512 control_frame.size()); |
3660 EXPECT_EQ(1, visitor.headers_frame_count_); | 3513 EXPECT_EQ(1, visitor.headers_frame_count_); |
3661 EXPECT_EQ(0, visitor.control_frame_header_data_count_); | 3514 // control_frame_header_data_count_ depends on the random sequence |
3662 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 3515 // produced by rand(), so adding, removing or running single tests |
| 3516 // alters this value. The best we can do is assert that it happens |
| 3517 // at least twice. |
| 3518 EXPECT_LE(2, visitor.control_frame_header_data_count_); |
| 3519 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
3663 EXPECT_EQ(0, visitor.end_of_stream_count_); | 3520 EXPECT_EQ(0, visitor.end_of_stream_count_); |
3664 EXPECT_EQ(headers, visitor.headers_); | 3521 EXPECT_EQ(headers, visitor.headers_); |
3665 } | 3522 } |
3666 | 3523 |
3667 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) { | 3524 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) { |
3668 SpdyFramer framer(spdy_version_); | 3525 SpdyFramer framer(spdy_version_); |
3669 SpdyHeadersIR headers_ir(1); | 3526 SpdyHeadersIR headers_ir(1); |
3670 headers_ir.set_fin(true); | 3527 headers_ir.set_fin(true); |
3671 headers_ir.SetHeader("alpha", "beta"); | 3528 headers_ir.SetHeader("alpha", "beta"); |
3672 headers_ir.SetHeader("gamma", "delta"); | 3529 headers_ir.SetHeader("gamma", "delta"); |
3673 SpdyHeaderBlock headers = headers_ir.header_block(); | 3530 SpdyHeaderBlock headers = headers_ir.header_block(); |
3674 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir)); | 3531 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir)); |
3675 TestSpdyVisitor visitor(spdy_version_); | 3532 TestSpdyVisitor visitor(spdy_version_); |
3676 visitor.use_compression_ = true; | 3533 visitor.use_compression_ = true; |
3677 visitor.SimulateInFramer( | 3534 visitor.SimulateInFramer( |
3678 reinterpret_cast<unsigned char*>(control_frame.data()), | 3535 reinterpret_cast<unsigned char*>(control_frame.data()), |
3679 control_frame.size()); | 3536 control_frame.size()); |
3680 EXPECT_EQ(1, visitor.headers_frame_count_); | 3537 EXPECT_EQ(1, visitor.headers_frame_count_); |
3681 EXPECT_EQ(0, visitor.control_frame_header_data_count_); | 3538 // control_frame_header_data_count_ depends on the random sequence |
3682 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 3539 // produced by rand(), so adding, removing or running single tests |
| 3540 // alters this value. The best we can do is assert that it happens |
| 3541 // at least twice. |
| 3542 EXPECT_LE(2, visitor.control_frame_header_data_count_); |
| 3543 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
3683 EXPECT_EQ(1, visitor.end_of_stream_count_); | 3544 EXPECT_EQ(1, visitor.end_of_stream_count_); |
3684 EXPECT_EQ(headers, visitor.headers_); | 3545 EXPECT_EQ(headers, visitor.headers_); |
3685 } | 3546 } |
3686 | 3547 |
3687 TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) { | 3548 TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) { |
3688 if (!IsSpdy3()) { | 3549 if (!IsSpdy3()) { |
3689 // TODO(jgraettinger): This test setup doesn't work with HPACK. | 3550 // TODO(jgraettinger): This test setup doesn't work with HPACK. |
3690 return; | 3551 return; |
3691 } | 3552 } |
3692 | 3553 |
(...skipping 15 matching lines...) Expand all Loading... |
3708 EXPECT_EQ(TestSpdyVisitor::sent_control_frame_max_size(), | 3569 EXPECT_EQ(TestSpdyVisitor::sent_control_frame_max_size(), |
3709 control_frame.size()); | 3570 control_frame.size()); |
3710 | 3571 |
3711 TestSpdyVisitor visitor(spdy_version_); | 3572 TestSpdyVisitor visitor(spdy_version_); |
3712 visitor.SimulateInFramer( | 3573 visitor.SimulateInFramer( |
3713 reinterpret_cast<unsigned char*>(control_frame.data()), | 3574 reinterpret_cast<unsigned char*>(control_frame.data()), |
3714 control_frame.size()); | 3575 control_frame.size()); |
3715 EXPECT_TRUE(visitor.header_buffer_valid_); | 3576 EXPECT_TRUE(visitor.header_buffer_valid_); |
3716 EXPECT_EQ(0, visitor.error_count_); | 3577 EXPECT_EQ(0, visitor.error_count_); |
3717 EXPECT_EQ(1, visitor.syn_frame_count_); | 3578 EXPECT_EQ(1, visitor.syn_frame_count_); |
3718 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 3579 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
3719 EXPECT_EQ(0, visitor.end_of_stream_count_); | 3580 EXPECT_EQ(0, visitor.end_of_stream_count_); |
| 3581 EXPECT_LT(kBigValueSize, visitor.header_buffer_length_); |
3720 } | 3582 } |
3721 | 3583 |
3722 TEST_P(SpdyFramerTest, ControlFrameTooLarge) { | 3584 TEST_P(SpdyFramerTest, ControlFrameTooLarge) { |
3723 if (!IsSpdy3()) { | 3585 if (!IsSpdy3()) { |
3724 // TODO(jgraettinger): This test setup doesn't work with HPACK. | 3586 // TODO(jgraettinger): This test setup doesn't work with HPACK. |
3725 return; | 3587 return; |
3726 } | 3588 } |
3727 | 3589 |
3728 // First find the size of the header value in order to just reach the control | 3590 // First find the size of the header value in order to just reach the control |
3729 // frame max size. | 3591 // frame max size. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3784 TestSpdyVisitor::sent_control_frame_max_size()); | 3646 TestSpdyVisitor::sent_control_frame_max_size()); |
3785 | 3647 |
3786 TestSpdyVisitor visitor(spdy_version_); | 3648 TestSpdyVisitor visitor(spdy_version_); |
3787 visitor.SimulateInFramer( | 3649 visitor.SimulateInFramer( |
3788 reinterpret_cast<unsigned char*>(control_frame.data()), | 3650 reinterpret_cast<unsigned char*>(control_frame.data()), |
3789 control_frame.size()); | 3651 control_frame.size()); |
3790 EXPECT_TRUE(visitor.header_buffer_valid_); | 3652 EXPECT_TRUE(visitor.header_buffer_valid_); |
3791 EXPECT_EQ(0, visitor.error_count_); | 3653 EXPECT_EQ(0, visitor.error_count_); |
3792 EXPECT_EQ(1, visitor.headers_frame_count_); | 3654 EXPECT_EQ(1, visitor.headers_frame_count_); |
3793 EXPECT_EQ(1, visitor.continuation_count_); | 3655 EXPECT_EQ(1, visitor.continuation_count_); |
3794 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 3656 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
3795 } | 3657 } |
3796 | 3658 |
3797 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { | 3659 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { |
3798 if (!IsHttp2()) { | 3660 if (!IsHttp2()) { |
3799 return; | 3661 return; |
3800 } | 3662 } |
3801 | 3663 |
3802 SpdyFramer framer(spdy_version_); | 3664 SpdyFramer framer(spdy_version_); |
3803 framer.set_enable_compression(false); | 3665 framer.set_enable_compression(false); |
3804 SpdyPushPromiseIR push_promise(1, 2); | 3666 SpdyPushPromiseIR push_promise(1, 2); |
3805 push_promise.set_padding_len(256); | 3667 push_promise.set_padding_len(256); |
3806 | 3668 |
3807 // Exact payload length will change with HPACK, but this should be long | 3669 // Exact payload length will change with HPACK, but this should be long |
3808 // enough to cause an overflow. | 3670 // enough to cause an overflow. |
3809 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); | 3671 const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size(); |
3810 string big_value(kBigValueSize, 'x'); | 3672 string big_value(kBigValueSize, 'x'); |
3811 push_promise.SetHeader("aa", big_value); | 3673 push_promise.SetHeader("aa", big_value); |
3812 SpdySerializedFrame control_frame(framer.SerializePushPromise(push_promise)); | 3674 SpdySerializedFrame control_frame(framer.SerializePushPromise(push_promise)); |
3813 EXPECT_GT(control_frame.size(), | 3675 EXPECT_GT(control_frame.size(), |
3814 TestSpdyVisitor::sent_control_frame_max_size()); | 3676 TestSpdyVisitor::sent_control_frame_max_size()); |
3815 | 3677 |
3816 TestSpdyVisitor visitor(spdy_version_); | 3678 TestSpdyVisitor visitor(spdy_version_); |
3817 visitor.SimulateInFramer( | 3679 visitor.SimulateInFramer( |
3818 reinterpret_cast<unsigned char*>(control_frame.data()), | 3680 reinterpret_cast<unsigned char*>(control_frame.data()), |
3819 control_frame.size()); | 3681 control_frame.size()); |
3820 EXPECT_TRUE(visitor.header_buffer_valid_); | 3682 EXPECT_TRUE(visitor.header_buffer_valid_); |
3821 EXPECT_EQ(0, visitor.error_count_); | 3683 EXPECT_EQ(0, visitor.error_count_); |
3822 EXPECT_EQ(1, visitor.push_promise_frame_count_); | 3684 EXPECT_EQ(1, visitor.push_promise_frame_count_); |
3823 EXPECT_EQ(1, visitor.continuation_count_); | 3685 EXPECT_EQ(1, visitor.continuation_count_); |
3824 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 3686 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
3825 } | 3687 } |
3826 | 3688 |
3827 // Check that the framer stops delivering header data chunks once the visitor | 3689 // Check that the framer stops delivering header data chunks once the visitor |
3828 // declares it doesn't want any more. This is important to guard against | 3690 // declares it doesn't want any more. This is important to guard against |
3829 // "zip bomb" types of attacks. | 3691 // "zip bomb" types of attacks. |
3830 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { | 3692 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { |
3831 const size_t kHeaderBufferChunks = 4; | 3693 const size_t kHeaderBufferChunks = 4; |
3832 const size_t kHeaderBufferSize = | 3694 const size_t kHeaderBufferSize = |
3833 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; | 3695 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; |
3834 const size_t kBigValueSize = kHeaderBufferSize * 2; | 3696 const size_t kBigValueSize = kHeaderBufferSize * 2; |
3835 string big_value(kBigValueSize, 'x'); | 3697 string big_value(kBigValueSize, 'x'); |
3836 SpdyFramer framer(spdy_version_); | 3698 SpdyFramer framer(spdy_version_); |
3837 SpdyHeadersIR headers(1); | 3699 SpdyHeadersIR headers(1); |
3838 headers.set_priority(1); | 3700 headers.set_priority(1); |
3839 headers.set_fin(true); | 3701 headers.set_fin(true); |
3840 headers.SetHeader("aa", big_value); | 3702 headers.SetHeader("aa", big_value); |
3841 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers)); | 3703 SpdySerializedFrame control_frame(framer.SerializeHeaders(headers)); |
3842 TestSpdyVisitor visitor(spdy_version_); | 3704 TestSpdyVisitor visitor(spdy_version_); |
3843 visitor.set_header_buffer_size(kHeaderBufferSize); | 3705 visitor.set_header_buffer_size(kHeaderBufferSize); |
3844 visitor.use_compression_ = true; | 3706 visitor.use_compression_ = true; |
3845 visitor.SimulateInFramer( | 3707 visitor.SimulateInFramer( |
3846 reinterpret_cast<unsigned char*>(control_frame.data()), | 3708 reinterpret_cast<unsigned char*>(control_frame.data()), |
3847 control_frame.size()); | 3709 control_frame.size()); |
3848 // It's up to the visitor to ignore extraneous header data; the framer | 3710 EXPECT_FALSE(visitor.header_buffer_valid_); |
3849 // won't throw an error. | 3711 EXPECT_EQ(1, visitor.error_count_); |
3850 EXPECT_GT(visitor.header_bytes_received_, visitor.header_buffer_size_); | 3712 EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE, |
3851 EXPECT_EQ(1, visitor.end_of_stream_count_); | 3713 visitor.framer_.error_code()) |
| 3714 << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); |
| 3715 |
| 3716 // The framer should have stoped delivering chunks after the visitor |
| 3717 // signaled "stop" by returning false from OnControlFrameHeaderData(). |
| 3718 // |
| 3719 // control_frame_header_data_count_ depends on the random sequence |
| 3720 // produced by rand(), so adding, removing or running single tests |
| 3721 // alters this value. The best we can do is assert that it happens |
| 3722 // at least kHeaderBufferChunks + 1. |
| 3723 EXPECT_LE(kHeaderBufferChunks + 1, |
| 3724 static_cast<unsigned>(visitor.control_frame_header_data_count_)); |
| 3725 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
| 3726 |
| 3727 // The framer should not have sent half-close to the visitor. |
| 3728 EXPECT_EQ(0, visitor.end_of_stream_count_); |
3852 } | 3729 } |
3853 | 3730 |
3854 TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) { | 3731 TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) { |
3855 if (!IsSpdy3()) { | 3732 if (!IsSpdy3()) { |
3856 // Deflate compression doesn't apply to HPACK. | 3733 // Deflate compression doesn't apply to HPACK. |
3857 return; | 3734 return; |
3858 } | 3735 } |
3859 | 3736 |
3860 SpdyFramer framer(spdy_version_); | 3737 SpdyFramer framer(spdy_version_); |
3861 framer.set_enable_compression(false); | 3738 framer.set_enable_compression(false); |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4295 }; | 4172 }; |
4296 | 4173 |
4297 SpdyFramer framer(spdy_version_); | 4174 SpdyFramer framer(spdy_version_); |
4298 TestSpdyVisitor visitor(spdy_version_); | 4175 TestSpdyVisitor visitor(spdy_version_); |
4299 visitor.SimulateInFramer(kInput, sizeof(kInput)); | 4176 visitor.SimulateInFramer(kInput, sizeof(kInput)); |
4300 | 4177 |
4301 EXPECT_EQ(0, visitor.error_count_); | 4178 EXPECT_EQ(0, visitor.error_count_); |
4302 EXPECT_EQ(1, visitor.headers_frame_count_); | 4179 EXPECT_EQ(1, visitor.headers_frame_count_); |
4303 EXPECT_EQ(2, visitor.continuation_count_); | 4180 EXPECT_EQ(2, visitor.continuation_count_); |
4304 EXPECT_EQ(1, visitor.fin_flag_count_); | 4181 EXPECT_EQ(1, visitor.fin_flag_count_); |
4305 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 4182 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
4306 EXPECT_EQ(1, visitor.end_of_stream_count_); | 4183 EXPECT_EQ(1, visitor.end_of_stream_count_); |
4307 | 4184 |
4308 EXPECT_THAT(visitor.headers_, | 4185 EXPECT_THAT(visitor.headers_, |
4309 testing::ElementsAre( | 4186 testing::ElementsAre( |
4310 testing::Pair("cookie", "foo=bar; baz=bing; "), | 4187 testing::Pair("cookie", "foo=bar; baz=bing; "), |
4311 testing::Pair("name", "value"))); | 4188 testing::Pair("name", "value"))); |
4312 } | 4189 } |
4313 | 4190 |
4314 TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) { | 4191 TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) { |
4315 if (!IsHttp2()) { | 4192 if (!IsHttp2()) { |
(...skipping 29 matching lines...) Expand all Loading... |
4345 }; | 4222 }; |
4346 | 4223 |
4347 SpdyFramer framer(spdy_version_); | 4224 SpdyFramer framer(spdy_version_); |
4348 TestSpdyVisitor visitor(spdy_version_); | 4225 TestSpdyVisitor visitor(spdy_version_); |
4349 visitor.SimulateInFramer(kInput, sizeof(kInput)); | 4226 visitor.SimulateInFramer(kInput, sizeof(kInput)); |
4350 | 4227 |
4351 EXPECT_EQ(0, visitor.error_count_); | 4228 EXPECT_EQ(0, visitor.error_count_); |
4352 EXPECT_EQ(1u, visitor.last_push_promise_stream_); | 4229 EXPECT_EQ(1u, visitor.last_push_promise_stream_); |
4353 EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_); | 4230 EXPECT_EQ(42u, visitor.last_push_promise_promised_stream_); |
4354 EXPECT_EQ(2, visitor.continuation_count_); | 4231 EXPECT_EQ(2, visitor.continuation_count_); |
4355 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 4232 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
4356 EXPECT_EQ(0, visitor.end_of_stream_count_); | 4233 EXPECT_EQ(0, visitor.end_of_stream_count_); |
4357 | 4234 |
4358 EXPECT_THAT(visitor.headers_, | 4235 EXPECT_THAT(visitor.headers_, |
4359 testing::ElementsAre( | 4236 testing::ElementsAre( |
4360 testing::Pair("cookie", "foo=bar; baz=bing; "), | 4237 testing::Pair("cookie", "foo=bar; baz=bing; "), |
4361 testing::Pair("name", "value"))); | 4238 testing::Pair("name", "value"))); |
4362 } | 4239 } |
4363 | 4240 |
4364 // Receiving an unknown frame when a continuation is expected should | 4241 // Receiving an unknown frame when a continuation is expected should |
4365 // result in a SPDY_UNEXPECTED_FRAME error | 4242 // result in a SPDY_UNEXPECTED_FRAME error |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4952 syn_stream.SetHeader("foo", "bar"); | 4829 syn_stream.SetHeader("foo", "bar"); |
4953 SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); | 4830 SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); |
4954 SetFrameFlags(&frame, flags, spdy_version_); | 4831 SetFrameFlags(&frame, flags, spdy_version_); |
4955 | 4832 |
4956 if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { | 4833 if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
4957 EXPECT_CALL(visitor, OnError(_)); | 4834 EXPECT_CALL(visitor, OnError(_)); |
4958 } else { | 4835 } else { |
4959 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _)); | 4836 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _)); |
4960 EXPECT_CALL(visitor, OnSynStream(8, 3, 1, flags & CONTROL_FLAG_FIN, | 4837 EXPECT_CALL(visitor, OnSynStream(8, 3, 1, flags & CONTROL_FLAG_FIN, |
4961 flags & CONTROL_FLAG_UNIDIRECTIONAL)); | 4838 flags & CONTROL_FLAG_UNIDIRECTIONAL)); |
4962 EXPECT_CALL(visitor, OnHeaderFrameStart(8)).Times(1); | 4839 EXPECT_CALL(visitor, OnControlFrameHeaderData(8, _, _)) |
4963 EXPECT_CALL(visitor, OnHeaderFrameEnd(8, _)).Times(1); | 4840 .WillRepeatedly(testing::Return(true)); |
4964 if (flags & DATA_FLAG_FIN) { | 4841 if (flags & DATA_FLAG_FIN) { |
4965 EXPECT_CALL(visitor, OnStreamEnd(_)); | 4842 EXPECT_CALL(visitor, OnStreamEnd(_)); |
4966 } else { | 4843 } else { |
4967 // Do not close the stream if we are expecting a CONTINUATION frame. | 4844 // Do not close the stream if we are expecting a CONTINUATION frame. |
4968 EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); | 4845 EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); |
4969 } | 4846 } |
4970 } | 4847 } |
4971 | 4848 |
4972 framer.ProcessInput(frame.data(), frame.size()); | 4849 framer.ProcessInput(frame.data(), frame.size()); |
4973 if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { | 4850 if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
(...skipping 25 matching lines...) Expand all Loading... |
4999 | 4876 |
5000 SpdySynReplyIR syn_reply(37); | 4877 SpdySynReplyIR syn_reply(37); |
5001 syn_reply.SetHeader("foo", "bar"); | 4878 syn_reply.SetHeader("foo", "bar"); |
5002 SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply)); | 4879 SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply)); |
5003 SetFrameFlags(&frame, flags, spdy_version_); | 4880 SetFrameFlags(&frame, flags, spdy_version_); |
5004 | 4881 |
5005 if (flags & ~CONTROL_FLAG_FIN) { | 4882 if (flags & ~CONTROL_FLAG_FIN) { |
5006 EXPECT_CALL(visitor, OnError(_)); | 4883 EXPECT_CALL(visitor, OnError(_)); |
5007 } else { | 4884 } else { |
5008 EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN)); | 4885 EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN)); |
5009 EXPECT_CALL(visitor, OnHeaderFrameStart(37)).Times(1); | 4886 EXPECT_CALL(visitor, OnControlFrameHeaderData(37, _, _)) |
5010 EXPECT_CALL(visitor, OnHeaderFrameEnd(37, _)).Times(1); | 4887 .WillRepeatedly(testing::Return(true)); |
5011 if (flags & DATA_FLAG_FIN) { | 4888 if (flags & DATA_FLAG_FIN) { |
5012 EXPECT_CALL(visitor, OnStreamEnd(_)); | 4889 EXPECT_CALL(visitor, OnStreamEnd(_)); |
5013 } | 4890 } |
5014 } | 4891 } |
5015 | 4892 |
5016 framer.ProcessInput(frame.data(), frame.size()); | 4893 framer.ProcessInput(frame.data(), frame.size()); |
5017 if (flags & ~CONTROL_FLAG_FIN) { | 4894 if (flags & ~CONTROL_FLAG_FIN) { |
5018 EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); | 4895 EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); |
5019 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, | 4896 EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, |
5020 framer.error_code()) | 4897 framer.error_code()) |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5198 bool fin = flags & CONTROL_FLAG_FIN; | 5075 bool fin = flags & CONTROL_FLAG_FIN; |
5199 bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS); | 5076 bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS); |
5200 if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) { | 5077 if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) { |
5201 has_priority = true; | 5078 has_priority = true; |
5202 priority = 3; | 5079 priority = 3; |
5203 parent_stream_id = 5; | 5080 parent_stream_id = 5; |
5204 exclusive = true; | 5081 exclusive = true; |
5205 } | 5082 } |
5206 EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority, | 5083 EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority, |
5207 parent_stream_id, exclusive, fin, end)); | 5084 parent_stream_id, exclusive, fin, end)); |
5208 EXPECT_CALL(visitor, OnHeaderFrameStart(57)).Times(1); | 5085 EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _)) |
5209 if (end) { | 5086 .WillRepeatedly(testing::Return(true)); |
5210 EXPECT_CALL(visitor, OnHeaderFrameEnd(57, _)).Times(1); | |
5211 } | |
5212 if (flags & DATA_FLAG_FIN && | 5087 if (flags & DATA_FLAG_FIN && |
5213 (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) { | 5088 (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) { |
5214 EXPECT_CALL(visitor, OnStreamEnd(_)); | 5089 EXPECT_CALL(visitor, OnStreamEnd(_)); |
5215 } else { | 5090 } else { |
5216 // Do not close the stream if we are expecting a CONTINUATION frame. | 5091 // Do not close the stream if we are expecting a CONTINUATION frame. |
5217 EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); | 5092 EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); |
5218 } | 5093 } |
5219 | 5094 |
5220 framer.ProcessInput(frame.data(), frame.size()); | 5095 framer.ProcessInput(frame.data(), frame.size()); |
5221 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 5096 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5297 SpdyPushPromiseIR push_promise(client_id, promised_id); | 5172 SpdyPushPromiseIR push_promise(client_id, promised_id); |
5298 push_promise.SetHeader("foo", "bar"); | 5173 push_promise.SetHeader("foo", "bar"); |
5299 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); | 5174 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); |
5300 // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, | 5175 // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, |
5301 // and implement framing. | 5176 // and implement framing. |
5302 SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_); | 5177 SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_); |
5303 | 5178 |
5304 bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 5179 bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
5305 EXPECT_CALL(debug_visitor, | 5180 EXPECT_CALL(debug_visitor, |
5306 OnReceiveCompressedFrame(client_id, PUSH_PROMISE, _)); | 5181 OnReceiveCompressedFrame(client_id, PUSH_PROMISE, _)); |
5307 EXPECT_CALL(visitor, | 5182 EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end)); |
5308 OnPushPromise(client_id, promised_id, | 5183 EXPECT_CALL(visitor, OnControlFrameHeaderData(client_id, _, _)) |
5309 flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)); | 5184 .WillRepeatedly(testing::Return(true)); |
5310 EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1); | |
5311 if (end) { | |
5312 EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id, _)).Times(1); | |
5313 } | |
5314 | 5185 |
5315 framer.ProcessInput(frame.data(), frame.size()); | 5186 framer.ProcessInput(frame.data(), frame.size()); |
5316 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 5187 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
5317 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 5188 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
5318 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 5189 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
5319 } while (++flags != 0); | 5190 } while (++flags != 0); |
5320 } | 5191 } |
5321 | 5192 |
5322 TEST_P(SpdyFramerTest, ContinuationFrameFlags) { | 5193 TEST_P(SpdyFramerTest, ContinuationFrameFlags) { |
5323 if (!IsHttp2()) { | 5194 if (!IsHttp2()) { |
5324 return; | 5195 return; |
5325 } | 5196 } |
5326 | 5197 |
5327 uint8_t flags = 0; | 5198 uint8_t flags = 0; |
5328 do { | 5199 do { |
5329 SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex | 5200 SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex |
5330 << static_cast<int>(flags)); | 5201 << static_cast<int>(flags)); |
5331 | 5202 |
5332 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; | 5203 testing::StrictMock<test::MockSpdyFramerVisitor> visitor; |
5333 testing::StrictMock<test::MockDebugVisitor> debug_visitor; | 5204 testing::StrictMock<test::MockDebugVisitor> debug_visitor; |
5334 SpdyFramer framer(spdy_version_); | 5205 SpdyFramer framer(spdy_version_); |
5335 framer.set_visitor(&visitor); | 5206 framer.set_visitor(&visitor); |
5336 framer.set_debug_visitor(&debug_visitor); | 5207 framer.set_debug_visitor(&debug_visitor); |
5337 | 5208 |
5338 EXPECT_CALL(debug_visitor, OnSendCompressedFrame(42, HEADERS, _, _)); | 5209 EXPECT_CALL(debug_visitor, OnSendCompressedFrame(42, HEADERS, _, _)); |
5339 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, HEADERS, _)); | 5210 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, HEADERS, _)); |
5340 EXPECT_CALL(visitor, OnHeaders(42, false, 0, 0, false, false, false)); | 5211 EXPECT_CALL(visitor, OnHeaders(42, false, 0, 0, false, false, false)); |
5341 EXPECT_CALL(visitor, OnHeaderFrameStart(42)).Times(1); | 5212 EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _)) |
| 5213 .WillRepeatedly(testing::Return(true)); |
5342 | 5214 |
5343 SpdyHeadersIR headers_ir(42); | 5215 SpdyHeadersIR headers_ir(42); |
5344 headers_ir.SetHeader("foo", "bar"); | 5216 headers_ir.SetHeader("foo", "bar"); |
5345 SpdySerializedFrame frame0(framer.SerializeHeaders(headers_ir)); | 5217 SpdySerializedFrame frame0(framer.SerializeHeaders(headers_ir)); |
5346 SetFrameFlags(&frame0, 0, spdy_version_); | 5218 SetFrameFlags(&frame0, 0, spdy_version_); |
5347 | 5219 |
5348 SpdyContinuationIR continuation(42); | 5220 SpdyContinuationIR continuation(42); |
5349 continuation.SetHeader("foo", "bar"); | 5221 continuation.SetHeader("foo", "bar"); |
5350 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); | 5222 SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); |
5351 SetFrameFlags(&frame, flags, spdy_version_); | 5223 SetFrameFlags(&frame, flags, spdy_version_); |
5352 | 5224 |
5353 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, CONTINUATION, _)); | 5225 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, CONTINUATION, _)); |
5354 EXPECT_CALL(visitor, OnContinuation(42, flags & HEADERS_FLAG_END_HEADERS)); | 5226 EXPECT_CALL(visitor, OnContinuation(42, flags & HEADERS_FLAG_END_HEADERS)); |
5355 bool end = flags & HEADERS_FLAG_END_HEADERS; | 5227 EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _)) |
5356 if (end) { | 5228 .WillRepeatedly(testing::Return(true)); |
5357 EXPECT_CALL(visitor, OnHeaderFrameEnd(42, _)).Times(1); | |
5358 } | |
5359 | 5229 |
5360 framer.ProcessInput(frame0.data(), frame0.size()); | 5230 framer.ProcessInput(frame0.data(), frame0.size()); |
5361 framer.ProcessInput(frame.data(), frame.size()); | 5231 framer.ProcessInput(frame.data(), frame.size()); |
5362 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 5232 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
5363 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 5233 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
5364 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 5234 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
5365 } while (++flags != 0); | 5235 } while (++flags != 0); |
5366 } | 5236 } |
5367 | 5237 |
5368 // TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags) | 5238 // TODO(mlavan): Add TEST_P(SpdyFramerTest, AltSvcFrameFlags) |
(...skipping 16 matching lines...) Expand all Loading... |
5385 SpdySynStreamIR syn_stream(1); | 5255 SpdySynStreamIR syn_stream(1); |
5386 syn_stream.set_priority(1); | 5256 syn_stream.set_priority(1); |
5387 SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); | 5257 SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); |
5388 // Adjust size to remove the header block. | 5258 // Adjust size to remove the header block. |
5389 SetFrameLength(&frame, framer.GetSynStreamMinimumSize() - | 5259 SetFrameLength(&frame, framer.GetSynStreamMinimumSize() - |
5390 framer.GetControlFrameHeaderSize(), | 5260 framer.GetControlFrameHeaderSize(), |
5391 spdy_version_); | 5261 spdy_version_); |
5392 | 5262 |
5393 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(1, SYN_STREAM, _)); | 5263 EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(1, SYN_STREAM, _)); |
5394 EXPECT_CALL(visitor, OnSynStream(1, 0, 1, false, false)); | 5264 EXPECT_CALL(visitor, OnSynStream(1, 0, 1, false, false)); |
5395 EXPECT_CALL(visitor, OnHeaderFrameStart(1)).Times(1); | 5265 EXPECT_CALL(visitor, OnControlFrameHeaderData(1, NULL, 0)); |
5396 EXPECT_CALL(visitor, OnHeaderFrameEnd(1, _)).Times(1); | |
5397 | 5266 |
5398 framer.ProcessInput(frame.data(), framer.GetSynStreamMinimumSize()); | 5267 framer.ProcessInput(frame.data(), framer.GetSynStreamMinimumSize()); |
5399 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 5268 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
5400 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 5269 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
5401 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 5270 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
5402 } | 5271 } |
5403 | 5272 |
5404 TEST_P(SpdyFramerTest, SettingsFlagsAndId) { | 5273 TEST_P(SpdyFramerTest, SettingsFlagsAndId) { |
5405 const uint32_t kId = 0x020304; | 5274 const uint32_t kId = 0x020304; |
5406 const uint32_t kFlags = 0x01; | 5275 const uint32_t kFlags = 0x01; |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5988 | 5857 |
5989 EXPECT_EQ(1, visitor->data_frame_count_); | 5858 EXPECT_EQ(1, visitor->data_frame_count_); |
5990 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); | 5859 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); |
5991 EXPECT_EQ(0, visitor->headers_frame_count_); | 5860 EXPECT_EQ(0, visitor->headers_frame_count_); |
5992 } | 5861 } |
5993 } | 5862 } |
5994 | 5863 |
5995 } // namespace test | 5864 } // namespace test |
5996 | 5865 |
5997 } // namespace net | 5866 } // namespace net |
OLD | NEW |