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

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

Issue 1914663002: Increase read buffer size for SPDY upload (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
« no previous file with comments | « net/spdy/spdy_http_stream.cc ('k') | 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 <cmath>
5 #include <memory> 6 #include <memory>
6 #include <string> 7 #include <string>
7 #include <utility> 8 #include <utility>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
12 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 52
52 //----------------------------------------------------------------------------- 53 //-----------------------------------------------------------------------------
53 54
54 namespace net { 55 namespace net {
55 56
56 namespace { 57 namespace {
57 58
58 using testing::Each; 59 using testing::Each;
59 using testing::Eq; 60 using testing::Eq;
60 61
62 // This currently 16kB.
Bence 2016/04/26 16:59:23 I think it would be better to remove this comment,
xunjieli 2016/04/26 17:03:16 Done.
63 const int32_t kBufferSize = SpdyHttpStream::kRequestBodyBufferSize;
64
61 enum SpdyNetworkTransactionTestSSLType { 65 enum SpdyNetworkTransactionTestSSLType {
62 // Request an https:// URL and use NPN (or ALPN) to negotiate SPDY during 66 // Request an https:// URL and use NPN (or ALPN) to negotiate SPDY during
63 // the TLS handshake. 67 // the TLS handshake.
64 HTTPS_SPDY_VIA_NPN, 68 HTTPS_SPDY_VIA_NPN,
65 // Request and http:// URL to a server that supports SPDY via Alternative 69 // Request and http:// URL to a server that supports SPDY via Alternative
66 // Service on port 443. 70 // Service on port 443.
67 // See: https//tools.ietf.org/id/draft-ietf-httpbis-alt-svc-06.html 71 // See: https//tools.ietf.org/id/draft-ietf-httpbis-alt-svc-06.html
68 HTTP_SPDY_VIA_ALT_SVC, 72 HTTP_SPDY_VIA_ALT_SVC,
69 }; 73 };
70 74
(...skipping 6457 matching lines...) Expand 10 before | Expand all | Expand 10 after
6528 // ("hello!") is not permitted to go through since by the time its turn 6532 // ("hello!") is not permitted to go through since by the time its turn
6529 // arrives, window size is 0. At this point MessageLoop::Run() called via 6533 // arrives, window size is 0. At this point MessageLoop::Run() called via
6530 // callback would block. Therefore we call MessageLoop::RunUntilIdle() 6534 // callback would block. Therefore we call MessageLoop::RunUntilIdle()
6531 // which returns after performing all possible writes. We use DCHECKS to 6535 // which returns after performing all possible writes. We use DCHECKS to
6532 // ensure that last data frame is still there and stream has stalled. 6536 // ensure that last data frame is still there and stream has stalled.
6533 // After that, next read is artifically enforced, which causes a 6537 // After that, next read is artifically enforced, which causes a
6534 // WINDOW_UPDATE to be read and I/O process resumes. 6538 // WINDOW_UPDATE to be read and I/O process resumes.
6535 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { 6539 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
6536 const int32_t initial_window_size = 6540 const int32_t initial_window_size =
6537 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); 6541 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
6538 // Number of frames we need to send to zero out the window size: data 6542 // Number of upload data buffers we need to send to zero out the window size
6539 // frames plus SYN_STREAM plus the last data frame; also we need another 6543 // is the minimal number of upload buffers takes to be bigger than
6540 // data frame that we will send once the WINDOW_UPDATE is received, 6544 // |initial_window_size|.
6541 // therefore +3. 6545 size_t num_upload_buffers =
6542 size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; 6546 ceil(static_cast<double>(initial_window_size) / kBufferSize);
6543 6547 // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
6544 // Calculate last frame's size; 0 size data frame is legal. 6548 // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
6545 size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; 6549 // which has kBufferSize % kMaxSpdyChunkSize bytes.
6550 size_t num_frames_in_one_upload_buffer =
6551 ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
6546 6552
6547 // Construct content for a data frame of maximum size. 6553 // Construct content for a data frame of maximum size.
6548 std::string content(kMaxSpdyFrameChunkSize, 'a'); 6554 std::string content(kMaxSpdyFrameChunkSize, 'a');
6549 6555
6550 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( 6556 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
6551 GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, 6557 GetDefaultUrl(), 1,
6552 0)); 6558 /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
6559 LOWEST, NULL, 0));
6553 6560
6554 // Full frames. 6561 // Full frames.
6555 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 6562 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
6556 1, content.c_str(), content.size(), false)); 6563 1, content.c_str(), content.size(), false));
6557 6564
6558 // Last frame to zero out the window size. 6565 // Last frame in each upload data buffer.
6559 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( 6566 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
6560 1, content.c_str(), last_frame_size, false)); 6567 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false));
6561 6568
6562 // Data frame to be sent once WINDOW_UPDATE frame is received. 6569 // The very last frame before the stalled frames.
6563 std::unique_ptr<SpdySerializedFrame> body3( 6570 std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame(
6571 1, content.c_str(),
6572 initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false));
6573
6574 // Data frames to be sent once WINDOW_UPDATE frame is received.
6575
6576 // If kBufferSize * num_upload_buffers > initial_window_size,
6577 // we need one additional frame to send the rest of 'a'.
6578 std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
6579 'a');
6580 std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame(
6581 1, last_body.c_str(), last_body.size(), false));
6582
6583 // Also send a "hello!" after WINDOW_UPDATE.
6584 std::unique_ptr<SpdySerializedFrame> body5(
6564 spdy_util_.ConstructSpdyBodyFrame(1, true)); 6585 spdy_util_.ConstructSpdyBodyFrame(1, true));
6565 6586
6566 // Fill in mock writes. 6587 // Fill in mock writes.
6567 std::unique_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
6568 size_t i = 0; 6588 size_t i = 0;
6569 writes[i] = CreateMockWrite(*req, i); 6589 std::vector<MockWrite> writes;
6570 for (i = 1; i < num_writes - 2; i++) 6590 writes.push_back(CreateMockWrite(*req, i++));
6571 writes[i] = CreateMockWrite(*body1, i); 6591 for (size_t j = 0; j < num_upload_buffers; j++) {
6572 writes[i] = CreateMockWrite(*body2, i); 6592 for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
6573 // The last write must not be attempted until after the WINDOW_UPDATES 6593 if (k == num_frames_in_one_upload_buffer - 1 &&
6574 // have been received. 6594 kBufferSize % kMaxSpdyFrameChunkSize != 0) {
6575 writes[i + 1] = CreateMockWrite(*body3, i + 4, SYNCHRONOUS); 6595 if (j == num_upload_buffers - 1 &&
6596 (initial_window_size % kBufferSize != 0)) {
6597 writes.push_back(CreateMockWrite(*body3, i++));
6598 } else {
6599 writes.push_back(CreateMockWrite(*body2, i++));
6600 }
6601 } else {
6602 writes.push_back(CreateMockWrite(*body1, i++));
6603 }
6604 }
6605 }
6576 6606
6577 // Construct read frame, give enough space to upload the rest of the 6607 // Fill in mock reads.
6578 // data. 6608 std::vector<MockRead> reads;
6609 // Force a pause.
6610 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++));
6611 // Construct read frame for window updates that gives enough space to upload
6612 // the rest of the data.
6579 std::unique_ptr<SpdySerializedFrame> session_window_update( 6613 std::unique_ptr<SpdySerializedFrame> session_window_update(
6580 spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); 6614 spdy_util_.ConstructSpdyWindowUpdate(0,
6615 kUploadDataSize + last_body.size()));
6581 std::unique_ptr<SpdySerializedFrame> window_update( 6616 std::unique_ptr<SpdySerializedFrame> window_update(
6582 spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); 6617 spdy_util_.ConstructSpdyWindowUpdate(1,
6618 kUploadDataSize + last_body.size()));
6619
6620 reads.push_back(CreateMockRead(*session_window_update, i++));
6621 reads.push_back(CreateMockRead(*window_update, i++));
6622
6623 // Stalled frames which can be sent after receiving window updates.
6624 if (last_body.size() > 0)
6625 writes.push_back(CreateMockWrite(*body4, i++));
6626 writes.push_back(CreateMockWrite(*body5, i++));
6627
6583 std::unique_ptr<SpdySerializedFrame> reply( 6628 std::unique_ptr<SpdySerializedFrame> reply(
6584 spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6629 spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6585 MockRead reads[] = { 6630 reads.push_back(CreateMockRead(*reply, i++));
6586 MockRead(ASYNC, ERR_IO_PENDING, i + 1), // Force a pause 6631 reads.push_back(CreateMockRead(*body2, i++));
6587 CreateMockRead(*session_window_update, i + 2), 6632 reads.push_back(CreateMockRead(*body5, i++));
6588 CreateMockRead(*window_update, i + 3), 6633 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
6589 // Now the last write will occur.
6590 CreateMockRead(*reply, i + 5),
6591 CreateMockRead(*body2, i + 6),
6592 CreateMockRead(*body3, i + 7),
6593 MockRead(ASYNC, 0, i + 8) // EOF
6594 };
6595 6634
6596 SequencedSocketData data(reads, arraysize(reads), writes.get(), num_writes); 6635 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
6636 writes.size());
6597 6637
6598 std::vector<std::unique_ptr<UploadElementReader>> element_readers; 6638 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
6599 std::string upload_data_string(initial_window_size, 'a'); 6639 std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
6600 upload_data_string.append(kUploadData, kUploadDataSize); 6640 upload_data_string.append(kUploadData, kUploadDataSize);
6601 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( 6641 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader(
6602 upload_data_string.c_str(), upload_data_string.size()))); 6642 upload_data_string.c_str(), upload_data_string.size())));
6603 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); 6643 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
6604 6644
6605 HttpRequestInfo request; 6645 HttpRequestInfo request;
6606 request.method = "POST"; 6646 request.method = "POST";
6607 request.url = GURL(GetDefaultUrl()); 6647 request.url = GURL(GetDefaultUrl());
6608 request.upload_data_stream = &upload_data_stream; 6648 request.upload_data_stream = &upload_data_stream;
6609 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 6649 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
6610 BoundNetLog(), GetParam(), NULL); 6650 GetParam(), NULL);
6611 helper.AddData(&data); 6651 helper.AddData(&data);
6612 helper.RunPreTestSetup(); 6652 helper.RunPreTestSetup();
6613 6653
6614 HttpNetworkTransaction* trans = helper.trans(); 6654 HttpNetworkTransaction* trans = helper.trans();
6615 6655
6616 TestCompletionCallback callback; 6656 TestCompletionCallback callback;
6617 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 6657 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6618 EXPECT_EQ(ERR_IO_PENDING, rv); 6658 EXPECT_EQ(ERR_IO_PENDING, rv);
6619 6659
6620 base::RunLoop().RunUntilIdle(); // Write as much as we can. 6660 base::RunLoop().RunUntilIdle(); // Write as much as we can.
6621 6661
6622 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6662 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6623 ASSERT_TRUE(stream != NULL); 6663 ASSERT_TRUE(stream != NULL);
6624 ASSERT_TRUE(stream->stream() != NULL); 6664 ASSERT_TRUE(stream->stream() != NULL);
6625 EXPECT_EQ(0, stream->stream()->send_window_size()); 6665 EXPECT_EQ(0, stream->stream()->send_window_size());
6626 // All the body data should have been read. 6666 if (initial_window_size % kBufferSize != 0) {
6627 // TODO(satorux): This is because of the weirdness in reading the request 6667 // If it does not take whole number of full upload buffer to zero out
6628 // body in OnSendBodyComplete(). See crbug.com/113107. 6668 // initial window size, then the upload data is not at EOF, because the
6629 EXPECT_TRUE(upload_data_stream.IsEOF()); 6669 // last read must be stalled.
6670 EXPECT_FALSE(upload_data_stream.IsEOF());
6671 } else {
6672 // All the body data should have been read.
6673 // TODO(satorux): This is because of the weirdness in reading the request
6674 // body in OnSendBodyComplete(). See crbug.com/113107.
6675 EXPECT_TRUE(upload_data_stream.IsEOF());
6676 }
6630 // But the body is not yet fully sent (kUploadData is not yet sent) 6677 // But the body is not yet fully sent (kUploadData is not yet sent)
6631 // since we're send-stalled. 6678 // since we're send-stalled.
6632 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 6679 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6633 6680
6634 data.Resume(); // Read in WINDOW_UPDATE frame. 6681 data.Resume(); // Read in WINDOW_UPDATE frame.
6635 rv = callback.WaitForResult(); 6682 rv = callback.WaitForResult();
6636 helper.VerifyDataConsumed(); 6683 helper.VerifyDataConsumed();
6637 } 6684 }
6638 6685
6639 // Test we correctly handle the case where the SETTINGS frame results in 6686 // Test we correctly handle the case where the SETTINGS frame results in
6640 // unstalling the send window. 6687 // unstalling the send window.
6641 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { 6688 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
6642 const int32_t initial_window_size = 6689 const int32_t initial_window_size =
6643 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); 6690 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
6644 6691 // Number of upload data buffers we need to send to zero out the window size
6645 // Number of frames we need to send to zero out the window size: data 6692 // is the minimal number of upload buffers takes to be bigger than
6646 // frames plus SYN_STREAM plus the last data frame; also we need another 6693 // |initial_window_size|.
6647 // data frame that we will send once the SETTING is received, therefore +3. 6694 size_t num_upload_buffers =
6648 size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; 6695 ceil(static_cast<double>(initial_window_size) / kBufferSize);
6649 6696 // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
6650 // Calculate last frame's size; 0 size data frame is legal. 6697 // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
6651 size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; 6698 // which has kBufferSize % kMaxSpdyChunkSize bytes.
6699 size_t num_frames_in_one_upload_buffer =
6700 ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
6652 6701
6653 // Construct content for a data frame of maximum size. 6702 // Construct content for a data frame of maximum size.
6654 std::string content(kMaxSpdyFrameChunkSize, 'a'); 6703 std::string content(kMaxSpdyFrameChunkSize, 'a');
6655 6704
6656 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( 6705 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
6657 GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, 6706 GetDefaultUrl(), 1,
6658 0)); 6707 /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
6708 LOWEST, NULL, 0));
6659 6709
6660 // Full frames. 6710 // Full frames.
6661 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 6711 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
6662 1, content.c_str(), content.size(), false)); 6712 1, content.c_str(), content.size(), false));
6663 6713
6664 // Last frame to zero out the window size. 6714 // Last frame in each upload data buffer.
6665 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( 6715 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
6666 1, content.c_str(), last_frame_size, false)); 6716 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false));
6667 6717
6668 // Data frame to be sent once SETTINGS frame is received. 6718 // The very last frame before the stalled frames.
6669 std::unique_ptr<SpdySerializedFrame> body3( 6719 std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame(
6720 1, content.c_str(),
6721 initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false));
6722
6723 // Data frames to be sent once WINDOW_UPDATE frame is received.
6724
6725 // If kBufferSize * num_upload_buffers > initial_window_size,
6726 // we need one additional frame to send the rest of 'a'.
6727 std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
6728 'a');
6729 std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame(
6730 1, last_body.c_str(), last_body.size(), false));
6731
6732 // Also send a "hello!" after WINDOW_UPDATE.
6733 std::unique_ptr<SpdySerializedFrame> body5(
6670 spdy_util_.ConstructSpdyBodyFrame(1, true)); 6734 spdy_util_.ConstructSpdyBodyFrame(1, true));
6671 6735
6672 // Fill in mock reads/writes. 6736 // Fill in mock writes.
6737 size_t i = 0;
6738 std::vector<MockWrite> writes;
6739 writes.push_back(CreateMockWrite(*req, i++));
6740 for (size_t j = 0; j < num_upload_buffers; j++) {
6741 for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
6742 if (k == num_frames_in_one_upload_buffer - 1 &&
6743 kBufferSize % kMaxSpdyFrameChunkSize != 0) {
6744 if (j == num_upload_buffers - 1 &&
6745 (initial_window_size % kBufferSize != 0)) {
6746 writes.push_back(CreateMockWrite(*body3, i++));
6747 } else {
6748 writes.push_back(CreateMockWrite(*body2, i++));
6749 }
6750 } else {
6751 writes.push_back(CreateMockWrite(*body1, i++));
6752 }
6753 }
6754 }
6755
6756 // Fill in mock reads.
6673 std::vector<MockRead> reads; 6757 std::vector<MockRead> reads;
6674 std::vector<MockWrite> writes; 6758 // Force a pause.
6675 size_t i = 0;
6676 writes.push_back(CreateMockWrite(*req, i++));
6677 while (i < num_writes - 2)
6678 writes.push_back(CreateMockWrite(*body1, i++));
6679 writes.push_back(CreateMockWrite(*body2, i++));
6680
6681 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++)); 6759 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++));
6682 6760
6683 // Construct read frame for SETTINGS that gives enough space to upload the 6761 // Construct read frame for SETTINGS that gives enough space to upload the
6684 // rest of the data. 6762 // rest of the data.
6685 SettingsMap settings; 6763 SettingsMap settings;
6686 settings[SETTINGS_INITIAL_WINDOW_SIZE] = 6764 settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6687 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size * 2); 6765 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size * 2);
6688 std::unique_ptr<SpdySerializedFrame> settings_frame_large( 6766 std::unique_ptr<SpdySerializedFrame> settings_frame_large(
6689 spdy_util_.ConstructSpdySettings(settings)); 6767 spdy_util_.ConstructSpdySettings(settings));
6690 6768
6691 reads.push_back(CreateMockRead(*settings_frame_large, i++)); 6769 reads.push_back(CreateMockRead(*settings_frame_large, i++));
6692 6770
6693 std::unique_ptr<SpdySerializedFrame> session_window_update( 6771 std::unique_ptr<SpdySerializedFrame> session_window_update(
6694 spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); 6772 spdy_util_.ConstructSpdyWindowUpdate(0,
6773 last_body.size() + kUploadDataSize));
6695 reads.push_back(CreateMockRead(*session_window_update, i++)); 6774 reads.push_back(CreateMockRead(*session_window_update, i++));
6696 6775
6697 std::unique_ptr<SpdySerializedFrame> settings_ack( 6776 std::unique_ptr<SpdySerializedFrame> settings_ack(
6698 spdy_util_.ConstructSpdySettingsAck()); 6777 spdy_util_.ConstructSpdySettingsAck());
6699 writes.push_back(CreateMockWrite(*settings_ack, i++)); 6778 writes.push_back(CreateMockWrite(*settings_ack, i++));
6700 6779
6701 writes.push_back(CreateMockWrite(*body3, i++)); 6780 // Stalled frames which can be sent after |settings_ack|.
6781 if (last_body.size() > 0)
6782 writes.push_back(CreateMockWrite(*body4, i++));
6783 writes.push_back(CreateMockWrite(*body5, i++));
6702 6784
6703 std::unique_ptr<SpdySerializedFrame> reply( 6785 std::unique_ptr<SpdySerializedFrame> reply(
6704 spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6786 spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6705 reads.push_back(CreateMockRead(*reply, i++)); 6787 reads.push_back(CreateMockRead(*reply, i++));
6706 reads.push_back(CreateMockRead(*body2, i++)); 6788 reads.push_back(CreateMockRead(*body2, i++));
6707 reads.push_back(CreateMockRead(*body3, i++)); 6789 reads.push_back(CreateMockRead(*body5, i++));
6708 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF 6790 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
6709 6791
6710 // Force all writes to happen before any read, last write will not 6792 // Force all writes to happen before any read, last write will not
6711 // actually queue a frame, due to window size being 0. 6793 // actually queue a frame, due to window size being 0.
6712 SequencedSocketData data(reads.data(), reads.size(), writes.data(), 6794 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
6713 writes.size()); 6795 writes.size());
6714 6796
6715 std::vector<std::unique_ptr<UploadElementReader>> element_readers; 6797 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
6716 std::string upload_data_string(initial_window_size, 'a'); 6798 std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
6717 upload_data_string.append(kUploadData, kUploadDataSize); 6799 upload_data_string.append(kUploadData, kUploadDataSize);
6718 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( 6800 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader(
6719 upload_data_string.c_str(), upload_data_string.size()))); 6801 upload_data_string.c_str(), upload_data_string.size())));
6720 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); 6802 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
6721 6803
6722 HttpRequestInfo request; 6804 HttpRequestInfo request;
6723 request.method = "POST"; 6805 request.method = "POST";
6724 request.url = GURL(GetDefaultUrl()); 6806 request.url = GURL(GetDefaultUrl());
6725 request.upload_data_stream = &upload_data_stream; 6807 request.upload_data_stream = &upload_data_stream;
6726 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 6808 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6727 BoundNetLog(), GetParam(), NULL); 6809 BoundNetLog(), GetParam(), NULL);
6728 helper.RunPreTestSetup(); 6810 helper.RunPreTestSetup();
6729 helper.AddData(&data); 6811 helper.AddData(&data);
6730 6812
6731 HttpNetworkTransaction* trans = helper.trans(); 6813 HttpNetworkTransaction* trans = helper.trans();
6732 6814
6733 TestCompletionCallback callback; 6815 TestCompletionCallback callback;
6734 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 6816 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6735 EXPECT_EQ(ERR_IO_PENDING, rv); 6817 EXPECT_EQ(ERR_IO_PENDING, rv);
6736 6818
6737 data.RunUntilPaused(); // Write as much as we can. 6819 data.RunUntilPaused(); // Write as much as we can.
6738 base::RunLoop().RunUntilIdle(); 6820 base::RunLoop().RunUntilIdle();
6739 6821
6740 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6822 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6741 ASSERT_TRUE(stream != NULL); 6823 ASSERT_TRUE(stream != NULL);
6742 ASSERT_TRUE(stream->stream() != NULL); 6824 ASSERT_TRUE(stream->stream() != NULL);
6743 EXPECT_EQ(0, stream->stream()->send_window_size()); 6825 EXPECT_EQ(0, stream->stream()->send_window_size());
6744 6826
6745 // All the body data should have been read. 6827 if (initial_window_size % kBufferSize != 0) {
6746 // TODO(satorux): This is because of the weirdness in reading the request 6828 // If it does not take whole number of full upload buffer to zero out
6747 // body in OnSendBodyComplete(). See crbug.com/113107. 6829 // initial window size, then the upload data is not at EOF, because the
6748 EXPECT_TRUE(upload_data_stream.IsEOF()); 6830 // last read must be stalled.
6831 EXPECT_FALSE(upload_data_stream.IsEOF());
6832 } else {
6833 // All the body data should have been read.
6834 // TODO(satorux): This is because of the weirdness in reading the request
6835 // body in OnSendBodyComplete(). See crbug.com/113107.
6836 EXPECT_TRUE(upload_data_stream.IsEOF());
6837 }
6749 // But the body is not yet fully sent (kUploadData is not yet sent) 6838 // But the body is not yet fully sent (kUploadData is not yet sent)
6750 // since we're send-stalled. 6839 // since we're send-stalled.
6751 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 6840 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6752 6841
6753 // Read in SETTINGS frame to unstall. 6842 // Read in SETTINGS frame to unstall.
6754 data.Resume(); 6843 data.Resume();
6755 base::RunLoop().RunUntilIdle(); 6844 base::RunLoop().RunUntilIdle();
6756 6845
6757 rv = callback.WaitForResult(); 6846 rv = callback.WaitForResult();
6758 helper.VerifyDataConsumed(); 6847 helper.VerifyDataConsumed();
6759 // If stream is NULL, that means it was unstalled and closed. 6848 // If stream is NULL, that means it was unstalled and closed.
6760 EXPECT_TRUE(stream->stream() == NULL); 6849 EXPECT_TRUE(stream->stream() == NULL);
6761 } 6850 }
6762 6851
6763 // Test we correctly handle the case where the SETTINGS frame results in a 6852 // Test we correctly handle the case where the SETTINGS frame results in a
6764 // negative send window size. 6853 // negative send window size.
6765 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { 6854 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
6766 const int32_t initial_window_size = 6855 const int32_t initial_window_size =
6767 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); 6856 SpdySession::GetDefaultInitialWindowSize(GetParam().protocol);
6768 // Number of frames we need to send to zero out the window size: data 6857 // Number of upload data buffers we need to send to zero out the window size
6769 // frames plus SYN_STREAM plus the last data frame; also we need another 6858 // is the minimal number of upload buffers takes to be bigger than
6770 // data frame that we will send once the SETTING is received, therefore +3. 6859 // |initial_window_size|.
6771 size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; 6860 size_t num_upload_buffers =
6772 6861 ceil(static_cast<double>(initial_window_size) / kBufferSize);
6773 // Calculate last frame's size; 0 size data frame is legal. 6862 // Each upload data buffer consists of |num_frames_in_one_upload_buffer|
6774 size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; 6863 // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame,
6864 // which has kBufferSize % kMaxSpdyChunkSize bytes.
6865 size_t num_frames_in_one_upload_buffer =
6866 ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize);
6775 6867
6776 // Construct content for a data frame of maximum size. 6868 // Construct content for a data frame of maximum size.
6777 std::string content(kMaxSpdyFrameChunkSize, 'a'); 6869 std::string content(kMaxSpdyFrameChunkSize, 'a');
6778 6870
6779 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( 6871 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
6780 GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, 6872 GetDefaultUrl(), 1,
6781 0)); 6873 /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize,
6874 LOWEST, NULL, 0));
6782 6875
6783 // Full frames. 6876 // Full frames.
6784 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 6877 std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
6785 1, content.c_str(), content.size(), false)); 6878 1, content.c_str(), content.size(), false));
6786 6879
6787 // Last frame to zero out the window size. 6880 // Last frame in each upload data buffer.
6788 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( 6881 std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
6789 1, content.c_str(), last_frame_size, false)); 6882 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false));
6790 6883
6791 // Data frame to be sent once SETTINGS frame is received. 6884 // The very last frame before the stalled frames.
6792 std::unique_ptr<SpdySerializedFrame> body3( 6885 std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame(
6886 1, content.c_str(),
6887 initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false));
6888
6889 // Data frames to be sent once WINDOW_UPDATE frame is received.
6890
6891 // If kBufferSize * num_upload_buffers > initial_window_size,
6892 // we need one additional frame to send the rest of 'a'.
6893 std::string last_body(kBufferSize * num_upload_buffers - initial_window_size,
6894 'a');
6895 std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame(
6896 1, last_body.c_str(), last_body.size(), false));
6897
6898 // Also send a "hello!" after WINDOW_UPDATE.
6899 std::unique_ptr<SpdySerializedFrame> body5(
6793 spdy_util_.ConstructSpdyBodyFrame(1, true)); 6900 spdy_util_.ConstructSpdyBodyFrame(1, true));
6794 6901
6795 // Fill in mock reads/writes. 6902 // Fill in mock writes.
6903 size_t i = 0;
6904 std::vector<MockWrite> writes;
6905 writes.push_back(CreateMockWrite(*req, i++));
6906 for (size_t j = 0; j < num_upload_buffers; j++) {
6907 for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) {
6908 if (k == num_frames_in_one_upload_buffer - 1 &&
6909 kBufferSize % kMaxSpdyFrameChunkSize != 0) {
6910 if (j == num_upload_buffers - 1 &&
6911 (initial_window_size % kBufferSize != 0)) {
6912 writes.push_back(CreateMockWrite(*body3, i++));
6913 } else {
6914 writes.push_back(CreateMockWrite(*body2, i++));
6915 }
6916 } else {
6917 writes.push_back(CreateMockWrite(*body1, i++));
6918 }
6919 }
6920 }
6921
6922 // Fill in mock reads.
6796 std::vector<MockRead> reads; 6923 std::vector<MockRead> reads;
6797 std::vector<MockWrite> writes; 6924 // Force a pause.
6798 size_t i = 0;
6799 writes.push_back(CreateMockWrite(*req, i++));
6800 while (i < num_writes - 2)
6801 writes.push_back(CreateMockWrite(*body1, i++));
6802 writes.push_back(CreateMockWrite(*body2, i++));
6803
6804 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++)); 6925 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++));
6805
6806 // Construct read frame for SETTINGS that makes the send_window_size 6926 // Construct read frame for SETTINGS that makes the send_window_size
6807 // negative. 6927 // negative.
6808 SettingsMap new_settings; 6928 SettingsMap new_settings;
6809 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = 6929 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6810 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size / 2); 6930 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size / 2);
6811 std::unique_ptr<SpdySerializedFrame> settings_frame_small( 6931 std::unique_ptr<SpdySerializedFrame> settings_frame_small(
6812 spdy_util_.ConstructSpdySettings(new_settings)); 6932 spdy_util_.ConstructSpdySettings(new_settings));
6813 // Construct read frames for WINDOW_UPDATE that makes the send_window_size 6933 // Construct read frames for WINDOW_UPDATE that makes the send_window_size
6814 // positive. 6934 // positive.
6815 std::unique_ptr<SpdySerializedFrame> session_window_update_init_size( 6935 std::unique_ptr<SpdySerializedFrame> session_window_update_init_size(
6816 spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size)); 6936 spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size));
6817 std::unique_ptr<SpdySerializedFrame> window_update_init_size( 6937 std::unique_ptr<SpdySerializedFrame> window_update_init_size(
6818 spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size)); 6938 spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size));
6819 6939
6820 reads.push_back(CreateMockRead(*settings_frame_small, i++)); 6940 reads.push_back(CreateMockRead(*settings_frame_small, i++));
6821 reads.push_back(CreateMockRead(*session_window_update_init_size, i++)); 6941 reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
6822 reads.push_back(CreateMockRead(*window_update_init_size, i++)); 6942 reads.push_back(CreateMockRead(*window_update_init_size, i++));
6823 6943
6824 std::unique_ptr<SpdySerializedFrame> settings_ack( 6944 std::unique_ptr<SpdySerializedFrame> settings_ack(
6825 spdy_util_.ConstructSpdySettingsAck()); 6945 spdy_util_.ConstructSpdySettingsAck());
6826 writes.push_back(CreateMockWrite(*settings_ack, i++)); 6946 writes.push_back(CreateMockWrite(*settings_ack, i++));
6827 6947
6828 writes.push_back(CreateMockWrite(*body3, i++)); 6948 // Stalled frames which can be sent after |settings_ack|.
6949 if (last_body.size() > 0)
6950 writes.push_back(CreateMockWrite(*body4, i++));
6951 writes.push_back(CreateMockWrite(*body5, i++));
6829 6952
6830 std::unique_ptr<SpdySerializedFrame> reply( 6953 std::unique_ptr<SpdySerializedFrame> reply(
6831 spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 6954 spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6832 reads.push_back(CreateMockRead(*reply, i++)); 6955 reads.push_back(CreateMockRead(*reply, i++));
6833 reads.push_back(CreateMockRead(*body2, i++)); 6956 reads.push_back(CreateMockRead(*body2, i++));
6834 reads.push_back(CreateMockRead(*body3, i++)); 6957 reads.push_back(CreateMockRead(*body5, i++));
6835 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF 6958 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
6836 6959
6837 // Force all writes to happen before any read, last write will not 6960 // Force all writes to happen before any read, last write will not
6838 // actually queue a frame, due to window size being 0. 6961 // actually queue a frame, due to window size being 0.
6839 SequencedSocketData data(reads.data(), reads.size(), writes.data(), 6962 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
6840 writes.size()); 6963 writes.size());
6841 6964
6842 std::vector<std::unique_ptr<UploadElementReader>> element_readers; 6965 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
6843 std::string upload_data_string(initial_window_size, 'a'); 6966 std::string upload_data_string(kBufferSize * num_upload_buffers, 'a');
6844 upload_data_string.append(kUploadData, kUploadDataSize); 6967 upload_data_string.append(kUploadData, kUploadDataSize);
6845 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( 6968 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader(
6846 upload_data_string.c_str(), upload_data_string.size()))); 6969 upload_data_string.c_str(), upload_data_string.size())));
6847 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); 6970 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
6848 6971
6849 HttpRequestInfo request; 6972 HttpRequestInfo request;
6850 request.method = "POST"; 6973 request.method = "POST";
6851 request.url = GURL(GetDefaultUrl()); 6974 request.url = GURL(GetDefaultUrl());
6852 request.upload_data_stream = &upload_data_stream; 6975 request.upload_data_stream = &upload_data_stream;
6853 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, 6976 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6854 BoundNetLog(), GetParam(), NULL); 6977 BoundNetLog(), GetParam(), NULL);
6855 helper.RunPreTestSetup(); 6978 helper.RunPreTestSetup();
6856 helper.AddData(&data); 6979 helper.AddData(&data);
6857 6980
6858 HttpNetworkTransaction* trans = helper.trans(); 6981 HttpNetworkTransaction* trans = helper.trans();
6859 6982
6860 TestCompletionCallback callback; 6983 TestCompletionCallback callback;
6861 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog()); 6984 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6862 EXPECT_EQ(ERR_IO_PENDING, rv); 6985 EXPECT_EQ(ERR_IO_PENDING, rv);
6863 6986
6864 data.RunUntilPaused(); // Write as much as we can. 6987 data.RunUntilPaused(); // Write as much as we can.
6865 base::RunLoop().RunUntilIdle(); 6988 base::RunLoop().RunUntilIdle();
6866 6989
6867 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get()); 6990 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6868 ASSERT_TRUE(stream != NULL); 6991 ASSERT_TRUE(stream != NULL);
6869 ASSERT_TRUE(stream->stream() != NULL); 6992 ASSERT_TRUE(stream->stream() != NULL);
6870 EXPECT_EQ(0, stream->stream()->send_window_size()); 6993 EXPECT_EQ(0, stream->stream()->send_window_size());
6871 6994
6872 // All the body data should have been read. 6995 if (initial_window_size % kBufferSize != 0) {
6873 // TODO(satorux): This is because of the weirdness in reading the request 6996 // If it does not take whole number of full upload buffer to zero out
6874 // body in OnSendBodyComplete(). See crbug.com/113107. 6997 // initial window size, then the upload data is not at EOF, because the
6875 EXPECT_TRUE(upload_data_stream.IsEOF()); 6998 // last read must be stalled.
6876 // But the body is not yet fully sent (kUploadData is not yet sent) 6999 EXPECT_FALSE(upload_data_stream.IsEOF());
6877 // since we're send-stalled. 7000 } else {
6878 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); 7001 // All the body data should have been read.
7002 // TODO(satorux): This is because of the weirdness in reading the request
7003 // body in OnSendBodyComplete(). See crbug.com/113107.
7004 EXPECT_TRUE(upload_data_stream.IsEOF());
7005 }
6879 7006
6880 // Read in WINDOW_UPDATE or SETTINGS frame. 7007 // Read in WINDOW_UPDATE or SETTINGS frame.
6881 data.Resume(); 7008 data.Resume();
6882 base::RunLoop().RunUntilIdle(); 7009 base::RunLoop().RunUntilIdle();
6883 rv = callback.WaitForResult(); 7010 rv = callback.WaitForResult();
6884 helper.VerifyDataConsumed(); 7011 helper.VerifyDataConsumed();
6885 } 7012 }
6886 7013
6887 TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) { 7014 TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) {
6888 std::unique_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); 7015 std::unique_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
7131 TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) { 7258 TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) {
7132 std::unique_ptr<SSLSocketDataProvider> ssl_provider( 7259 std::unique_ptr<SSLSocketDataProvider> ssl_provider(
7133 new SSLSocketDataProvider(ASYNC, OK)); 7260 new SSLSocketDataProvider(ASYNC, OK));
7134 // Set to TLS_RSA_WITH_NULL_MD5 7261 // Set to TLS_RSA_WITH_NULL_MD5
7135 SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status); 7262 SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status);
7136 7263
7137 RunTLSUsageCheckTest(std::move(ssl_provider)); 7264 RunTLSUsageCheckTest(std::move(ssl_provider));
7138 } 7265 }
7139 7266
7140 } // namespace net 7267 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_http_stream.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698