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 19 matching lines...) Expand all Loading... |
30 #include "testing/platform_test.h" | 30 #include "testing/platform_test.h" |
31 | 31 |
32 using base::StringPiece; | 32 using base::StringPiece; |
33 using std::string; | 33 using std::string; |
34 using testing::_; | 34 using testing::_; |
35 | 35 |
36 namespace net { | 36 namespace net { |
37 | 37 |
38 namespace test { | 38 namespace test { |
39 | 39 |
40 static const size_t kMaxDecompressedSize = 1024; | |
41 | |
42 class MockDebugVisitor : public SpdyFramerDebugVisitorInterface { | 40 class MockDebugVisitor : public SpdyFramerDebugVisitorInterface { |
43 public: | 41 public: |
44 MOCK_METHOD4(OnSendCompressedFrame, | 42 MOCK_METHOD4(OnSendCompressedFrame, |
45 void(SpdyStreamId stream_id, | 43 void(SpdyStreamId stream_id, |
46 SpdyFrameType type, | 44 SpdyFrameType type, |
47 size_t payload_len, | 45 size_t payload_len, |
48 size_t frame_len)); | 46 size_t frame_len)); |
49 | 47 |
50 MOCK_METHOD3(OnReceiveCompressedFrame, | 48 MOCK_METHOD3(OnReceiveCompressedFrame, |
51 void(SpdyStreamId stream_id, | 49 void(SpdyStreamId stream_id, |
52 SpdyFrameType type, | 50 SpdyFrameType type, |
53 size_t frame_len)); | 51 size_t frame_len)); |
54 }; | 52 }; |
55 | 53 |
56 class SpdyFramerTestUtil { | 54 class SpdyFramerTestUtil { |
57 public: | 55 public: |
58 // Decompress a single frame using the decompression context held by | 56 // Decompress a single frame using the decompression context held by |
59 // the SpdyFramer. The implemention is meant for use only in tests | 57 // the SpdyFramer. The implemention is meant for use only in tests |
60 // and will CHECK fail if the input is anything other than a single, | 58 // and will CHECK fail if the input is anything other than a single, |
61 // well-formed compressed frame. | 59 // well-formed compressed frame. |
62 // | 60 // |
63 // Returns a new decompressed SpdySerializedFrame. | 61 // Returns a new decompressed SpdySerializedFrame. |
64 template <class SpdyFrameType> | 62 template <class SpdyFrameType> |
65 static SpdySerializedFrame DecompressFrame(SpdyFramer* framer, | 63 static SpdySerializedFrame DecompressFrame(SpdyFramer* framer, |
66 const SpdyFrameType& frame) { | 64 const SpdyFrameType& frame) { |
67 NewDecompressionVisitor visitor; | 65 DecompressionVisitor visitor; |
68 framer->set_visitor(&visitor); | 66 framer->set_visitor(&visitor); |
69 CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size())); | 67 CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size())); |
70 CHECK_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer->state()); | 68 CHECK_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer->state()); |
71 framer->set_visitor(nullptr); | 69 framer->set_visitor(nullptr); |
72 SpdyFramer serializer(framer->protocol_version()); | 70 SpdyFramer serializer(framer->protocol_version()); |
73 serializer.set_enable_compression(false); | 71 serializer.set_enable_compression(false); |
74 return serializer.SerializeFrame(visitor.GetFrame()); | 72 return serializer.SerializeFrame(visitor.GetFrame()); |
75 } | 73 } |
76 | 74 |
77 class NewDecompressionVisitor : public SpdyFramerVisitorInterface { | 75 class DecompressionVisitor : public SpdyFramerVisitorInterface { |
78 public: | 76 public: |
79 NewDecompressionVisitor() : finished_(false) {} | 77 DecompressionVisitor() : finished_(false) {} |
80 | 78 |
81 const SpdyFrameIR& GetFrame() const { | 79 const SpdyFrameIR& GetFrame() const { |
82 CHECK(finished_); | 80 CHECK(finished_); |
83 return *frame_; | 81 return *frame_; |
84 } | 82 } |
85 | 83 |
86 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | 84 SpdyHeadersHandlerInterface* OnHeaderFrameStart( |
87 SpdyStreamId stream_id) override { | 85 SpdyStreamId stream_id) override { |
88 if (headers_handler_ == nullptr) { | 86 if (headers_handler_ == nullptr) { |
89 headers_handler_.reset(new TestHeadersHandler); | 87 headers_handler_.reset(new TestHeadersHandler); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { | 201 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { |
204 LOG(FATAL); | 202 LOG(FATAL); |
205 return false; | 203 return false; |
206 } | 204 } |
207 | 205 |
208 private: | 206 private: |
209 std::unique_ptr<TestHeadersHandler> headers_handler_; | 207 std::unique_ptr<TestHeadersHandler> headers_handler_; |
210 std::unique_ptr<SpdyFrameWithHeaderBlockIR> frame_; | 208 std::unique_ptr<SpdyFrameWithHeaderBlockIR> frame_; |
211 bool finished_; | 209 bool finished_; |
212 | 210 |
213 DISALLOW_COPY_AND_ASSIGN(NewDecompressionVisitor); | |
214 }; | |
215 | |
216 class DecompressionVisitor : public SpdyFramerVisitorInterface { | |
217 public: | |
218 explicit DecompressionVisitor(SpdyMajorVersion version) | |
219 : version_(version), size_(0), finished_(false) {} | |
220 | |
221 void ResetBuffer() { | |
222 CHECK(buffer_.get() == NULL); | |
223 CHECK_EQ(0u, size_); | |
224 CHECK(!finished_); | |
225 buffer_.reset(new char[kMaxDecompressedSize]); | |
226 } | |
227 | |
228 void OnError(SpdyFramer* framer) override { LOG(FATAL); } | |
229 void OnDataFrameHeader(SpdyStreamId stream_id, | |
230 size_t length, | |
231 bool fin) override { | |
232 LOG(FATAL) << "Unexpected data frame header"; | |
233 } | |
234 void OnStreamFrameData(SpdyStreamId stream_id, | |
235 const char* data, | |
236 size_t len) override { | |
237 LOG(FATAL); | |
238 } | |
239 | |
240 void OnStreamEnd(SpdyStreamId stream_id) override { LOG(FATAL); } | |
241 | |
242 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { | |
243 LOG(FATAL); | |
244 } | |
245 | |
246 SpdyHeadersHandlerInterface* OnHeaderFrameStart( | |
247 SpdyStreamId stream_id) override { | |
248 LOG(FATAL) << "Not implemented."; | |
249 return nullptr; | |
250 } | |
251 | |
252 void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { | |
253 LOG(FATAL) << "Not implemented."; | |
254 } | |
255 | |
256 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | |
257 const char* header_data, | |
258 size_t len) override { | |
259 CHECK(buffer_.get() != NULL); | |
260 CHECK_GE(kMaxDecompressedSize, size_ + len); | |
261 CHECK(!finished_); | |
262 if (len != 0) { | |
263 memcpy(buffer_.get() + size_, header_data, len); | |
264 size_ += len; | |
265 } else { | |
266 // Done. | |
267 finished_ = true; | |
268 } | |
269 return true; | |
270 } | |
271 | |
272 void OnSynStream(SpdyStreamId stream_id, | |
273 SpdyStreamId associated_stream_id, | |
274 SpdyPriority priority, | |
275 bool fin, | |
276 bool unidirectional) override { | |
277 SpdyFramer framer(version_); | |
278 framer.set_enable_compression(false); | |
279 SpdySynStreamIR syn_stream(stream_id); | |
280 syn_stream.set_associated_to_stream_id(associated_stream_id); | |
281 syn_stream.set_priority(priority); | |
282 syn_stream.set_fin(fin); | |
283 syn_stream.set_unidirectional(unidirectional); | |
284 SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); | |
285 ResetBuffer(); | |
286 memcpy(buffer_.get(), frame.data(), framer.GetSynStreamMinimumSize()); | |
287 size_ += framer.GetSynStreamMinimumSize(); | |
288 } | |
289 | |
290 void OnSynReply(SpdyStreamId stream_id, bool fin) override { | |
291 SpdyFramer framer(version_); | |
292 framer.set_enable_compression(false); | |
293 SpdyHeadersIR headers(stream_id); | |
294 headers.set_fin(fin); | |
295 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); | |
296 ResetBuffer(); | |
297 memcpy(buffer_.get(), frame.data(), framer.GetHeadersMinimumSize()); | |
298 size_ += framer.GetSynStreamMinimumSize(); | |
299 } | |
300 | |
301 void OnRstStream(SpdyStreamId stream_id, | |
302 SpdyRstStreamStatus status) override { | |
303 LOG(FATAL); | |
304 } | |
305 void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override { | |
306 LOG(FATAL); | |
307 } | |
308 void OnPing(SpdyPingId unique_id, bool is_ack) override { LOG(FATAL); } | |
309 void OnSettingsEnd() override { LOG(FATAL); } | |
310 void OnGoAway(SpdyStreamId last_accepted_stream_id, | |
311 SpdyGoAwayStatus status) override { | |
312 LOG(FATAL); | |
313 } | |
314 | |
315 void OnHeaders(SpdyStreamId stream_id, | |
316 bool has_priority, | |
317 int weight, | |
318 SpdyStreamId parent_stream_id, | |
319 bool exclusive, | |
320 bool fin, | |
321 bool end) override { | |
322 SpdyFramer framer(version_); | |
323 framer.set_enable_compression(false); | |
324 SpdyHeadersIR headers(stream_id); | |
325 headers.set_has_priority(has_priority); | |
326 headers.set_weight(weight); | |
327 headers.set_parent_stream_id(parent_stream_id); | |
328 headers.set_exclusive(exclusive); | |
329 headers.set_fin(fin); | |
330 SpdySerializedFrame frame(framer.SerializeHeaders(headers)); | |
331 ResetBuffer(); | |
332 memcpy(buffer_.get(), frame.data(), framer.GetHeadersMinimumSize()); | |
333 size_ += framer.GetHeadersMinimumSize(); | |
334 } | |
335 | |
336 void OnWindowUpdate(SpdyStreamId stream_id, | |
337 int delta_window_size) override { | |
338 LOG(FATAL); | |
339 } | |
340 | |
341 void OnPushPromise(SpdyStreamId stream_id, | |
342 SpdyStreamId promised_stream_id, | |
343 bool end) override { | |
344 SpdyFramer framer(version_); | |
345 framer.set_enable_compression(false); | |
346 SpdyPushPromiseIR push_promise(stream_id, promised_stream_id); | |
347 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); | |
348 ResetBuffer(); | |
349 memcpy(buffer_.get(), frame.data(), framer.GetPushPromiseMinimumSize()); | |
350 size_ += framer.GetPushPromiseMinimumSize(); | |
351 } | |
352 | |
353 void OnContinuation(SpdyStreamId stream_id, bool end) override { | |
354 LOG(FATAL); | |
355 } | |
356 | |
357 void OnPriority(SpdyStreamId stream_id, | |
358 SpdyStreamId parent_stream_id, | |
359 int weight, | |
360 bool exclusive) override { | |
361 // Do nothing. | |
362 } | |
363 | |
364 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { | |
365 LOG(FATAL); | |
366 return false; | |
367 } | |
368 | |
369 char* ReleaseBuffer() { | |
370 CHECK(finished_); | |
371 return buffer_.release(); | |
372 } | |
373 | |
374 size_t size() const { | |
375 CHECK(finished_); | |
376 return size_; | |
377 } | |
378 | |
379 private: | |
380 SpdyMajorVersion version_; | |
381 std::unique_ptr<char[]> buffer_; | |
382 size_t size_; | |
383 bool finished_; | |
384 | |
385 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); | 211 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); |
386 }; | 212 }; |
387 | 213 |
388 private: | 214 private: |
389 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); | 215 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); |
390 }; | 216 }; |
391 | 217 |
392 MATCHER_P(IsFrameUnionOf, frame_list, "") { | 218 MATCHER_P(IsFrameUnionOf, frame_list, "") { |
393 size_t size_verified = 0; | 219 size_t size_verified = 0; |
394 for (const auto& frame : *frame_list) { | 220 for (const auto& frame : *frame_list) { |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 | 823 |
998 TestSpdyVisitor visitor(spdy_version_); | 824 TestSpdyVisitor visitor(spdy_version_); |
999 visitor.use_compression_ = false; | 825 visitor.use_compression_ = false; |
1000 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), | 826 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), |
1001 frame.size() - 2); | 827 frame.size() - 2); |
1002 | 828 |
1003 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 829 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
1004 EXPECT_EQ(0u, visitor.headers_.size()); | 830 EXPECT_EQ(0u, visitor.headers_.size()); |
1005 } | 831 } |
1006 | 832 |
| 833 // Test that we make all header field names (keys) lower case on encoding. |
| 834 TEST_P(SpdyFramerTest, HeaderBlockToLowerCase) { |
| 835 // The HPACK encoding path does not lowercase field names. |
| 836 if (IsHttp2()) { |
| 837 return; |
| 838 } |
| 839 |
| 840 SpdyFramer framer(spdy_version_); |
| 841 framer.set_enable_compression(true); |
| 842 |
| 843 // Encode the header block into a Headers frame. |
| 844 SpdyHeadersIR headers_ir(1); |
| 845 headers_ir.SetHeader("aLpha", "beta"); |
| 846 headers_ir.SetHeader("GAMMA", "charlie"); |
| 847 headers_ir.SetHeader("foo", "Bar"); // Upper case values are okay. |
| 848 SpdySerializedFrame frame( |
| 849 SpdyFramerPeer::SerializeHeaders(&framer, headers_ir)); |
| 850 TestSpdyVisitor visitor(spdy_version_); |
| 851 visitor.use_compression_ = true; |
| 852 visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()), |
| 853 frame.size()); |
| 854 EXPECT_EQ(1, visitor.headers_frame_count_); |
| 855 EXPECT_EQ(headers_ir.header_block().size(), visitor.headers_.size()); |
| 856 EXPECT_EQ("beta", visitor.headers_["alpha"]); |
| 857 EXPECT_EQ("charlie", visitor.headers_["gamma"]); |
| 858 EXPECT_EQ("Bar", visitor.headers_["foo"]); |
| 859 } |
| 860 |
| 861 // Test that we treat incoming upper-case or mixed-case header values as |
| 862 // malformed for HTTP2. |
| 863 TEST_P(SpdyFramerTest, RejectUpperCaseHeaderBlockValue) { |
| 864 if (!IsHttp2()) { |
| 865 return; |
| 866 } |
| 867 |
| 868 SpdyFramer framer(spdy_version_); |
| 869 framer.set_enable_compression(false); |
| 870 |
| 871 SpdyFrameBuilder frame(1024, spdy_version_); |
| 872 frame.BeginNewFrame(framer, HEADERS, 0, 1); |
| 873 frame.WriteUInt32(1); |
| 874 frame.WriteStringPiece32("Name1"); |
| 875 frame.WriteStringPiece32("value1"); |
| 876 frame.RewriteLength(framer); |
| 877 |
| 878 SpdyFrameBuilder frame2(1024, spdy_version_); |
| 879 frame2.BeginNewFrame(framer, HEADERS, 0, 1); |
| 880 frame2.WriteUInt32(2); |
| 881 frame2.WriteStringPiece32("name1"); |
| 882 frame2.WriteStringPiece32("value1"); |
| 883 frame2.WriteStringPiece32("nAmE2"); |
| 884 frame2.WriteStringPiece32("value2"); |
| 885 frame2.RewriteLength(framer); |
| 886 |
| 887 SpdySerializedFrame control_frame(frame.take()); |
| 888 StringPiece serialized_headers = GetSerializedHeaders(control_frame, framer); |
| 889 SpdySerializedFrame control_frame2(frame2.take()); |
| 890 StringPiece serialized_headers2 = |
| 891 GetSerializedHeaders(control_frame2, framer); |
| 892 |
| 893 SpdyHeaderBlock new_headers; |
| 894 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer( |
| 895 serialized_headers.data(), serialized_headers.size(), &new_headers)); |
| 896 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer( |
| 897 serialized_headers2.data(), serialized_headers2.size(), &new_headers)); |
| 898 } |
| 899 |
1007 // Test that we can encode and decode stream dependency values in a header | 900 // Test that we can encode and decode stream dependency values in a header |
1008 // frame. | 901 // frame. |
1009 TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) { | 902 TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) { |
1010 if (!IsHttp2()) { | 903 if (!IsHttp2()) { |
1011 return; | 904 return; |
1012 } | 905 } |
1013 | 906 |
1014 SpdyFramer framer(spdy_version_); | 907 SpdyFramer framer(spdy_version_); |
1015 framer.set_enable_compression(false); | 908 framer.set_enable_compression(false); |
1016 | 909 |
(...skipping 3732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4749 | 4642 |
4750 TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) { | 4643 TEST_P(SpdyFramerTest, ReadHeadersWithContinuation) { |
4751 if (!IsHttp2()) { | 4644 if (!IsHttp2()) { |
4752 return; | 4645 return; |
4753 } | 4646 } |
4754 | 4647 |
4755 // frame-format off | 4648 // frame-format off |
4756 const unsigned char kInput[] = { | 4649 const unsigned char kInput[] = { |
4757 0x00, 0x00, 0x14, // Length: 20 | 4650 0x00, 0x00, 0x14, // Length: 20 |
4758 0x01, // Type: HEADERS | 4651 0x01, // Type: HEADERS |
4759 0x09, // Flags: FIN, PADDED | 4652 0x08, // Flags: PADDED |
4760 0x00, 0x00, 0x00, 0x01, // Stream: 1 | 4653 0x00, 0x00, 0x00, 0x01, // Stream: 1 |
4761 0x03, // PadLen: 3 trailing bytes | 4654 0x03, // PadLen: 3 trailing bytes |
4762 0x00, // Unindexed Entry | 4655 0x00, // Unindexed Entry |
4763 0x06, // Name Len: 6 | 4656 0x06, // Name Len: 6 |
4764 'c', 'o', 'o', 'k', 'i', 'e', // Name | 4657 'c', 'o', 'o', 'k', 'i', 'e', // Name |
4765 0x07, // Value Len: 7 | 4658 0x07, // Value Len: 7 |
4766 'f', 'o', 'o', '=', 'b', 'a', 'r', // Value | 4659 'f', 'o', 'o', '=', 'b', 'a', 'r', // Value |
4767 0x00, 0x00, 0x00, // Padding | 4660 0x00, 0x00, 0x00, // Padding |
4768 | 4661 |
4769 0x00, 0x00, 0x14, // Length: 20 | 4662 0x00, 0x00, 0x14, // Length: 20 |
(...skipping 23 matching lines...) Expand all Loading... |
4793 }; | 4686 }; |
4794 // frame-format on | 4687 // frame-format on |
4795 | 4688 |
4796 SpdyFramer framer(spdy_version_); | 4689 SpdyFramer framer(spdy_version_); |
4797 TestSpdyVisitor visitor(spdy_version_); | 4690 TestSpdyVisitor visitor(spdy_version_); |
4798 visitor.SimulateInFramer(kInput, sizeof(kInput)); | 4691 visitor.SimulateInFramer(kInput, sizeof(kInput)); |
4799 | 4692 |
4800 EXPECT_EQ(0, visitor.error_count_); | 4693 EXPECT_EQ(0, visitor.error_count_); |
4801 EXPECT_EQ(1, visitor.headers_frame_count_); | 4694 EXPECT_EQ(1, visitor.headers_frame_count_); |
4802 EXPECT_EQ(2, visitor.continuation_count_); | 4695 EXPECT_EQ(2, visitor.continuation_count_); |
| 4696 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
| 4697 EXPECT_EQ(0, visitor.end_of_stream_count_); |
| 4698 |
| 4699 EXPECT_THAT( |
| 4700 visitor.headers_, |
| 4701 testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "), |
| 4702 testing::Pair("name", "value"))); |
| 4703 } |
| 4704 |
| 4705 TEST_P(SpdyFramerTest, ReadHeadersWithContinuationAndFin) { |
| 4706 if (!IsHttp2()) { |
| 4707 return; |
| 4708 } |
| 4709 // frame-format off |
| 4710 const unsigned char kInput[] = { |
| 4711 0x00, 0x00, 0x10, // Length: 20 |
| 4712 0x01, // Type: HEADERS |
| 4713 0x01, // Flags: END_STREAM |
| 4714 0x00, 0x00, 0x00, 0x01, // Stream: 1 |
| 4715 0x00, // Unindexed Entry |
| 4716 0x06, // Name Len: 6 |
| 4717 'c', 'o', 'o', 'k', 'i', 'e', // Name |
| 4718 0x07, // Value Len: 7 |
| 4719 'f', 'o', 'o', '=', 'b', 'a', 'r', // Value |
| 4720 |
| 4721 0x00, 0x00, 0x14, // Length: 20 |
| 4722 0x09, // Type: CONTINUATION |
| 4723 0x00, // Flags: none |
| 4724 0x00, 0x00, 0x00, 0x01, // Stream: 1 |
| 4725 0x00, // Unindexed Entry |
| 4726 0x06, // Name Len: 6 |
| 4727 'c', 'o', 'o', 'k', 'i', 'e', // Name |
| 4728 0x08, // Value Len: 7 |
| 4729 'b', 'a', 'z', '=', 'b', 'i', 'n', 'g', // Value |
| 4730 0x00, // Unindexed Entry |
| 4731 0x06, // Name Len: 6 |
| 4732 'c', // Name (split) |
| 4733 |
| 4734 0x00, 0x00, 0x12, // Length: 18 |
| 4735 0x09, // Type: CONTINUATION |
| 4736 0x04, // Flags: END_HEADERS |
| 4737 0x00, 0x00, 0x00, 0x01, // Stream: 1 |
| 4738 'o', 'o', 'k', 'i', 'e', // Name (continued) |
| 4739 0x00, // Value Len: 0 |
| 4740 0x00, // Unindexed Entry |
| 4741 0x04, // Name Len: 4 |
| 4742 'n', 'a', 'm', 'e', // Name |
| 4743 0x05, // Value Len: 5 |
| 4744 'v', 'a', 'l', 'u', 'e', // Value |
| 4745 }; |
| 4746 // frame-format on |
| 4747 |
| 4748 SpdyFramer framer(spdy_version_); |
| 4749 TestSpdyVisitor visitor(spdy_version_); |
| 4750 visitor.SimulateInFramer(kInput, sizeof(kInput)); |
| 4751 |
| 4752 EXPECT_EQ(0, visitor.error_count_); |
| 4753 EXPECT_EQ(1, visitor.headers_frame_count_); |
| 4754 EXPECT_EQ(2, visitor.continuation_count_); |
4803 EXPECT_EQ(1, visitor.fin_flag_count_); | 4755 EXPECT_EQ(1, visitor.fin_flag_count_); |
4804 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); | 4756 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_); |
4805 EXPECT_EQ(1, visitor.end_of_stream_count_); | 4757 EXPECT_EQ(1, visitor.end_of_stream_count_); |
4806 | 4758 |
4807 EXPECT_THAT( | 4759 EXPECT_THAT( |
4808 visitor.headers_, | 4760 visitor.headers_, |
4809 testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "), | 4761 testing::ElementsAre(testing::Pair("cookie", "foo=bar; baz=bing; "), |
4810 testing::Pair("name", "value"))); | 4762 testing::Pair("name", "value"))); |
4811 } | 4763 } |
4812 | 4764 |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5793 SpdyPushPromiseIR push_promise(client_id, promised_id); | 5745 SpdyPushPromiseIR push_promise(client_id, promised_id); |
5794 push_promise.SetHeader("foo", "bar"); | 5746 push_promise.SetHeader("foo", "bar"); |
5795 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); | 5747 SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); |
5796 // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, | 5748 // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, |
5797 // and implement framing. | 5749 // and implement framing. |
5798 SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_); | 5750 SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_); |
5799 | 5751 |
5800 bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 5752 bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
5801 EXPECT_CALL(debug_visitor, | 5753 EXPECT_CALL(debug_visitor, |
5802 OnReceiveCompressedFrame(client_id, PUSH_PROMISE, _)); | 5754 OnReceiveCompressedFrame(client_id, PUSH_PROMISE, _)); |
5803 EXPECT_CALL(visitor, | 5755 EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end)); |
5804 OnPushPromise(client_id, promised_id, | |
5805 flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)); | |
5806 EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1); | 5756 EXPECT_CALL(visitor, OnHeaderFrameStart(client_id)).Times(1); |
5807 if (end) { | 5757 if (end) { |
5808 EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id, _)).Times(1); | 5758 EXPECT_CALL(visitor, OnHeaderFrameEnd(client_id, _)).Times(1); |
5809 } | 5759 } |
5810 | 5760 |
5811 framer.ProcessInput(frame.data(), frame.size()); | 5761 framer.ProcessInput(frame.data(), frame.size()); |
5812 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); | 5762 EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); |
5813 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 5763 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
5814 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 5764 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
5815 } while (++flags != 0); | 5765 } while (++flags != 0); |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6474 | 6424 |
6475 EXPECT_EQ(1, visitor->data_frame_count_); | 6425 EXPECT_EQ(1, visitor->data_frame_count_); |
6476 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); | 6426 EXPECT_EQ(strlen(four_score), static_cast<unsigned>(visitor->data_bytes_)); |
6477 EXPECT_EQ(0, visitor->headers_frame_count_); | 6427 EXPECT_EQ(0, visitor->headers_frame_count_); |
6478 } | 6428 } |
6479 } | 6429 } |
6480 | 6430 |
6481 } // namespace test | 6431 } // namespace test |
6482 | 6432 |
6483 } // namespace net | 6433 } // namespace net |
OLD | NEW |