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 <algorithm> | 5 #include <algorithm> |
6 #include <iostream> | 6 #include <iostream> |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); | 215 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor); |
216 }; | 216 }; |
217 | 217 |
218 private: | 218 private: |
219 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); | 219 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil); |
220 }; | 220 }; |
221 | 221 |
222 class TestSpdyVisitor : public SpdyFramerVisitorInterface, | 222 class TestSpdyVisitor : public SpdyFramerVisitorInterface, |
223 public SpdyFramerDebugVisitorInterface { | 223 public SpdyFramerDebugVisitorInterface { |
224 public: | 224 public: |
| 225 // This is larger than our max frame size because header blocks that |
| 226 // are too long can spill over into CONTINUATION frames. |
225 static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024; | 227 static const size_t kDefaultHeaderBufferSize = 16 * 1024 * 1024; |
226 | 228 |
227 explicit TestSpdyVisitor(SpdyMajorVersion version) | 229 explicit TestSpdyVisitor(SpdyMajorVersion version) |
228 : framer_(version), | 230 : framer_(version), |
229 use_compression_(false), | 231 use_compression_(false), |
230 error_count_(0), | 232 error_count_(0), |
231 syn_frame_count_(0), | 233 syn_frame_count_(0), |
232 syn_reply_frame_count_(0), | 234 syn_reply_frame_count_(0), |
233 headers_frame_count_(0), | 235 headers_frame_count_(0), |
| 236 push_promise_frame_count_(0), |
234 goaway_count_(0), | 237 goaway_count_(0), |
235 setting_count_(0), | 238 setting_count_(0), |
236 settings_ack_sent_(0), | 239 settings_ack_sent_(0), |
237 settings_ack_received_(0), | 240 settings_ack_received_(0), |
238 continuation_count_(0), | 241 continuation_count_(0), |
239 last_window_update_stream_(0), | 242 last_window_update_stream_(0), |
240 last_window_update_delta_(0), | 243 last_window_update_delta_(0), |
241 last_push_promise_stream_(0), | 244 last_push_promise_stream_(0), |
242 last_push_promise_promised_stream_(0), | 245 last_push_promise_promised_stream_(0), |
243 data_bytes_(0), | 246 data_bytes_(0), |
(...skipping 10 matching lines...) Expand all Loading... |
254 header_buffer_length_(0), | 257 header_buffer_length_(0), |
255 header_buffer_size_(kDefaultHeaderBufferSize), | 258 header_buffer_size_(kDefaultHeaderBufferSize), |
256 header_stream_id_(-1), | 259 header_stream_id_(-1), |
257 header_control_type_(DATA), | 260 header_control_type_(DATA), |
258 header_buffer_valid_(false) { | 261 header_buffer_valid_(false) { |
259 } | 262 } |
260 | 263 |
261 virtual void OnError(SpdyFramer* f) OVERRIDE { | 264 virtual void OnError(SpdyFramer* f) OVERRIDE { |
262 LOG(INFO) << "SpdyFramer Error: " | 265 LOG(INFO) << "SpdyFramer Error: " |
263 << SpdyFramer::ErrorCodeToString(f->error_code()); | 266 << SpdyFramer::ErrorCodeToString(f->error_code()); |
264 error_count_++; | 267 ++error_count_; |
265 } | 268 } |
266 | 269 |
267 virtual void OnDataFrameHeader(SpdyStreamId stream_id, | 270 virtual void OnDataFrameHeader(SpdyStreamId stream_id, |
268 size_t length, | 271 size_t length, |
269 bool fin) OVERRIDE { | 272 bool fin) OVERRIDE { |
270 data_frame_count_++; | 273 ++data_frame_count_; |
271 header_stream_id_ = stream_id; | 274 header_stream_id_ = stream_id; |
272 } | 275 } |
273 | 276 |
274 virtual void OnStreamFrameData(SpdyStreamId stream_id, | 277 virtual void OnStreamFrameData(SpdyStreamId stream_id, |
275 const char* data, | 278 const char* data, |
276 size_t len, | 279 size_t len, |
277 bool fin) OVERRIDE { | 280 bool fin) OVERRIDE { |
278 EXPECT_EQ(header_stream_id_, stream_id); | 281 EXPECT_EQ(header_stream_id_, stream_id); |
279 if (len == 0) | 282 if (len == 0) |
280 ++zero_length_data_frame_count_; | 283 ++zero_length_data_frame_count_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 memcpy(header_buffer_.get() + header_buffer_length_, header_data, len); | 317 memcpy(header_buffer_.get() + header_buffer_length_, header_data, len); |
315 header_buffer_length_ += len; | 318 header_buffer_length_ += len; |
316 return true; | 319 return true; |
317 } | 320 } |
318 | 321 |
319 virtual void OnSynStream(SpdyStreamId stream_id, | 322 virtual void OnSynStream(SpdyStreamId stream_id, |
320 SpdyStreamId associated_stream_id, | 323 SpdyStreamId associated_stream_id, |
321 SpdyPriority priority, | 324 SpdyPriority priority, |
322 bool fin, | 325 bool fin, |
323 bool unidirectional) OVERRIDE { | 326 bool unidirectional) OVERRIDE { |
324 syn_frame_count_++; | 327 ++syn_frame_count_; |
325 InitHeaderStreaming(SYN_STREAM, stream_id); | 328 InitHeaderStreaming(SYN_STREAM, stream_id); |
326 if (fin) { | 329 if (fin) { |
327 fin_flag_count_++; | 330 ++fin_flag_count_; |
328 } | 331 } |
329 } | 332 } |
330 | 333 |
331 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE { | 334 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE { |
332 syn_reply_frame_count_++; | 335 ++syn_reply_frame_count_; |
333 InitHeaderStreaming(SYN_REPLY, stream_id); | 336 InitHeaderStreaming(SYN_REPLY, stream_id); |
334 if (fin) { | 337 if (fin) { |
335 fin_flag_count_++; | 338 ++fin_flag_count_; |
336 } | 339 } |
337 } | 340 } |
338 | 341 |
339 virtual void OnRstStream(SpdyStreamId stream_id, | 342 virtual void OnRstStream(SpdyStreamId stream_id, |
340 SpdyRstStreamStatus status) OVERRIDE { | 343 SpdyRstStreamStatus status) OVERRIDE { |
341 fin_frame_count_++; | 344 ++fin_frame_count_; |
342 } | 345 } |
343 | 346 |
344 virtual bool OnRstStreamFrameData(const char* rst_stream_data, | 347 virtual bool OnRstStreamFrameData(const char* rst_stream_data, |
345 size_t len) OVERRIDE { | 348 size_t len) OVERRIDE { |
346 if ((rst_stream_data != NULL) && (len > 0)) { | 349 if ((rst_stream_data != NULL) && (len > 0)) { |
347 fin_opaque_data_ += std::string(rst_stream_data, len); | 350 fin_opaque_data_ += std::string(rst_stream_data, len); |
348 } | 351 } |
349 return true; | 352 return true; |
350 } | 353 } |
351 | 354 |
352 virtual void OnSetting(SpdySettingsIds id, | 355 virtual void OnSetting(SpdySettingsIds id, |
353 uint8 flags, | 356 uint8 flags, |
354 uint32 value) OVERRIDE { | 357 uint32 value) OVERRIDE { |
355 setting_count_++; | 358 ++setting_count_; |
356 } | 359 } |
357 | 360 |
358 virtual void OnSettingsAck() OVERRIDE { | 361 virtual void OnSettingsAck() OVERRIDE { |
359 DCHECK_GE(4, framer_.protocol_version()); | 362 DCHECK_GE(4, framer_.protocol_version()); |
360 settings_ack_received_++; | 363 ++settings_ack_received_; |
361 } | 364 } |
362 | 365 |
363 virtual void OnSettingsEnd() OVERRIDE { | 366 virtual void OnSettingsEnd() OVERRIDE { |
364 if (framer_.protocol_version() < 4) { return; } | 367 if (framer_.protocol_version() < 4) { return; } |
365 settings_ack_sent_++; | 368 ++settings_ack_sent_; |
366 } | 369 } |
367 | 370 |
368 virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE { | 371 virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE { |
369 DLOG(FATAL); | 372 DLOG(FATAL); |
370 } | 373 } |
371 | 374 |
372 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, | 375 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, |
373 SpdyGoAwayStatus status) OVERRIDE { | 376 SpdyGoAwayStatus status) OVERRIDE { |
374 goaway_count_++; | 377 ++goaway_count_; |
375 } | 378 } |
376 | 379 |
377 virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE { | 380 virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE { |
378 headers_frame_count_++; | 381 ++headers_frame_count_; |
379 InitHeaderStreaming(HEADERS, stream_id); | 382 InitHeaderStreaming(HEADERS, stream_id); |
380 if (fin) { | 383 if (fin) { |
381 fin_flag_count_++; | 384 ++fin_flag_count_; |
382 } | 385 } |
383 } | 386 } |
384 | 387 |
385 virtual void OnWindowUpdate(SpdyStreamId stream_id, | 388 virtual void OnWindowUpdate(SpdyStreamId stream_id, |
386 uint32 delta_window_size) OVERRIDE { | 389 uint32 delta_window_size) OVERRIDE { |
387 last_window_update_stream_ = stream_id; | 390 last_window_update_stream_ = stream_id; |
388 last_window_update_delta_ = delta_window_size; | 391 last_window_update_delta_ = delta_window_size; |
389 } | 392 } |
390 | 393 |
391 virtual void OnPushPromise(SpdyStreamId stream_id, | 394 virtual void OnPushPromise(SpdyStreamId stream_id, |
392 SpdyStreamId promised_stream_id, | 395 SpdyStreamId promised_stream_id, |
393 bool end) OVERRIDE { | 396 bool end) OVERRIDE { |
| 397 ++push_promise_frame_count_; |
394 InitHeaderStreaming(PUSH_PROMISE, stream_id); | 398 InitHeaderStreaming(PUSH_PROMISE, stream_id); |
395 last_push_promise_stream_ = stream_id; | 399 last_push_promise_stream_ = stream_id; |
396 last_push_promise_promised_stream_ = promised_stream_id; | 400 last_push_promise_promised_stream_ = promised_stream_id; |
397 } | 401 } |
398 | 402 |
399 virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE { | 403 virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE { |
400 continuation_count_++; | 404 ++continuation_count_; |
401 } | 405 } |
402 | 406 |
403 virtual void OnSendCompressedFrame(SpdyStreamId stream_id, | 407 virtual void OnSendCompressedFrame(SpdyStreamId stream_id, |
404 SpdyFrameType type, | 408 SpdyFrameType type, |
405 size_t payload_len, | 409 size_t payload_len, |
406 size_t frame_len) OVERRIDE { | 410 size_t frame_len) OVERRIDE { |
407 last_payload_len_ = payload_len; | 411 last_payload_len_ = payload_len; |
408 last_frame_len_ = frame_len; | 412 last_frame_len_ = frame_len; |
409 } | 413 } |
410 | 414 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 } | 461 } |
458 | 462 |
459 SpdyFramer framer_; | 463 SpdyFramer framer_; |
460 bool use_compression_; | 464 bool use_compression_; |
461 | 465 |
462 // Counters from the visitor callbacks. | 466 // Counters from the visitor callbacks. |
463 int error_count_; | 467 int error_count_; |
464 int syn_frame_count_; | 468 int syn_frame_count_; |
465 int syn_reply_frame_count_; | 469 int syn_reply_frame_count_; |
466 int headers_frame_count_; | 470 int headers_frame_count_; |
| 471 int push_promise_frame_count_; |
467 int goaway_count_; | 472 int goaway_count_; |
468 int setting_count_; | 473 int setting_count_; |
469 int settings_ack_sent_; | 474 int settings_ack_sent_; |
470 int settings_ack_received_; | 475 int settings_ack_received_; |
471 int continuation_count_; | 476 int continuation_count_; |
472 SpdyStreamId last_window_update_stream_; | 477 SpdyStreamId last_window_update_stream_; |
473 uint32 last_window_update_delta_; | 478 uint32 last_window_update_delta_; |
474 SpdyStreamId last_push_promise_stream_; | 479 SpdyStreamId last_push_promise_stream_; |
475 SpdyStreamId last_push_promise_promised_stream_; | 480 SpdyStreamId last_push_promise_promised_stream_; |
476 int data_bytes_; | 481 int data_bytes_; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 EXPECT_EQ("Bar", new_headers["foo"]); | 693 EXPECT_EQ("Bar", new_headers["foo"]); |
689 } | 694 } |
690 | 695 |
691 // Test that we treat incoming upper-case or mixed-case header values as | 696 // Test that we treat incoming upper-case or mixed-case header values as |
692 // malformed for SPDY4. | 697 // malformed for SPDY4. |
693 TEST_P(SpdyFramerTest, RejectUpperCaseHeaderBlockValue) { | 698 TEST_P(SpdyFramerTest, RejectUpperCaseHeaderBlockValue) { |
694 if (spdy_version_ < SPDY4) { return; } | 699 if (spdy_version_ < SPDY4) { return; } |
695 SpdyFramer framer(spdy_version_); | 700 SpdyFramer framer(spdy_version_); |
696 framer.set_enable_compression(false); | 701 framer.set_enable_compression(false); |
697 | 702 |
698 SpdyFrameBuilder frame(1024); | 703 SpdyFrameBuilder frame(1024, spdy_version_); |
699 frame.WriteFramePrefix(framer, HEADERS, HEADERS_FLAG_PRIORITY, 1); | 704 frame.BeginNewFrame(framer, HEADERS, HEADERS_FLAG_PRIORITY, 1); |
700 frame.WriteUInt32(framer.GetHighestPriority()); | 705 frame.WriteUInt32(framer.GetHighestPriority()); |
701 frame.WriteUInt32(1); | 706 frame.WriteUInt32(1); |
702 frame.WriteStringPiece32("Name1"); | 707 frame.WriteStringPiece32("Name1"); |
703 frame.WriteStringPiece32("value1"); | 708 frame.WriteStringPiece32("value1"); |
704 frame.RewriteLength(framer); | 709 frame.RewriteLength(framer); |
705 | 710 |
706 SpdyFrameBuilder frame2(1024); | 711 SpdyFrameBuilder frame2(1024, spdy_version_); |
707 frame2.WriteFramePrefix(framer, HEADERS, 0, 1); | 712 frame2.BeginNewFrame(framer, HEADERS, 0, 1); |
708 frame2.WriteUInt32(2); | 713 frame2.WriteUInt32(2); |
709 frame2.WriteStringPiece32("name1"); | 714 frame2.WriteStringPiece32("name1"); |
710 frame2.WriteStringPiece32("value1"); | 715 frame2.WriteStringPiece32("value1"); |
711 frame2.WriteStringPiece32("nAmE2"); | 716 frame2.WriteStringPiece32("nAmE2"); |
712 frame2.WriteStringPiece32("value2"); | 717 frame2.WriteStringPiece32("value2"); |
713 frame2.RewriteLength(framer); | 718 frame2.RewriteLength(framer); |
714 | 719 |
715 scoped_ptr<SpdyFrame> control_frame(frame.take()); | 720 scoped_ptr<SpdyFrame> control_frame(frame.take()); |
716 StringPiece serialized_headers = GetSerializedHeaders(control_frame.get(), | 721 StringPiece serialized_headers = GetSerializedHeaders(control_frame.get(), |
717 framer); | 722 framer); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 | 834 |
830 TEST_P(SpdyFramerTest, DuplicateHeader) { | 835 TEST_P(SpdyFramerTest, DuplicateHeader) { |
831 if (spdy_version_ >= 4) { | 836 if (spdy_version_ >= 4) { |
832 // TODO(jgraettinger): Punting on this because we haven't determined | 837 // TODO(jgraettinger): Punting on this because we haven't determined |
833 // whether duplicate HPACK headers other than Cookie are an error. | 838 // whether duplicate HPACK headers other than Cookie are an error. |
834 // If they are, this will need to be updated to use HpackOutputStream. | 839 // If they are, this will need to be updated to use HpackOutputStream. |
835 return; | 840 return; |
836 } | 841 } |
837 SpdyFramer framer(spdy_version_); | 842 SpdyFramer framer(spdy_version_); |
838 // Frame builder with plentiful buffer size. | 843 // Frame builder with plentiful buffer size. |
839 SpdyFrameBuilder frame(1024); | 844 SpdyFrameBuilder frame(1024, spdy_version_); |
840 if (spdy_version_ < 4) { | 845 if (spdy_version_ < 4) { |
841 frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE); | 846 frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE); |
842 frame.WriteUInt32(3); // stream_id | 847 frame.WriteUInt32(3); // stream_id |
843 frame.WriteUInt32(0); // associated stream id | 848 frame.WriteUInt32(0); // associated stream id |
844 frame.WriteUInt16(0); // Priority. | 849 frame.WriteUInt16(0); // Priority. |
845 } else { | 850 } else { |
846 frame.WriteFramePrefix(framer, HEADERS, HEADERS_FLAG_PRIORITY, 3); | 851 frame.BeginNewFrame(framer, HEADERS, HEADERS_FLAG_PRIORITY, 3); |
847 frame.WriteUInt32(framer.GetHighestPriority()); | 852 frame.WriteUInt32(framer.GetHighestPriority()); |
848 } | 853 } |
849 | 854 |
850 if (IsSpdy2()) { | 855 if (IsSpdy2()) { |
851 frame.WriteUInt16(2); // Number of headers. | 856 frame.WriteUInt16(2); // Number of headers. |
852 frame.WriteString("name"); | 857 frame.WriteString("name"); |
853 frame.WriteString("value1"); | 858 frame.WriteString("value1"); |
854 frame.WriteString("name"); | 859 frame.WriteString("name"); |
855 frame.WriteString("value2"); | 860 frame.WriteString("value2"); |
856 } else { | 861 } else { |
(...skipping 13 matching lines...) Expand all Loading... |
870 GetSerializedHeaders(control_frame.get(), framer); | 875 GetSerializedHeaders(control_frame.get(), framer); |
871 // This should fail because duplicate headers are verboten by the spec. | 876 // This should fail because duplicate headers are verboten by the spec. |
872 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(), | 877 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(), |
873 serialized_headers.size(), | 878 serialized_headers.size(), |
874 &new_headers)); | 879 &new_headers)); |
875 } | 880 } |
876 | 881 |
877 TEST_P(SpdyFramerTest, MultiValueHeader) { | 882 TEST_P(SpdyFramerTest, MultiValueHeader) { |
878 SpdyFramer framer(spdy_version_); | 883 SpdyFramer framer(spdy_version_); |
879 // Frame builder with plentiful buffer size. | 884 // Frame builder with plentiful buffer size. |
880 SpdyFrameBuilder frame(1024); | 885 SpdyFrameBuilder frame(1024, spdy_version_); |
881 if (spdy_version_ < 4) { | 886 if (spdy_version_ < 4) { |
882 frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE); | 887 frame.WriteControlFrameHeader(framer, SYN_STREAM, CONTROL_FLAG_NONE); |
883 frame.WriteUInt32(3); // stream_id | 888 frame.WriteUInt32(3); // stream_id |
884 frame.WriteUInt32(0); // associated stream id | 889 frame.WriteUInt32(0); // associated stream id |
885 frame.WriteUInt16(0); // Priority. | 890 frame.WriteUInt16(0); // Priority. |
886 } else { | 891 } else { |
887 frame.WriteFramePrefix(framer, | 892 frame.BeginNewFrame(framer, |
888 HEADERS, | 893 HEADERS, |
889 HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, | 894 HEADERS_FLAG_PRIORITY | HEADERS_FLAG_END_HEADERS, |
890 3); | 895 3); |
891 frame.WriteUInt32(framer.GetHighestPriority()); | 896 frame.WriteUInt32(framer.GetHighestPriority()); |
892 } | 897 } |
893 | 898 |
894 string value("value1\0value2", 13); | 899 string value("value1\0value2", 13); |
895 if (IsSpdy2()) { | 900 if (IsSpdy2()) { |
896 frame.WriteUInt16(1); // Number of headers. | 901 frame.WriteUInt16(1); // Number of headers. |
897 frame.WriteString("name"); | 902 frame.WriteString("name"); |
898 frame.WriteString(value); | 903 frame.WriteString(value); |
899 } else if (spdy_version_ >= 4) { | 904 } else if (spdy_version_ >= 4) { |
900 HpackOutputStream output_stream(1024); | 905 HpackOutputStream output_stream(1024); |
(...skipping 2232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 control_frame->size()); | 3138 control_frame->size()); |
3134 EXPECT_FALSE(visitor.header_buffer_valid_); | 3139 EXPECT_FALSE(visitor.header_buffer_valid_); |
3135 EXPECT_EQ(1, visitor.error_count_); | 3140 EXPECT_EQ(1, visitor.error_count_); |
3136 EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE, | 3141 EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE, |
3137 visitor.framer_.error_code()) | 3142 visitor.framer_.error_code()) |
3138 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 3143 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
3139 EXPECT_EQ(0, visitor.syn_frame_count_); | 3144 EXPECT_EQ(0, visitor.syn_frame_count_); |
3140 EXPECT_EQ(0u, visitor.header_buffer_length_); | 3145 EXPECT_EQ(0u, visitor.header_buffer_length_); |
3141 } | 3146 } |
3142 | 3147 |
| 3148 TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { |
| 3149 if (spdy_version_ < net::SPDY4) { |
| 3150 return; |
| 3151 } |
| 3152 SpdyFramer framer(spdy_version_); |
| 3153 framer.set_enable_compression(false); |
| 3154 SpdyHeadersIR headers(1); |
| 3155 |
| 3156 // Exact payload length will change with HPACK, but this should be long |
| 3157 // enough to cause an overflow. |
| 3158 const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize(); |
| 3159 string big_value(kBigValueSize, 'x'); |
| 3160 headers.SetHeader("aa", big_value.c_str()); |
| 3161 scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers)); |
| 3162 EXPECT_TRUE(control_frame.get() != NULL); |
| 3163 EXPECT_GT(control_frame->size(), framer.GetControlFrameBufferMaxSize()); |
| 3164 |
| 3165 TestSpdyVisitor visitor(spdy_version_); |
| 3166 visitor.SimulateInFramer( |
| 3167 reinterpret_cast<unsigned char*>(control_frame->data()), |
| 3168 control_frame->size()); |
| 3169 EXPECT_TRUE(visitor.header_buffer_valid_); |
| 3170 EXPECT_EQ(0, visitor.error_count_); |
| 3171 EXPECT_EQ(1, visitor.headers_frame_count_); |
| 3172 EXPECT_EQ(1, visitor.continuation_count_); |
| 3173 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
| 3174 } |
| 3175 |
| 3176 TEST_P(SpdyFramerTest, TooLargePushPromiseFrameUsesContinuation) { |
| 3177 if (spdy_version_ < net::SPDY4) { |
| 3178 return; |
| 3179 } |
| 3180 SpdyFramer framer(spdy_version_); |
| 3181 framer.set_enable_compression(false); |
| 3182 SpdyPushPromiseIR push_promise(1, 2); |
| 3183 |
| 3184 // Exact payload length will change with HPACK, but this should be long |
| 3185 // enough to cause an overflow. |
| 3186 const size_t kBigValueSize = framer.GetControlFrameBufferMaxSize(); |
| 3187 string big_value(kBigValueSize, 'x'); |
| 3188 push_promise.SetHeader("aa", big_value.c_str()); |
| 3189 scoped_ptr<SpdyFrame> control_frame( |
| 3190 framer.SerializePushPromise(push_promise)); |
| 3191 EXPECT_TRUE(control_frame.get() != NULL); |
| 3192 EXPECT_GT(control_frame->size(), framer.GetControlFrameBufferMaxSize()); |
| 3193 |
| 3194 TestSpdyVisitor visitor(spdy_version_); |
| 3195 visitor.SimulateInFramer( |
| 3196 reinterpret_cast<unsigned char*>(control_frame->data()), |
| 3197 control_frame->size()); |
| 3198 EXPECT_TRUE(visitor.header_buffer_valid_); |
| 3199 EXPECT_EQ(0, visitor.error_count_); |
| 3200 EXPECT_EQ(1, visitor.push_promise_frame_count_); |
| 3201 EXPECT_EQ(1, visitor.continuation_count_); |
| 3202 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); |
| 3203 } |
| 3204 |
3143 // Check that the framer stops delivering header data chunks once the visitor | 3205 // Check that the framer stops delivering header data chunks once the visitor |
3144 // declares it doesn't want any more. This is important to guard against | 3206 // declares it doesn't want any more. This is important to guard against |
3145 // "zip bomb" types of attacks. | 3207 // "zip bomb" types of attacks. |
3146 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { | 3208 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { |
3147 const size_t kHeaderBufferChunks = 4; | 3209 const size_t kHeaderBufferChunks = 4; |
3148 const size_t kHeaderBufferSize = | 3210 const size_t kHeaderBufferSize = |
3149 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; | 3211 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks; |
3150 const size_t kBigValueSize = kHeaderBufferSize * 2; | 3212 const size_t kBigValueSize = kHeaderBufferSize * 2; |
3151 string big_value(kBigValueSize, 'x'); | 3213 string big_value(kBigValueSize, 'x'); |
3152 SpdyFramer framer(spdy_version_); | 3214 SpdyFramer framer(spdy_version_); |
(...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4913 SpdyBlockedIR blocked_ir(0); | 4975 SpdyBlockedIR blocked_ir(0); |
4914 scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir)); | 4976 scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir)); |
4915 framer.ProcessInput(frame->data(), framer.GetBlockedSize()); | 4977 framer.ProcessInput(frame->data(), framer.GetBlockedSize()); |
4916 | 4978 |
4917 EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state()); | 4979 EXPECT_EQ(SpdyFramer::SPDY_RESET, framer.state()); |
4918 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) | 4980 EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) |
4919 << SpdyFramer::ErrorCodeToString(framer.error_code()); | 4981 << SpdyFramer::ErrorCodeToString(framer.error_code()); |
4920 } | 4982 } |
4921 | 4983 |
4922 } // namespace net | 4984 } // namespace net |
OLD | NEW |