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

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