blob: 7d107cbfea1d31acfc82aca986de027d5b913d2e [file] [log] [blame]
[email protected]f702d572012-12-04 15:56:201// 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
3// found in the LICENSE file.
4
5#include "net/quic/quic_http_stream.h"
6
7#include <vector>
8
9#include "net/base/net_errors.h"
10#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0611#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2012#include "net/base/upload_data_stream.h"
13#include "net/http/http_response_headers.h"
[email protected]fee17f72013-02-03 07:47:4114#include "net/quic/congestion_control/receive_algorithm_interface.h"
15#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0516#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1617#include "net/quic/crypto/quic_decrypter.h"
18#include "net/quic/crypto/quic_encrypter.h"
[email protected]f702d572012-12-04 15:56:2019#include "net/quic/quic_client_session.h"
20#include "net/quic/quic_connection.h"
21#include "net/quic/quic_connection_helper.h"
22#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0523#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0324#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3925#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]f702d572012-12-04 15:56:2026#include "net/quic/test_tools/quic_test_utils.h"
27#include "net/quic/test_tools/test_task_runner.h"
28#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3629#include "net/spdy/spdy_frame_builder.h"
30#include "net/spdy/spdy_framer.h"
31#include "net/spdy/spdy_http_utils.h"
32#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2033#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gtest/include/gtest/gtest.h"
35
36using testing::_;
37
38namespace net {
[email protected]f702d572012-12-04 15:56:2039namespace test {
[email protected]f702d572012-12-04 15:56:2040namespace {
41
42const char kUploadData[] = "hello world!";
43
44class TestQuicConnection : public QuicConnection {
45 public:
46 TestQuicConnection(QuicGuid guid,
47 IPEndPoint address,
48 QuicConnectionHelper* helper)
[email protected]48878092013-07-26 14:51:5649 : QuicConnection(guid, address, helper, false, QuicVersionMax()) {
[email protected]f702d572012-12-04 15:56:2050 }
51
[email protected]fee17f72013-02-03 07:47:4152 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
53 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2054 }
[email protected]26f3f8e2012-12-13 21:07:1955
[email protected]fee17f72013-02-03 07:47:4156 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
57 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
[email protected]26f3f8e2012-12-13 21:07:1958 }
59};
60
[email protected]fee17f72013-02-03 07:47:4161class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
[email protected]26f3f8e2012-12-13 21:07:1962 public:
[email protected]fee17f72013-02-03 07:47:4163 explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback)
64 : feedback_(feedback) {
[email protected]26f3f8e2012-12-13 21:07:1965 }
66
67 bool GenerateCongestionFeedback(
68 QuicCongestionFeedbackFrame* congestion_feedback) {
69 if (feedback_ == NULL) {
70 return false;
71 }
72 *congestion_feedback = *feedback_;
73 return true;
74 }
75
76 MOCK_METHOD4(RecordIncomingPacket,
[email protected]fee17f72013-02-03 07:47:4177 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool));
[email protected]26f3f8e2012-12-13 21:07:1978
79 private:
80 MockClock clock_;
81 QuicCongestionFeedbackFrame* feedback_;
82
[email protected]fee17f72013-02-03 07:47:4183 DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm);
[email protected]f702d572012-12-04 15:56:2084};
85
[email protected]63534512012-12-23 18:49:0086// Subclass of QuicHttpStream that closes itself when the first piece of data
87// is received.
88class AutoClosingStream : public QuicHttpStream {
89 public:
[email protected]0b2294d32013-08-02 00:46:3690 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
91 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0092 }
93
[email protected]46fadfd2013-02-06 09:40:1694 virtual int OnDataReceived(const char* data, int length) OVERRIDE {
[email protected]63534512012-12-23 18:49:0095 Close(false);
96 return OK;
97 }
98};
99
[email protected]f702d572012-12-04 15:56:20100} // namespace
101
[email protected]6cca996b2013-01-25 07:43:36102class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
[email protected]f702d572012-12-04 15:56:20103 protected:
104 const static bool kFin = true;
[email protected]f702d572012-12-04 15:56:20105 // Holds a packet to be written to the wire, and the IO mode that should
106 // be used by the mock socket when performing the write.
107 struct PacketToWrite {
108 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
109 : mode(mode),
110 packet(packet) {
111 }
112 IoMode mode;
113 QuicEncryptedPacket* packet;
114 };
115
116 QuicHttpStreamTest()
117 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00118 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20119 read_buffer_(new IOBufferWithSize(4096)),
120 guid_(2),
[email protected]48878092013-07-26 14:51:56121 framer_(QuicVersionMax(), QuicTime::Zero(), false),
[email protected]14e8106c2013-03-14 16:25:33122 creator_(guid_, &framer_, &random_, false) {
[email protected]f702d572012-12-04 15:56:20123 IPAddressNumber ip;
124 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
125 peer_addr_ = IPEndPoint(ip, 443);
126 self_addr_ = IPEndPoint(ip, 8435);
[email protected]f702d572012-12-04 15:56:20127 }
128
129 ~QuicHttpStreamTest() {
130 for (size_t i = 0; i < writes_.size(); i++) {
131 delete writes_[i].packet;
132 }
133 }
134
135 // Adds a packet to the list of expected writes.
136 void AddWrite(IoMode mode, QuicEncryptedPacket* packet) {
137 writes_.push_back(PacketToWrite(mode, packet));
138 }
139
140 // Returns the packet to be written at position |pos|.
141 QuicEncryptedPacket* GetWrite(size_t pos) {
142 return writes_[pos].packet;
143 }
144
145 bool AtEof() {
146 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
147 }
148
149 void ProcessPacket(const QuicEncryptedPacket& packet) {
150 connection_->ProcessUdpPacket(self_addr_, peer_addr_, packet);
151 }
152
153 // Configures the test fixture to use the list of expected writes.
154 void Initialize() {
155 mock_writes_.reset(new MockWrite[writes_.size()]);
156 for (size_t i = 0; i < writes_.size(); i++) {
157 mock_writes_[i] = MockWrite(writes_[i].mode,
158 writes_[i].packet->data(),
159 writes_[i].packet->length());
160 };
161
162 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
163 writes_.size()));
164
[email protected]e13201d82012-12-12 05:00:32165 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
166 net_log_.net_log());
167 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20168 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41169 send_algorithm_ = new MockSendAlgorithm();
170 receive_algorithm_ = new TestReceiveAlgorithm(NULL);
[email protected]48878092013-07-26 14:51:56171 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
172 testing::Return(QuicTime::Delta::Zero()));
[email protected]575cce62013-08-03 02:06:43173 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
[email protected]c995c572013-01-18 05:43:20174 WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45175 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(
176 testing::Return(QuicTime::Delta::Zero()));
177 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
178 testing::Return(QuicBandwidth::Zero()));
[email protected]9558c5d32012-12-22 00:08:14179 helper_ = new QuicConnectionHelper(runner_.get(), &clock_,
180 &random_generator_, socket);
[email protected]e13201d82012-12-12 05:00:32181 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_);
[email protected]f702d572012-12-04 15:56:20182 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41183 connection_->SetSendAlgorithm(send_algorithm_);
184 connection_->SetReceiveAlgorithm(receive_algorithm_);
[email protected]ef95114d2013-04-17 17:57:01185 crypto_config_.SetDefaults();
[email protected]18ccfdb2013-08-15 00:13:44186 session_.reset(
187 new QuicClientSession(connection_,
188 scoped_ptr<DatagramClientSocket>(socket), NULL,
189 &crypto_client_stream_factory_,
190 "www.google.com", DefaultQuicConfig(),
191 &crypto_config_, NULL));
[email protected]ed3fc15d2013-03-08 18:37:44192 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48193 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36194 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36195 new AutoClosingStream(session_->GetWeakPtr()) :
196 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36197 }
198
199 void SetRequestString(const std::string& method, const std::string& path) {
[email protected]9d9e7932013-02-25 18:31:05200 SpdyHeaderBlock headers;
201 headers[":method"] = method;
202 headers[":host"] = "www.google.com";
203 headers[":path"] = path;
204 headers[":scheme"] = "http";
205 headers[":version"] = "HTTP/1.1";
206 request_data_ = SerializeHeaderBlock(headers);
[email protected]6cca996b2013-01-25 07:43:36207 }
208
209 void SetResponseString(const std::string& status, const std::string& body) {
[email protected]9d9e7932013-02-25 18:31:05210 SpdyHeaderBlock headers;
211 headers[":status"] = status;
212 headers[":version"] = "HTTP/1.1";
213 headers["content-type"] = "text/plain";
[email protected]821555c2013-05-16 20:20:17214 response_data_ = SerializeHeaderBlock(headers) + body;
[email protected]6cca996b2013-01-25 07:43:36215 }
216
217 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
[email protected]821555c2013-05-16 20:20:17218 QuicSpdyCompressor compressor;
[email protected]e4e47462013-08-22 19:37:46219 return compressor.CompressHeaders(headers);
[email protected]6cca996b2013-01-25 07:43:36220 }
[email protected]f702d572012-12-04 15:56:20221
222 // Returns a newly created packet to send kData on stream 1.
223 QuicEncryptedPacket* ConstructDataPacket(
224 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05225 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20226 bool fin,
227 QuicStreamOffset offset,
228 base::StringPiece data) {
[email protected]e8ff26842013-03-22 21:02:05229 InitializeHeader(sequence_number, should_include_version);
[email protected]f702d572012-12-04 15:56:20230 QuicStreamFrame frame(3, fin, offset, data);
231 return ConstructPacket(header_, QuicFrame(&frame));
232 }
233
234 // Returns a newly created packet to send ack data.
235 QuicEncryptedPacket* ConstructAckPacket(
236 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00237 QuicPacketSequenceNumber largest_received,
238 QuicPacketSequenceNumber least_unacked) {
[email protected]e8ff26842013-03-22 21:02:05239 InitializeHeader(sequence_number, false);
[email protected]f702d572012-12-04 15:56:20240
[email protected]14e8106c2013-03-14 16:25:33241 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]9db443912013-02-25 05:27:03242 ack.sent_info.entropy_hash = 0;
243 ack.received_info.entropy_hash = 0;
244
[email protected]f702d572012-12-04 15:56:20245 return ConstructPacket(header_, QuicFrame(&ack));
246 }
247
[email protected]63534512012-12-23 18:49:00248 // Returns a newly created packet to send ack data.
249 QuicEncryptedPacket* ConstructRstPacket(
250 QuicPacketSequenceNumber sequence_number,
[email protected]9db443912013-02-25 05:27:03251 QuicStreamId stream_id) {
[email protected]e8ff26842013-03-22 21:02:05252 InitializeHeader(sequence_number, false);
[email protected]63534512012-12-23 18:49:00253
[email protected]74bda142013-03-31 02:49:11254 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
[email protected]63534512012-12-23 18:49:00255 return ConstructPacket(header_, QuicFrame(&rst));
256 }
257
[email protected]f702d572012-12-04 15:56:20258 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00259 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41260 MockSendAlgorithm* send_algorithm_;
261 TestReceiveAlgorithm* receive_algorithm_;
[email protected]f702d572012-12-04 15:56:20262 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17263 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20264 MockClock clock_;
[email protected]9558c5d32012-12-22 00:08:14265 MockRandom random_generator_;
[email protected]f702d572012-12-04 15:56:20266 TestQuicConnection* connection_;
[email protected]e13201d82012-12-12 05:00:32267 QuicConnectionHelper* helper_;
[email protected]f702d572012-12-04 15:56:20268 testing::StrictMock<MockConnectionVisitor> visitor_;
269 scoped_ptr<QuicHttpStream> stream_;
270 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01271 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20272 TestCompletionCallback callback_;
273 HttpRequestInfo request_;
274 HttpRequestHeaders headers_;
275 HttpResponseInfo response_;
276 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]6cca996b2013-01-25 07:43:36277 std::string request_data_;
278 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20279
280 private:
[email protected]e8ff26842013-03-22 21:02:05281 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
282 bool should_include_version) {
[email protected]c995c572013-01-18 05:43:20283 header_.public_header.guid = guid_;
[email protected]9db443912013-02-25 05:27:03284 header_.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:05285 header_.public_header.version_flag = should_include_version;
[email protected]ea825e02013-08-21 18:12:45286 header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
[email protected]f702d572012-12-04 15:56:20287 header_.packet_sequence_number = sequence_number;
[email protected]f702d572012-12-04 15:56:20288 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03289 header_.entropy_flag = false;
290 header_.fec_flag = false;
[email protected]f702d572012-12-04 15:56:20291 }
292
293 QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header,
294 const QuicFrame& frame) {
295 QuicFrames frames;
296 frames.push_back(frame);
[email protected]610a7e942012-12-18 00:21:39297 scoped_ptr<QuicPacket> packet(
[email protected]3e60db82013-08-05 19:43:06298 framer_.BuildUnsizedDataPacket(header_, frames).packet);
[email protected]8ba81212013-05-03 13:11:48299 return framer_.EncryptPacket(
300 ENCRYPTION_NONE, header.packet_sequence_number, *packet);
[email protected]f702d572012-12-04 15:56:20301 }
302
303 const QuicGuid guid_;
304 QuicFramer framer_;
305 IPEndPoint self_addr_;
306 IPEndPoint peer_addr_;
[email protected]9db443912013-02-25 05:27:03307 MockRandom random_;
[email protected]e8ff26842013-03-22 21:02:05308 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20309 QuicPacketCreator creator_;
310 QuicPacketHeader header_;
[email protected]f702d572012-12-04 15:56:20311 scoped_ptr<StaticSocketDataProvider> socket_data_;
312 std::vector<PacketToWrite> writes_;
313};
314
[email protected]9d9e7932013-02-25 18:31:05315TEST_F(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44316 Initialize();
[email protected]f702d572012-12-04 15:56:20317 EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
318}
319
[email protected]9d9e7932013-02-25 18:31:05320TEST_F(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44321 Initialize();
[email protected]f702d572012-12-04 15:56:20322 EXPECT_TRUE(stream_->CanFindEndOfResponse());
323}
324
[email protected]9d9e7932013-02-25 18:31:05325TEST_F(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44326 Initialize();
[email protected]f702d572012-12-04 15:56:20327 EXPECT_FALSE(stream_->IsConnectionReusable());
328}
329
[email protected]9d9e7932013-02-25 18:31:05330TEST_F(QuicHttpStreamTest, GetRequest) {
[email protected]6cca996b2013-01-25 07:43:36331 SetRequestString("GET", "/");
[email protected]e8ff26842013-03-22 21:02:05332 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0,
[email protected]6cca996b2013-01-25 07:43:36333 request_data_));
[email protected]f702d572012-12-04 15:56:20334 Initialize();
335
336 request_.method = "GET";
337 request_.url = GURL("http://www.google.com/");
338
[email protected]262eec82013-03-19 21:01:36339 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
340 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20341 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
342 callback_.callback()));
343 EXPECT_EQ(&response_, stream_->GetResponseInfo());
344
345 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05346 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20347 ProcessPacket(*ack);
348
349 EXPECT_EQ(ERR_IO_PENDING,
350 stream_->ReadResponseHeaders(callback_.callback()));
351
352 // Send the response without a body.
[email protected]007b3f82013-04-09 08:46:45353 SetResponseString("404 Not Found", std::string());
[email protected]f702d572012-12-04 15:56:20354 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05355 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20356 ProcessPacket(*resp);
357
358 // Now that the headers have been processed, the callback will return.
359 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36360 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20361 EXPECT_EQ(404, response_.headers->response_code());
362 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
363
364 // There is no body, so this should return immediately.
365 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
366 read_buffer_->size(),
367 callback_.callback()));
368 EXPECT_TRUE(stream_->IsResponseBodyComplete());
369 EXPECT_TRUE(AtEof());
370}
371
[email protected]9d9e7932013-02-25 18:31:05372TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) {
[email protected]6cca996b2013-01-25 07:43:36373 SetRequestString("GET", "/");
[email protected]e8ff26842013-03-22 21:02:05374 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
[email protected]f702d572012-12-04 15:56:20375 Initialize();
376
377 request_.method = "GET";
378 request_.url = GURL("http://www.google.com/");
379
[email protected]262eec82013-03-19 21:01:36380 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
381 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20382 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
383 callback_.callback()));
384 EXPECT_EQ(&response_, stream_->GetResponseInfo());
385
386 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05387 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20388 ProcessPacket(*ack);
389
390 EXPECT_EQ(ERR_IO_PENDING,
391 stream_->ReadResponseHeaders(callback_.callback()));
392
393 // Send the response with a body.
[email protected]6cca996b2013-01-25 07:43:36394 SetResponseString("200 OK", "hello world!");
[email protected]f702d572012-12-04 15:56:20395 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05396 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20397 ProcessPacket(*resp);
398
399 // Now that the headers have been processed, the callback will return.
400 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36401 ASSERT_TRUE(response_.headers.get());
[email protected]6cca996b2013-01-25 07:43:36402 EXPECT_EQ(200, response_.headers->response_code());
[email protected]f702d572012-12-04 15:56:20403 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
404
405 // There is no body, so this should return immediately.
406 // Since the body has already arrived, this should return immediately.
407 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(),
408 read_buffer_->size(),
409 callback_.callback()));
410 EXPECT_TRUE(stream_->IsResponseBodyComplete());
411 EXPECT_TRUE(AtEof());
412}
413
[email protected]9d9e7932013-02-25 18:31:05414TEST_F(QuicHttpStreamTest, SendPostRequest) {
[email protected]6cca996b2013-01-25 07:43:36415 SetRequestString("POST", "/");
[email protected]e8ff26842013-03-22 21:02:05416 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
417 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin,
418 request_data_.length(),
[email protected]f702d572012-12-04 15:56:20419 kUploadData));
[email protected]ec640112013-08-09 03:56:18420 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20421
422 Initialize();
423
[email protected]b2d26cfd2012-12-11 10:36:06424 ScopedVector<UploadElementReader> element_readers;
425 element_readers.push_back(
426 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
427 UploadDataStream upload_data_stream(&element_readers, 0);
[email protected]f702d572012-12-04 15:56:20428 request_.method = "POST";
429 request_.url = GURL("http://www.google.com/");
430 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24431 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20432
[email protected]262eec82013-03-19 21:01:36433 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
434 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20435 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
436 callback_.callback()));
437 EXPECT_EQ(&response_, stream_->GetResponseInfo());
438
439 // Ack both packets in the request.
[email protected]e8ff26842013-03-22 21:02:05440 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20441 ProcessPacket(*ack);
442
443 // Send the response headers (but not the body).
[email protected]007b3f82013-04-09 08:46:45444 SetResponseString("200 OK", std::string());
[email protected]f702d572012-12-04 15:56:20445 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05446 ConstructDataPacket(2, false, !kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20447 ProcessPacket(*resp);
448
449 // Since the headers have already arrived, this should return immediately.
450 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36451 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20452 EXPECT_EQ(200, response_.headers->response_code());
453 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
454
455 // Send the response body.
456 const char kResponseBody[] = "Hello world!";
457 scoped_ptr<QuicEncryptedPacket> resp_body(
[email protected]e8ff26842013-03-22 21:02:05458 ConstructDataPacket(3, false, kFin, response_data_.length(),
459 kResponseBody));
[email protected]f702d572012-12-04 15:56:20460 ProcessPacket(*resp_body);
461
462 // Since the body has already arrived, this should return immediately.
463 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
464 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
465 callback_.callback()));
466
467 EXPECT_TRUE(stream_->IsResponseBodyComplete());
468 EXPECT_TRUE(AtEof());
469}
470
[email protected]c9e49a02013-02-26 05:56:47471TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) {
472 SetRequestString("POST", "/");
473 size_t chunk_size = strlen(kUploadData);
[email protected]e8ff26842013-03-22 21:02:05474 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
475 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin,
476 request_data_.length(),
[email protected]c9e49a02013-02-26 05:56:47477 kUploadData));
[email protected]e8ff26842013-03-22 21:02:05478 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin,
[email protected]c9e49a02013-02-26 05:56:47479 request_data_.length() + chunk_size,
480 kUploadData));
[email protected]ec640112013-08-09 03:56:18481 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47482
483 Initialize();
484
485 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
486 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
487
488 request_.method = "POST";
489 request_.url = GURL("http://www.google.com/");
490 request_.upload_data_stream = &upload_data_stream;
491 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
492
[email protected]262eec82013-03-19 21:01:36493 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
494 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47495 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
496 callback_.callback()));
497 EXPECT_EQ(&response_, stream_->GetResponseInfo());
498
499 upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
500
501 // Ack both packets in the request.
[email protected]e8ff26842013-03-22 21:02:05502 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47503 ProcessPacket(*ack);
504
505 // Send the response headers (but not the body).
[email protected]007b3f82013-04-09 08:46:45506 SetResponseString("200 OK", std::string());
[email protected]c9e49a02013-02-26 05:56:47507 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05508 ConstructDataPacket(2, false, !kFin, 0, response_data_));
[email protected]c9e49a02013-02-26 05:56:47509 ProcessPacket(*resp);
510
511 // Since the headers have already arrived, this should return immediately.
512 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36513 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47514 EXPECT_EQ(200, response_.headers->response_code());
515 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
516
517 // Send the response body.
518 const char kResponseBody[] = "Hello world!";
519 scoped_ptr<QuicEncryptedPacket> resp_body(
[email protected]e8ff26842013-03-22 21:02:05520 ConstructDataPacket(3, false, kFin, response_data_.length(),
521 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47522 ProcessPacket(*resp_body);
523
524 // Since the body has already arrived, this should return immediately.
525 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
526 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
527 callback_.callback()));
528
529 EXPECT_TRUE(stream_->IsResponseBodyComplete());
530 EXPECT_TRUE(AtEof());
531}
532
[email protected]9d9e7932013-02-25 18:31:05533TEST_F(QuicHttpStreamTest, DestroyedEarly) {
[email protected]6cca996b2013-01-25 07:43:36534 SetRequestString("GET", "/");
[email protected]e8ff26842013-03-22 21:02:05535 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
[email protected]63534512012-12-23 18:49:00536 use_closing_stream_ = true;
537 Initialize();
538
539 request_.method = "GET";
540 request_.url = GURL("http://www.google.com/");
541
[email protected]262eec82013-03-19 21:01:36542 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
543 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00544 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
545 callback_.callback()));
546 EXPECT_EQ(&response_, stream_->GetResponseInfo());
547
548 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05549 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00550 ProcessPacket(*ack);
551 EXPECT_EQ(ERR_IO_PENDING,
552 stream_->ReadResponseHeaders(callback_.callback()));
553
554 // Send the response with a body.
[email protected]c244c5a12013-05-07 20:55:04555 SetResponseString("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00556 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]c244c5a12013-05-07 20:55:04557 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]63534512012-12-23 18:49:00558
559 // In the course of processing this packet, the QuicHttpStream close itself.
560 ProcessPacket(*resp);
561
562 EXPECT_TRUE(AtEof());
563}
564
[email protected]f702d572012-12-04 15:56:20565} // namespace test
566
567} // namespace net