| 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/buffered_spdy_framer.h" | 5 #include "net/spdy/buffered_spdy_framer.h" |
| 6 | 6 |
| 7 #include "net/spdy/spdy_test_util.h" | 7 #include "net/spdy/spdy_test_util.h" |
| 8 #include "testing/platform_test.h" | 8 #include "testing/platform_test.h" |
| 9 | 9 |
| 10 namespace spdy { | 10 namespace spdy { |
| 11 | 11 |
| 12 namespace test { | 12 namespace test { |
| 13 | 13 |
| 14 class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { | 14 class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { |
| 15 public: | 15 public: |
| 16 TestBufferedSpdyVisitor() | 16 TestBufferedSpdyVisitor() |
| 17 : error_count_(0), | 17 : error_count_(0), |
| 18 syn_frame_count_(0), | 18 syn_frame_count_(0), |
| 19 syn_reply_frame_count_(0), | 19 syn_reply_frame_count_(0), |
| 20 headers_frame_count_(0), | 20 headers_frame_count_(0), |
| 21 control_frame_header_data_count_(0), | |
| 22 zero_length_control_frame_header_data_count_(0), | |
| 23 header_stream_id_(-1) { | 21 header_stream_id_(-1) { |
| 24 } | 22 } |
| 25 | 23 |
| 26 void OnError(SpdyFramer* f) { | 24 void OnError() { |
| 27 LOG(INFO) << "SpdyFramer Error: " | 25 LOG(INFO) << "SpdyFramer Error"; |
| 28 << SpdyFramer::ErrorCodeToString(f->error_code()); | |
| 29 error_count_++; | 26 error_count_++; |
| 30 } | 27 } |
| 31 | 28 |
| 32 void OnSyn(const SpdySynStreamControlFrame& frame, | 29 void OnStreamError(spdy::SpdyStreamId stream_id) { |
| 30 LOG(INFO) << "SpdyFramer Error on stream: " << stream_id; |
| 31 error_count_++; |
| 32 } |
| 33 |
| 34 void OnSynStream(const SpdySynStreamControlFrame& frame, |
| 33 const linked_ptr<SpdyHeaderBlock>& headers) { | 35 const linked_ptr<SpdyHeaderBlock>& headers) { |
| 34 EXPECT_EQ(header_stream_id_, frame.stream_id()); | 36 header_stream_id_ = frame.stream_id(); |
| 37 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 35 syn_frame_count_++; | 38 syn_frame_count_++; |
| 36 headers_ = *headers; | 39 headers_ = *headers; |
| 37 } | 40 } |
| 38 | 41 |
| 39 void OnSynReply(const SpdySynReplyControlFrame& frame, | 42 void OnSynReply(const SpdySynReplyControlFrame& frame, |
| 40 const linked_ptr<SpdyHeaderBlock>& headers) { | 43 const linked_ptr<SpdyHeaderBlock>& headers) { |
| 41 EXPECT_EQ(header_stream_id_, frame.stream_id()); | 44 header_stream_id_ = frame.stream_id(); |
| 45 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 42 syn_reply_frame_count_++; | 46 syn_reply_frame_count_++; |
| 43 headers_ = *headers; | 47 headers_ = *headers; |
| 44 } | 48 } |
| 45 | 49 |
| 46 void OnHeaders(const SpdyHeadersControlFrame& frame, | 50 void OnHeaders(const SpdyHeadersControlFrame& frame, |
| 47 const linked_ptr<SpdyHeaderBlock>& headers) { | 51 const linked_ptr<SpdyHeaderBlock>& headers) { |
| 48 EXPECT_EQ(header_stream_id_, frame.stream_id()); | 52 header_stream_id_ = frame.stream_id(); |
| 53 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 49 headers_frame_count_++; | 54 headers_frame_count_++; |
| 50 headers_ = *headers; | 55 headers_ = *headers; |
| 51 } | 56 } |
| 52 | 57 |
| 53 void OnStreamFrameData(SpdyStreamId stream_id, | 58 void OnStreamFrameData(SpdyStreamId stream_id, |
| 54 const char* data, | 59 const char* data, |
| 55 size_t len) { | 60 size_t len) { |
| 56 LOG(FATAL) << "Unexpected OnStreamFrameData call."; | 61 LOG(FATAL) << "Unexpected OnStreamFrameData call."; |
| 57 } | 62 } |
| 58 | 63 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 73 case HEADERS: | 78 case HEADERS: |
| 74 header_stream_id_ = SpdyFramer::GetControlFrameStreamId(frame); | 79 header_stream_id_ = SpdyFramer::GetControlFrameStreamId(frame); |
| 75 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); | 80 EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream); |
| 76 buffered_spdy_framer_.OnControl(frame); | 81 buffered_spdy_framer_.OnControl(frame); |
| 77 break; | 82 break; |
| 78 default: | 83 default: |
| 79 LOG(FATAL) << "Unexpected frame type." << type; | 84 LOG(FATAL) << "Unexpected frame type." << type; |
| 80 } | 85 } |
| 81 } | 86 } |
| 82 | 87 |
| 83 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | 88 void OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) {} |
| 84 const char* header_data, | 89 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) {} |
| 85 size_t len) { | 90 void OnPing(const spdy::SpdyPingControlFrame& frame) {} |
| 86 EXPECT_EQ(header_stream_id_, stream_id); | 91 void OnSettings(const spdy::SpdySettingsControlFrame& frame) {} |
| 87 | 92 void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame) {} |
| 88 bool result = buffered_spdy_framer_.OnControlFrameHeaderData( | 93 void OnCredential(const spdy::SpdyCredentialControlFrame& frame) {} |
| 89 stream_id, header_data, len); | |
| 90 EXPECT_TRUE(result); | |
| 91 | |
| 92 ++control_frame_header_data_count_; | |
| 93 | |
| 94 if (len == 0) | |
| 95 ++zero_length_control_frame_header_data_count_; | |
| 96 | |
| 97 return true; | |
| 98 } | |
| 99 | 94 |
| 100 // Convenience function which runs a framer simulation with particular input. | 95 // Convenience function which runs a framer simulation with particular input. |
| 101 void SimulateInFramer(const unsigned char* input, size_t size) { | 96 void SimulateInFramer(const unsigned char* input, size_t size) { |
| 102 buffered_spdy_framer_.set_visitor(this); | 97 buffered_spdy_framer_.set_visitor(this); |
| 103 size_t input_remaining = size; | 98 size_t input_remaining = size; |
| 104 const char* input_ptr = reinterpret_cast<const char*>(input); | 99 const char* input_ptr = reinterpret_cast<const char*>(input); |
| 105 while (input_remaining > 0 && | 100 while (input_remaining > 0 && |
| 106 buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) { | 101 buffered_spdy_framer_.error_code() == SpdyFramer::SPDY_NO_ERROR) { |
| 107 // To make the tests more interesting, we feed random (amd small) chunks | 102 // To make the tests more interesting, we feed random (amd small) chunks |
| 108 // into the framer. This simulates getting strange-sized reads from | 103 // into the framer. This simulates getting strange-sized reads from |
| (...skipping 10 matching lines...) Expand all Loading... |
| 119 } | 114 } |
| 120 } | 115 } |
| 121 | 116 |
| 122 BufferedSpdyFramer buffered_spdy_framer_; | 117 BufferedSpdyFramer buffered_spdy_framer_; |
| 123 | 118 |
| 124 // Counters from the visitor callbacks. | 119 // Counters from the visitor callbacks. |
| 125 int error_count_; | 120 int error_count_; |
| 126 int syn_frame_count_; | 121 int syn_frame_count_; |
| 127 int syn_reply_frame_count_; | 122 int syn_reply_frame_count_; |
| 128 int headers_frame_count_; | 123 int headers_frame_count_; |
| 129 int control_frame_header_data_count_; // The count of chunks received. | |
| 130 // The count of zero-length control frame header data chunks received. | |
| 131 int zero_length_control_frame_header_data_count_; | |
| 132 | 124 |
| 133 // Header block streaming state: | 125 // Header block streaming state: |
| 134 SpdyStreamId header_stream_id_; | 126 SpdyStreamId header_stream_id_; |
| 135 | 127 |
| 136 // Headers from OnSyn, OnSynReply and OnHeaders for verification. | 128 // Headers from OnSyn, OnSynReply and OnHeaders for verification. |
| 137 SpdyHeaderBlock headers_; | 129 SpdyHeaderBlock headers_; |
| 138 }; | 130 }; |
| 139 | 131 |
| 140 } // namespace test | 132 } // namespace test |
| 141 | 133 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 CONTROL_FLAG_NONE, | 185 CONTROL_FLAG_NONE, |
| 194 true, // compress | 186 true, // compress |
| 195 &headers)); | 187 &headers)); |
| 196 EXPECT_TRUE(control_frame.get() != NULL); | 188 EXPECT_TRUE(control_frame.get() != NULL); |
| 197 | 189 |
| 198 TestBufferedSpdyVisitor visitor; | 190 TestBufferedSpdyVisitor visitor; |
| 199 visitor.SimulateInFramer( | 191 visitor.SimulateInFramer( |
| 200 reinterpret_cast<unsigned char*>(control_frame.get()->data()), | 192 reinterpret_cast<unsigned char*>(control_frame.get()->data()), |
| 201 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); | 193 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); |
| 202 EXPECT_EQ(0, visitor.error_count_); | 194 EXPECT_EQ(0, visitor.error_count_); |
| 203 EXPECT_GT(visitor.control_frame_header_data_count_, 0); | |
| 204 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); | |
| 205 EXPECT_EQ(1, visitor.syn_frame_count_); | 195 EXPECT_EQ(1, visitor.syn_frame_count_); |
| 206 EXPECT_EQ(0, visitor.syn_reply_frame_count_); | 196 EXPECT_EQ(0, visitor.syn_reply_frame_count_); |
| 207 EXPECT_EQ(0, visitor.headers_frame_count_); | 197 EXPECT_EQ(0, visitor.headers_frame_count_); |
| 208 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); | 198 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); |
| 209 } | 199 } |
| 210 | 200 |
| 211 TEST_F(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) { | 201 TEST_F(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) { |
| 212 EnableCompression(false); | 202 EnableCompression(false); |
| 213 | 203 |
| 214 SpdyHeaderBlock headers; | 204 SpdyHeaderBlock headers; |
| 215 headers["alpha"] = "beta"; | 205 headers["alpha"] = "beta"; |
| 216 headers["gamma"] = "delta"; | 206 headers["gamma"] = "delta"; |
| 217 BufferedSpdyFramer framer; | 207 BufferedSpdyFramer framer; |
| 218 scoped_ptr<SpdySynReplyControlFrame> control_frame( | 208 scoped_ptr<SpdySynReplyControlFrame> control_frame( |
| 219 framer.CreateSynReply(1, // stream_id | 209 framer.CreateSynReply(1, // stream_id |
| 220 CONTROL_FLAG_NONE, | 210 CONTROL_FLAG_NONE, |
| 221 true, // compress | 211 true, // compress |
| 222 &headers)); | 212 &headers)); |
| 223 EXPECT_TRUE(control_frame.get() != NULL); | 213 EXPECT_TRUE(control_frame.get() != NULL); |
| 224 | 214 |
| 225 TestBufferedSpdyVisitor visitor; | 215 TestBufferedSpdyVisitor visitor; |
| 226 visitor.SimulateInFramer( | 216 visitor.SimulateInFramer( |
| 227 reinterpret_cast<unsigned char*>(control_frame.get()->data()), | 217 reinterpret_cast<unsigned char*>(control_frame.get()->data()), |
| 228 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); | 218 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); |
| 229 EXPECT_EQ(0, visitor.error_count_); | 219 EXPECT_EQ(0, visitor.error_count_); |
| 230 EXPECT_GT(visitor.control_frame_header_data_count_, 0); | |
| 231 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); | |
| 232 EXPECT_EQ(0, visitor.syn_frame_count_); | 220 EXPECT_EQ(0, visitor.syn_frame_count_); |
| 233 EXPECT_EQ(1, visitor.syn_reply_frame_count_); | 221 EXPECT_EQ(1, visitor.syn_reply_frame_count_); |
| 234 EXPECT_EQ(0, visitor.headers_frame_count_); | 222 EXPECT_EQ(0, visitor.headers_frame_count_); |
| 235 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); | 223 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); |
| 236 } | 224 } |
| 237 | 225 |
| 238 TEST_F(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) { | 226 TEST_F(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) { |
| 239 EnableCompression(false); | 227 EnableCompression(false); |
| 240 | 228 |
| 241 SpdyHeaderBlock headers; | 229 SpdyHeaderBlock headers; |
| 242 headers["alpha"] = "beta"; | 230 headers["alpha"] = "beta"; |
| 243 headers["gamma"] = "delta"; | 231 headers["gamma"] = "delta"; |
| 244 BufferedSpdyFramer framer; | 232 BufferedSpdyFramer framer; |
| 245 scoped_ptr<SpdyHeadersControlFrame> control_frame( | 233 scoped_ptr<SpdyHeadersControlFrame> control_frame( |
| 246 framer.CreateHeaders(1, // stream_id | 234 framer.CreateHeaders(1, // stream_id |
| 247 CONTROL_FLAG_NONE, | 235 CONTROL_FLAG_NONE, |
| 248 true, // compress | 236 true, // compress |
| 249 &headers)); | 237 &headers)); |
| 250 EXPECT_TRUE(control_frame.get() != NULL); | 238 EXPECT_TRUE(control_frame.get() != NULL); |
| 251 | 239 |
| 252 TestBufferedSpdyVisitor visitor; | 240 TestBufferedSpdyVisitor visitor; |
| 253 visitor.SimulateInFramer( | 241 visitor.SimulateInFramer( |
| 254 reinterpret_cast<unsigned char*>(control_frame.get()->data()), | 242 reinterpret_cast<unsigned char*>(control_frame.get()->data()), |
| 255 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); | 243 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); |
| 256 EXPECT_EQ(0, visitor.error_count_); | 244 EXPECT_EQ(0, visitor.error_count_); |
| 257 EXPECT_GT(visitor.control_frame_header_data_count_, 0); | |
| 258 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); | |
| 259 EXPECT_EQ(0, visitor.syn_frame_count_); | 245 EXPECT_EQ(0, visitor.syn_frame_count_); |
| 260 EXPECT_EQ(0, visitor.syn_reply_frame_count_); | 246 EXPECT_EQ(0, visitor.syn_reply_frame_count_); |
| 261 EXPECT_EQ(1, visitor.headers_frame_count_); | 247 EXPECT_EQ(1, visitor.headers_frame_count_); |
| 262 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); | 248 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_)); |
| 263 } | 249 } |
| 264 } // namespace spdy | 250 } // namespace spdy |
| OLD | NEW |