Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: net/spdy/spdy_framer_test.cc

Issue 10164020: Add a number of tests to spdy_framer_test.cc from server code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 7
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 #include "net/spdy/spdy_protocol.h" 10 #include "net/spdy/spdy_protocol.h"
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream); 393 DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
394 } 394 }
395 395
396 // Override the default buffer size (16K). Call before using the framer! 396 // Override the default buffer size (16K). Call before using the framer!
397 void set_header_buffer_size(size_t header_buffer_size) { 397 void set_header_buffer_size(size_t header_buffer_size) {
398 header_buffer_size_ = header_buffer_size; 398 header_buffer_size_ = header_buffer_size;
399 header_buffer_.reset(new char[header_buffer_size]); 399 header_buffer_.reset(new char[header_buffer_size]);
400 } 400 }
401 401
402 static size_t control_frame_buffer_max_size() { 402 static size_t control_frame_buffer_max_size() {
403 return SpdyFramer::kControlFrameBufferSize; 403 return SpdyFramer::kMaxControlFrameSize;
404 } 404 }
405 405
406 static size_t header_data_chunk_max_size() { 406 static size_t header_data_chunk_max_size() {
407 return SpdyFramer::kHeaderDataChunkMaxSize; 407 return SpdyFramer::kHeaderDataChunkMaxSize;
408 } 408 }
409 409
410 SpdyFramer framer_; 410 SpdyFramer framer_;
411 bool use_compression_; 411 bool use_compression_;
412 412
413 // Counters from the visitor callbacks. 413 // Counters from the visitor callbacks.
(...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after
2229 0x12, 0x34, 0x56, 0x78, 2229 0x12, 0x34, 0x56, 0x78,
2230 }; 2230 };
2231 scoped_ptr<SpdyFrame> frame1(framer.CreatePingFrame(0x12345678u)); 2231 scoped_ptr<SpdyFrame> frame1(framer.CreatePingFrame(0x12345678u));
2232 CompareFrame(kDescription, *frame1, kFrameData, arraysize(kFrameData)); 2232 CompareFrame(kDescription, *frame1, kFrameData, arraysize(kFrameData));
2233 2233
2234 scoped_ptr<SpdyFrame> frame2(framer.DuplicateFrame(*frame1)); 2234 scoped_ptr<SpdyFrame> frame2(framer.DuplicateFrame(*frame1));
2235 CompareFrame(kDescription, *frame2, kFrameData, arraysize(kFrameData)); 2235 CompareFrame(kDescription, *frame2, kFrameData, arraysize(kFrameData));
2236 } 2236 }
2237 } 2237 }
2238 2238
2239 TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
2240 SpdyHeaderBlock headers;
2241 headers["aa"] = "vv";
2242 headers["bb"] = "ww";
2243 SpdyFramer framer(spdy_version_);
2244 scoped_ptr<SpdySynStreamControlFrame> control_frame(
2245 framer.CreateSynStream(1, // stream_id
2246 0, // associated_stream_id
2247 1, // priority
2248 0, // credential_slot
2249 CONTROL_FLAG_NONE,
2250 true, // compress
2251 &headers));
2252 EXPECT_TRUE(control_frame.get() != NULL);
2253 TestSpdyVisitor visitor(spdy_version_);
2254 visitor.use_compression_ = true;
2255 visitor.SimulateInFramer(
2256 reinterpret_cast<unsigned char*>(control_frame->data()),
2257 control_frame->length() + SpdyControlFrame::kHeaderSize);
2258 EXPECT_EQ(1, visitor.syn_frame_count_);
2259 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
2260 }
2261
2262 TEST_P(SpdyFramerTest, ReadCompressedSynReplyHeaderBlock) {
2263 SpdyHeaderBlock headers;
2264 headers["alpha"] = "beta";
2265 headers["gamma"] = "delta";
2266 SpdyFramer framer(spdy_version_);
2267 scoped_ptr<SpdySynReplyControlFrame> control_frame(
2268 framer.CreateSynReply(1, // stream_id
2269 CONTROL_FLAG_NONE,
2270 true, // compress
2271 &headers));
2272 EXPECT_TRUE(control_frame.get() != NULL);
2273 TestSpdyVisitor visitor(spdy_version_);
2274 visitor.use_compression_ = true;
2275 visitor.SimulateInFramer(
2276 reinterpret_cast<unsigned char*>(control_frame->data()),
2277 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
2278 EXPECT_EQ(1, visitor.syn_reply_frame_count_);
2279 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
2280 }
2281
2282 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlock) {
2283 SpdyHeaderBlock headers;
2284 headers["alpha"] = "beta";
2285 headers["gamma"] = "delta";
2286 SpdyFramer framer(spdy_version_);
2287 scoped_ptr<SpdyHeadersControlFrame> control_frame(
2288 framer.CreateHeaders(1, // stream_id
2289 CONTROL_FLAG_NONE,
2290 true, // compress
2291 &headers));
2292 EXPECT_TRUE(control_frame.get() != NULL);
2293 TestSpdyVisitor visitor(spdy_version_);
2294 visitor.use_compression_ = true;
2295 visitor.SimulateInFramer(
2296 reinterpret_cast<unsigned char*>(control_frame->data()),
2297 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
2298 EXPECT_EQ(1, visitor.headers_frame_count_);
2299 // control_frame_header_data_count_ depends on the random sequence
2300 // produced by rand(), so adding, removing or running single tests
2301 // alters this value. The best we can do is assert that it happens
2302 // at least twice.
2303 EXPECT_LE(2, visitor.control_frame_header_data_count_);
2304 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
2305 EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
2306 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
2307 }
2308
2309 TEST_P(SpdyFramerTest, ReadCompressedHeadersHeaderBlockWithHalfClose) {
2310 SpdyHeaderBlock headers;
2311 headers["alpha"] = "beta";
2312 headers["gamma"] = "delta";
2313 SpdyFramer framer(spdy_version_);
2314 scoped_ptr<SpdyHeadersControlFrame> control_frame(
2315 framer.CreateHeaders(1, // stream_id
2316 CONTROL_FLAG_FIN,
2317 true, // compress
2318 &headers));
2319 EXPECT_TRUE(control_frame.get() != NULL);
2320 TestSpdyVisitor visitor(spdy_version_);
2321 visitor.use_compression_ = true;
2322 visitor.SimulateInFramer(
2323 reinterpret_cast<unsigned char*>(control_frame->data()),
2324 control_frame->length() + SpdyControlFrame::kHeaderSize);
2325 EXPECT_EQ(1, visitor.headers_frame_count_);
2326 // control_frame_header_data_count_ depends on the random sequence
2327 // produced by rand(), so adding, removing or running single tests
2328 // alters this value. The best we can do is assert that it happens
2329 // at least twice.
2330 EXPECT_LE(2, visitor.control_frame_header_data_count_);
2331 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
2332 EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
2333 EXPECT_TRUE(CompareHeaderBlocks(&headers, &visitor.headers_));
2334 }
2335
2336 TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) {
2337 SpdyHeaderBlock headers;
2338 // Size a header value to just fit inside the control frame buffer:
2339 // SPDY 2 SPDY 3
2340 // SYN_STREAM header: 18 bytes 18 bytes
2341 // Serialized header block:
2342 // # headers 2 bytes (uint16) 4 bytes (uint32)
2343 // name length 2 bytes (uint16) 4 bytes (uint32)
2344 // name text ("aa") 2 bytes 2 bytes
2345 // value length 2 bytes (uint16) 4 bytes (uint32)
2346 // --- ---
2347 // 26 bytes 32 bytes
2348 const size_t overhead = IsSpdy2() ? 26 : 32;
2349 const size_t big_value_size =
2350 TestSpdyVisitor::control_frame_buffer_max_size() - overhead;
2351 std::string big_value(big_value_size, 'x');
2352 headers["aa"] = big_value.c_str();
2353 SpdyFramer framer(spdy_version_);
2354 scoped_ptr<SpdySynStreamControlFrame> control_frame(
2355 framer.CreateSynStream(1, // stream_id
2356 0, // associated_stream_id
2357 1, // priority
2358 0, // credential_slot
2359 CONTROL_FLAG_NONE,
2360 false, // compress
2361 &headers));
2362 EXPECT_TRUE(control_frame.get() != NULL);
2363 TestSpdyVisitor visitor(spdy_version_);
2364 visitor.SimulateInFramer(
2365 reinterpret_cast<unsigned char*>(control_frame->data()),
2366 control_frame->length() + SpdyControlFrame::kHeaderSize);
2367 EXPECT_TRUE(visitor.header_buffer_valid_);
2368 EXPECT_EQ(0, visitor.error_count_);
2369 EXPECT_EQ(1, visitor.syn_frame_count_);
2370 EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
2371 EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
2372 EXPECT_LT(big_value_size, visitor.header_buffer_length_);
2373 }
2374
2375 TEST_P(SpdyFramerTest, ControlFrameTooLarge) {
2376 SpdyHeaderBlock headers;
2377 // See size calculation for test above. This is one byte larger, which
2378 // should exceed the control frame buffer capacity by that one byte.
2379 const size_t overhead = IsSpdy2() ? 25 : 31;
2380 const size_t kBigValueSize =
2381 TestSpdyVisitor::control_frame_buffer_max_size() - overhead;
2382 std::string big_value(kBigValueSize, 'x');
2383 headers["aa"] = big_value.c_str();
2384 SpdyFramer framer(spdy_version_);
2385 scoped_ptr<SpdySynStreamControlFrame> control_frame(
2386 framer.CreateSynStream(1, // stream_id
2387 0, // associated_stream_id
2388 1, // priority
2389 0, // credential_slot
2390 CONTROL_FLAG_NONE,
2391 false, // compress
2392 &headers));
2393 EXPECT_TRUE(control_frame.get() != NULL);
2394 TestSpdyVisitor visitor(spdy_version_);
2395 visitor.SimulateInFramer(
2396 reinterpret_cast<unsigned char*>(control_frame->data()),
2397 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
2398 EXPECT_FALSE(visitor.header_buffer_valid_);
2399 EXPECT_EQ(1, visitor.error_count_);
2400 EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
2401 visitor.framer_.error_code());
2402 EXPECT_EQ(0, visitor.syn_frame_count_);
2403 EXPECT_EQ(0u, visitor.header_buffer_length_);
2404 }
2405
2406 // Check that the framer stops delivering header data chunks once the visitor
2407 // declares it doesn't want any more. This is important to guard against
2408 // "zip bomb" types of attacks.
2409 TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) {
2410 SpdyHeaderBlock headers;
2411 const size_t kHeaderBufferChunks = 4;
2412 const size_t kHeaderBufferSize =
2413 TestSpdyVisitor::header_data_chunk_max_size() * kHeaderBufferChunks;
2414 const size_t big_value_size = kHeaderBufferSize * 2;
2415 std::string big_value(big_value_size, 'x');
2416 headers["aa"] = big_value.c_str();
2417 SpdyFramer framer(spdy_version_);
2418 scoped_ptr<SpdySynStreamControlFrame> control_frame(
2419 framer.CreateSynStream(1, // stream_id
2420 0, // associated_stream_id
2421 1, // priority
2422 0, // credential_slot
2423 CONTROL_FLAG_FIN, // half close
2424 true, // compress
2425 &headers));
2426 EXPECT_TRUE(control_frame.get() != NULL);
2427 TestSpdyVisitor visitor(spdy_version_);
2428 visitor.set_header_buffer_size(kHeaderBufferSize);
2429 visitor.use_compression_ = true;
2430 visitor.SimulateInFramer(
2431 reinterpret_cast<unsigned char*>(control_frame->data()),
2432 control_frame->length() + SpdyControlFrame::kHeaderSize);
2433 EXPECT_FALSE(visitor.header_buffer_valid_);
2434 EXPECT_EQ(1, visitor.error_count_);
2435 EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
2436 visitor.framer_.error_code());
2437
2438 // The framer should have stoped delivering chunks after the visitor
2439 // signaled "stop" by returning false from OnControlFrameHeaderData().
2440 //
2441 // control_frame_header_data_count_ depends on the random sequence
2442 // produced by rand(), so adding, removing or running single tests
2443 // alters this value. The best we can do is assert that it happens
2444 // at least kHeaderBufferChunks + 1.
2445 EXPECT_LE(kHeaderBufferChunks + 1,
2446 static_cast<unsigned>(visitor.control_frame_header_data_count_));
2447 EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
2448
2449 // The framer should not have sent half-close to the visitor.
2450 EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
2451 }
2452
2453 TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) {
2454 SpdyHeaderBlock headers;
2455 headers["aa"] = "alpha beta gamma delta";
2456 SpdyFramer framer(spdy_version_);
2457 // Construct a SYN_STREAM control frame without compressing the header block,
2458 // and have the framer try to decompress it. This will cause the framer to
2459 // deal with a decompression error.
2460 scoped_ptr<SpdySynStreamControlFrame> control_frame(
2461 framer.CreateSynStream(1, // stream_id
2462 0, // associated_stream_id
2463 1, // priority
2464 0, // credential_slot
2465 CONTROL_FLAG_NONE,
2466 false, // compress
2467 &headers));
2468 TestSpdyVisitor visitor(spdy_version_);
2469 visitor.use_compression_ = true;
2470 visitor.SimulateInFramer(
2471 reinterpret_cast<unsigned char*>(control_frame->data()),
2472 control_frame->length() + SpdyControlFrame::kHeaderSize);
2473 EXPECT_EQ(1, visitor.error_count_);
2474 EXPECT_EQ(SpdyFramer::SPDY_DECOMPRESS_FAILURE, visitor.framer_.error_code());
2475 EXPECT_EQ(0u, visitor.header_buffer_length_);
2476 }
2477
2239 TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) { 2478 TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) {
2240 // Create a GoAway frame that has a few extra bytes at the end. 2479 // Create a GoAway frame that has a few extra bytes at the end.
2241 // We create enough overhead to overflow the framer's control frame buffer. 2480 // We create enough overhead to overflow the framer's control frame buffer.
2242 size_t overhead = SpdyFramer::kControlFrameBufferSize; 2481 size_t overhead = SpdyFramer::kControlFrameBufferSize;
2243 2482
2244 SpdyFramer framer(spdy_version_); 2483 SpdyFramer framer(spdy_version_);
2245 scoped_ptr<SpdyGoAwayControlFrame> goaway(framer.CreateGoAway(1, GOAWAY_OK)); 2484 scoped_ptr<SpdyGoAwayControlFrame> goaway(framer.CreateGoAway(1, GOAWAY_OK));
2246 goaway->set_length(goaway->length() + overhead); 2485 goaway->set_length(goaway->length() + overhead);
2247 std::string pad('A', overhead); 2486 std::string pad('A', overhead);
2248 TestSpdyVisitor visitor(spdy_version_); 2487 TestSpdyVisitor visitor(spdy_version_);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2354 EXPECT_EQ(1, visitor.credential_count_); 2593 EXPECT_EQ(1, visitor.credential_count_);
2355 EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_); 2594 EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_);
2356 EXPECT_EQ(credential.slot, visitor.credential_.slot); 2595 EXPECT_EQ(credential.slot, visitor.credential_.slot);
2357 EXPECT_EQ(credential.proof, visitor.credential_.proof); 2596 EXPECT_EQ(credential.proof, visitor.credential_.proof);
2358 EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size()); 2597 EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
2359 for (size_t i = 0; i < credential.certs.size(); i++) { 2598 for (size_t i = 0; i < credential.certs.size(); i++) {
2360 EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]); 2599 EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
2361 } 2600 }
2362 } 2601 }
2363 2602
2603 TEST_P(SpdyFramerTest, ReadCredentialFrameOneByteAtATime) {
2604 SpdyCredential credential;
2605 credential.slot = 3;
2606 credential.proof = "proof";
2607 credential.certs.push_back("a cert");
2608 credential.certs.push_back("another cert");
2609 credential.certs.push_back("final cert");
2610 SpdyFramer framer(spdy_version_);
2611 scoped_ptr<SpdyFrame> control_frame(
2612 framer.CreateCredentialFrame(credential));
2613 EXPECT_TRUE(control_frame.get() != NULL);
2614 TestSpdyVisitor visitor(spdy_version_);
2615 visitor.use_compression_ = false;
2616 // Read one byte at a time to make sure we handle edge cases
2617 unsigned char* data =
2618 reinterpret_cast<unsigned char*>(control_frame->data());
2619 for (size_t idx = 0;
2620 idx < control_frame->length() + SpdyFrame::kHeaderSize;
2621 ++idx) {
2622 visitor.SimulateInFramer(data + idx, 1);
2623 ASSERT_EQ(0, visitor.error_count_);
2624 }
2625 EXPECT_EQ(0, visitor.error_count_);
2626 EXPECT_EQ(1, visitor.credential_count_);
2627 EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_);
2628 EXPECT_EQ(credential.slot, visitor.credential_.slot);
2629 EXPECT_EQ(credential.proof, visitor.credential_.proof);
2630 EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
2631 for (size_t i = 0; i < credential.certs.size(); i++) {
2632 EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
2633 }
2634 }
2635
2636 TEST_P(SpdyFramerTest, ReadCredentialFrameWithNoPayload) {
2637 SpdyCredential credential;
2638 credential.slot = 3;
2639 credential.proof = "proof";
2640 credential.certs.push_back("a cert");
2641 credential.certs.push_back("another cert");
2642 credential.certs.push_back("final cert");
2643 SpdyFramer framer(spdy_version_);
2644 scoped_ptr<SpdyFrame> control_frame(
2645 framer.CreateCredentialFrame(credential));
2646 EXPECT_TRUE(control_frame.get() != NULL);
2647 TestSpdyVisitor visitor(spdy_version_);
2648 visitor.use_compression_ = false;
2649 control_frame->set_length(0);
2650 unsigned char* data =
2651 reinterpret_cast<unsigned char*>(control_frame->data());
2652 visitor.SimulateInFramer(data, SpdyControlFrame::kHeaderSize);
2653 EXPECT_EQ(1, visitor.error_count_);
2654 }
2655
2364 TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) { 2656 TEST_P(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) {
2365 SpdyCredential credential; 2657 SpdyCredential credential;
2366 credential.slot = 3; 2658 credential.slot = 3;
2367 credential.proof = "proof"; 2659 credential.proof = "proof";
2368 credential.certs.push_back("a cert"); 2660 credential.certs.push_back("a cert");
2369 credential.certs.push_back("another cert"); 2661 credential.certs.push_back("another cert");
2370 credential.certs.push_back("final cert"); 2662 credential.certs.push_back("final cert");
2371 SpdyFramer framer(spdy_version_); 2663 SpdyFramer framer(spdy_version_);
2372 scoped_ptr<SpdyFrame> control_frame( 2664 scoped_ptr<SpdyFrame> control_frame(
2373 framer.CreateCredentialFrame(credential)); 2665 framer.CreateCredentialFrame(credential));
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 htonl(IsSpdy2() ? 0x04030201 : 0x01020304); 2958 htonl(IsSpdy2() ? 0x04030201 : 0x01020304);
2667 2959
2668 SettingsFlagsAndId id_and_flags = 2960 SettingsFlagsAndId id_and_flags =
2669 SettingsFlagsAndId::FromWireFormat(spdy_version_, kWireFormat); 2961 SettingsFlagsAndId::FromWireFormat(spdy_version_, kWireFormat);
2670 EXPECT_EQ(kId, id_and_flags.id()); 2962 EXPECT_EQ(kId, id_and_flags.id());
2671 EXPECT_EQ(kFlags, id_and_flags.flags()); 2963 EXPECT_EQ(kFlags, id_and_flags.flags());
2672 EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(spdy_version_)); 2964 EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(spdy_version_));
2673 } 2965 }
2674 2966
2675 } // namespace net 2967 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698