blob: b26087f9a1024f998c9b006e4ff89a27f84cb36b [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"
[email protected]24e5bc52013-09-18 15:36:5822#include "net/quic/quic_http_utils.h"
23#include "net/quic/quic_reliable_client_stream.h"
[email protected]3e7dca62013-09-10 16:14:2324#include "net/quic/spdy_utils.h"
[email protected]f702d572012-12-04 15:56:2025#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0526#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0327#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3928#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]f702d572012-12-04 15:56:2029#include "net/quic/test_tools/quic_test_utils.h"
30#include "net/quic/test_tools/test_task_runner.h"
31#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3632#include "net/spdy/spdy_frame_builder.h"
33#include "net/spdy/spdy_framer.h"
34#include "net/spdy/spdy_http_utils.h"
35#include "net/spdy/spdy_protocol.h"
[email protected]24e5bc52013-09-18 15:36:5836#include "net/spdy/write_blocked_list.h"
[email protected]f702d572012-12-04 15:56:2037#include "testing/gmock/include/gmock/gmock.h"
38#include "testing/gtest/include/gtest/gtest.h"
39
40using testing::_;
[email protected]06ff5152013-08-29 01:03:0541using testing::AnyNumber;
42using testing::Return;
[email protected]f702d572012-12-04 15:56:2043
44namespace net {
[email protected]f702d572012-12-04 15:56:2045namespace test {
[email protected]f702d572012-12-04 15:56:2046namespace {
47
48const char kUploadData[] = "hello world!";
49
50class TestQuicConnection : public QuicConnection {
51 public:
52 TestQuicConnection(QuicGuid guid,
53 IPEndPoint address,
54 QuicConnectionHelper* helper)
[email protected]48878092013-07-26 14:51:5655 : QuicConnection(guid, address, helper, false, QuicVersionMax()) {
[email protected]f702d572012-12-04 15:56:2056 }
57
[email protected]fee17f72013-02-03 07:47:4158 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
59 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2060 }
[email protected]26f3f8e2012-12-13 21:07:1961
[email protected]fee17f72013-02-03 07:47:4162 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
63 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
[email protected]26f3f8e2012-12-13 21:07:1964 }
65};
66
[email protected]fee17f72013-02-03 07:47:4167class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
[email protected]26f3f8e2012-12-13 21:07:1968 public:
[email protected]fee17f72013-02-03 07:47:4169 explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback)
70 : feedback_(feedback) {
[email protected]26f3f8e2012-12-13 21:07:1971 }
72
73 bool GenerateCongestionFeedback(
74 QuicCongestionFeedbackFrame* congestion_feedback) {
75 if (feedback_ == NULL) {
76 return false;
77 }
78 *congestion_feedback = *feedback_;
79 return true;
80 }
81
82 MOCK_METHOD4(RecordIncomingPacket,
[email protected]fee17f72013-02-03 07:47:4183 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool));
[email protected]26f3f8e2012-12-13 21:07:1984
85 private:
86 MockClock clock_;
87 QuicCongestionFeedbackFrame* feedback_;
88
[email protected]fee17f72013-02-03 07:47:4189 DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm);
[email protected]f702d572012-12-04 15:56:2090};
91
[email protected]63534512012-12-23 18:49:0092// Subclass of QuicHttpStream that closes itself when the first piece of data
93// is received.
94class AutoClosingStream : public QuicHttpStream {
95 public:
[email protected]0b2294d32013-08-02 00:46:3696 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
97 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0098 }
99
[email protected]46fadfd2013-02-06 09:40:16100 virtual int OnDataReceived(const char* data, int length) OVERRIDE {
[email protected]63534512012-12-23 18:49:00101 Close(false);
102 return OK;
103 }
104};
105
[email protected]f702d572012-12-04 15:56:20106} // namespace
107
[email protected]24e5bc52013-09-18 15:36:58108class QuicHttpStreamPeer {
109 public:
110 static QuicReliableClientStream* GetQuicReliableClientStream(
111 QuicHttpStream* stream) {
112 return stream->stream_;
113 }
114};
115
[email protected]6cca996b2013-01-25 07:43:36116class QuicHttpStreamTest : public ::testing::TestWithParam<bool> {
[email protected]f702d572012-12-04 15:56:20117 protected:
118 const static bool kFin = true;
[email protected]f702d572012-12-04 15:56:20119 // Holds a packet to be written to the wire, and the IO mode that should
120 // be used by the mock socket when performing the write.
121 struct PacketToWrite {
122 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
123 : mode(mode),
124 packet(packet) {
125 }
126 IoMode mode;
127 QuicEncryptedPacket* packet;
128 };
129
130 QuicHttpStreamTest()
131 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00132 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20133 read_buffer_(new IOBufferWithSize(4096)),
134 guid_(2),
[email protected]48878092013-07-26 14:51:56135 framer_(QuicVersionMax(), QuicTime::Zero(), false),
[email protected]14e8106c2013-03-14 16:25:33136 creator_(guid_, &framer_, &random_, false) {
[email protected]f702d572012-12-04 15:56:20137 IPAddressNumber ip;
138 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
139 peer_addr_ = IPEndPoint(ip, 443);
140 self_addr_ = IPEndPoint(ip, 8435);
[email protected]d6202d012013-09-03 21:38:32141 // TODO(rch): remove this.
142 QuicConnection::g_acks_do_not_instigate_acks = true;
[email protected]f702d572012-12-04 15:56:20143 }
144
145 ~QuicHttpStreamTest() {
146 for (size_t i = 0; i < writes_.size(); i++) {
147 delete writes_[i].packet;
148 }
[email protected]d6202d012013-09-03 21:38:32149 // TODO(rch): remove this.
150 QuicConnection::g_acks_do_not_instigate_acks = false;
[email protected]f702d572012-12-04 15:56:20151 }
152
153 // Adds a packet to the list of expected writes.
154 void AddWrite(IoMode mode, QuicEncryptedPacket* packet) {
155 writes_.push_back(PacketToWrite(mode, packet));
156 }
157
158 // Returns the packet to be written at position |pos|.
159 QuicEncryptedPacket* GetWrite(size_t pos) {
160 return writes_[pos].packet;
161 }
162
163 bool AtEof() {
164 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
165 }
166
167 void ProcessPacket(const QuicEncryptedPacket& packet) {
168 connection_->ProcessUdpPacket(self_addr_, peer_addr_, packet);
169 }
170
171 // Configures the test fixture to use the list of expected writes.
172 void Initialize() {
173 mock_writes_.reset(new MockWrite[writes_.size()]);
174 for (size_t i = 0; i < writes_.size(); i++) {
175 mock_writes_[i] = MockWrite(writes_[i].mode,
176 writes_[i].packet->data(),
177 writes_[i].packet->length());
178 };
179
180 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
181 writes_.size()));
182
[email protected]e13201d82012-12-12 05:00:32183 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
184 net_log_.net_log());
185 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20186 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41187 send_algorithm_ = new MockSendAlgorithm();
188 receive_algorithm_ = new TestReceiveAlgorithm(NULL);
[email protected]06ff5152013-08-29 01:03:05189 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)).
190 Times(AnyNumber());
[email protected]efecff92013-09-24 07:49:23191 EXPECT_CALL(*send_algorithm_,
192 OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
[email protected]48878092013-07-26 14:51:56193 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05194 Return(QuicTime::Delta::Zero()));
[email protected]575cce62013-08-03 02:06:43195 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
[email protected]06ff5152013-08-29 01:03:05196 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45197 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05198 Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45199 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05200 Return(QuicBandwidth::Zero()));
[email protected]9558c5d32012-12-22 00:08:14201 helper_ = new QuicConnectionHelper(runner_.get(), &clock_,
202 &random_generator_, socket);
[email protected]e13201d82012-12-12 05:00:32203 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_);
[email protected]f702d572012-12-04 15:56:20204 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41205 connection_->SetSendAlgorithm(send_algorithm_);
206 connection_->SetReceiveAlgorithm(receive_algorithm_);
[email protected]ef95114d2013-04-17 17:57:01207 crypto_config_.SetDefaults();
[email protected]18ccfdb2013-08-15 00:13:44208 session_.reset(
209 new QuicClientSession(connection_,
210 scoped_ptr<DatagramClientSocket>(socket), NULL,
211 &crypto_client_stream_factory_,
212 "www.google.com", DefaultQuicConfig(),
213 &crypto_config_, NULL));
[email protected]ed3fc15d2013-03-08 18:37:44214 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48215 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36216 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36217 new AutoClosingStream(session_->GetWeakPtr()) :
218 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36219 }
220
[email protected]24e5bc52013-09-18 15:36:58221 void SetRequestString(const std::string& method,
222 const std::string& path,
223 RequestPriority priority) {
[email protected]9d9e7932013-02-25 18:31:05224 SpdyHeaderBlock headers;
225 headers[":method"] = method;
226 headers[":host"] = "www.google.com";
227 headers[":path"] = path;
228 headers[":scheme"] = "http";
229 headers[":version"] = "HTTP/1.1";
[email protected]24e5bc52013-09-18 15:36:58230 request_data_ = SerializeHeaderBlock(headers, true, priority);
[email protected]6cca996b2013-01-25 07:43:36231 }
232
233 void SetResponseString(const std::string& status, const std::string& body) {
[email protected]9d9e7932013-02-25 18:31:05234 SpdyHeaderBlock headers;
235 headers[":status"] = status;
236 headers[":version"] = "HTTP/1.1";
237 headers["content-type"] = "text/plain";
[email protected]24e5bc52013-09-18 15:36:58238 response_data_ = SerializeHeaderBlock(headers, false, DEFAULT_PRIORITY) +
239 body;
[email protected]6cca996b2013-01-25 07:43:36240 }
241
[email protected]8edeb8d2013-08-28 06:11:43242 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers,
[email protected]24e5bc52013-09-18 15:36:58243 bool write_priority,
244 RequestPriority priority) {
[email protected]821555c2013-05-16 20:20:17245 QuicSpdyCompressor compressor;
[email protected]c67a82cb2013-09-24 02:53:21246 if (write_priority) {
[email protected]24e5bc52013-09-18 15:36:58247 return compressor.CompressHeadersWithPriority(
248 ConvertRequestPriorityToQuicPriority(priority), headers);
[email protected]8edeb8d2013-08-28 06:11:43249 }
[email protected]e4e47462013-08-22 19:37:46250 return compressor.CompressHeaders(headers);
[email protected]6cca996b2013-01-25 07:43:36251 }
[email protected]f702d572012-12-04 15:56:20252
[email protected]06ff5152013-08-29 01:03:05253 // Returns a newly created packet to send kData on stream 3.
[email protected]f702d572012-12-04 15:56:20254 QuicEncryptedPacket* ConstructDataPacket(
255 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05256 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20257 bool fin,
258 QuicStreamOffset offset,
259 base::StringPiece data) {
[email protected]e8ff26842013-03-22 21:02:05260 InitializeHeader(sequence_number, should_include_version);
[email protected]f702d572012-12-04 15:56:20261 QuicStreamFrame frame(3, fin, offset, data);
262 return ConstructPacket(header_, QuicFrame(&frame));
263 }
264
[email protected]06ff5152013-08-29 01:03:05265 // Returns a newly created packet to RST_STREAM stream 3.
266 QuicEncryptedPacket* ConstructRstStreamPacket(
267 QuicPacketSequenceNumber sequence_number) {
268 InitializeHeader(sequence_number, false);
[email protected]24e5bc52013-09-18 15:36:58269 QuicRstStreamFrame frame(3, QUIC_ERROR_PROCESSING_STREAM);
[email protected]06ff5152013-08-29 01:03:05270 return ConstructPacket(header_, QuicFrame(&frame));
271 }
272
[email protected]f702d572012-12-04 15:56:20273 // Returns a newly created packet to send ack data.
274 QuicEncryptedPacket* ConstructAckPacket(
275 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00276 QuicPacketSequenceNumber largest_received,
277 QuicPacketSequenceNumber least_unacked) {
[email protected]e8ff26842013-03-22 21:02:05278 InitializeHeader(sequence_number, false);
[email protected]f702d572012-12-04 15:56:20279
[email protected]14e8106c2013-03-14 16:25:33280 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
[email protected]9db443912013-02-25 05:27:03281 ack.sent_info.entropy_hash = 0;
282 ack.received_info.entropy_hash = 0;
283
[email protected]f702d572012-12-04 15:56:20284 return ConstructPacket(header_, QuicFrame(&ack));
285 }
286
[email protected]63534512012-12-23 18:49:00287 // Returns a newly created packet to send ack data.
288 QuicEncryptedPacket* ConstructRstPacket(
289 QuicPacketSequenceNumber sequence_number,
[email protected]9db443912013-02-25 05:27:03290 QuicStreamId stream_id) {
[email protected]e8ff26842013-03-22 21:02:05291 InitializeHeader(sequence_number, false);
[email protected]63534512012-12-23 18:49:00292
[email protected]74bda142013-03-31 02:49:11293 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
[email protected]63534512012-12-23 18:49:00294 return ConstructPacket(header_, QuicFrame(&rst));
295 }
296
[email protected]f702d572012-12-04 15:56:20297 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00298 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41299 MockSendAlgorithm* send_algorithm_;
300 TestReceiveAlgorithm* receive_algorithm_;
[email protected]f702d572012-12-04 15:56:20301 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17302 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20303 MockClock clock_;
[email protected]9558c5d32012-12-22 00:08:14304 MockRandom random_generator_;
[email protected]f702d572012-12-04 15:56:20305 TestQuicConnection* connection_;
[email protected]e13201d82012-12-12 05:00:32306 QuicConnectionHelper* helper_;
[email protected]f702d572012-12-04 15:56:20307 testing::StrictMock<MockConnectionVisitor> visitor_;
308 scoped_ptr<QuicHttpStream> stream_;
309 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01310 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20311 TestCompletionCallback callback_;
312 HttpRequestInfo request_;
313 HttpRequestHeaders headers_;
314 HttpResponseInfo response_;
315 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]6cca996b2013-01-25 07:43:36316 std::string request_data_;
317 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20318
319 private:
[email protected]e8ff26842013-03-22 21:02:05320 void InitializeHeader(QuicPacketSequenceNumber sequence_number,
321 bool should_include_version) {
[email protected]c995c572013-01-18 05:43:20322 header_.public_header.guid = guid_;
[email protected]9db443912013-02-25 05:27:03323 header_.public_header.reset_flag = false;
[email protected]e8ff26842013-03-22 21:02:05324 header_.public_header.version_flag = should_include_version;
[email protected]ea825e02013-08-21 18:12:45325 header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER;
[email protected]f702d572012-12-04 15:56:20326 header_.packet_sequence_number = sequence_number;
[email protected]f702d572012-12-04 15:56:20327 header_.fec_group = 0;
[email protected]9db443912013-02-25 05:27:03328 header_.entropy_flag = false;
329 header_.fec_flag = false;
[email protected]f702d572012-12-04 15:56:20330 }
331
332 QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header,
333 const QuicFrame& frame) {
334 QuicFrames frames;
335 frames.push_back(frame);
[email protected]610a7e942012-12-18 00:21:39336 scoped_ptr<QuicPacket> packet(
[email protected]3e60db82013-08-05 19:43:06337 framer_.BuildUnsizedDataPacket(header_, frames).packet);
[email protected]8ba81212013-05-03 13:11:48338 return framer_.EncryptPacket(
339 ENCRYPTION_NONE, header.packet_sequence_number, *packet);
[email protected]f702d572012-12-04 15:56:20340 }
341
342 const QuicGuid guid_;
343 QuicFramer framer_;
344 IPEndPoint self_addr_;
345 IPEndPoint peer_addr_;
[email protected]9db443912013-02-25 05:27:03346 MockRandom random_;
[email protected]e8ff26842013-03-22 21:02:05347 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20348 QuicPacketCreator creator_;
349 QuicPacketHeader header_;
[email protected]f702d572012-12-04 15:56:20350 scoped_ptr<StaticSocketDataProvider> socket_data_;
351 std::vector<PacketToWrite> writes_;
352};
353
[email protected]9d9e7932013-02-25 18:31:05354TEST_F(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44355 Initialize();
[email protected]f702d572012-12-04 15:56:20356 EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
357}
358
[email protected]9d9e7932013-02-25 18:31:05359TEST_F(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44360 Initialize();
[email protected]f702d572012-12-04 15:56:20361 EXPECT_TRUE(stream_->CanFindEndOfResponse());
362}
363
[email protected]9d9e7932013-02-25 18:31:05364TEST_F(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44365 Initialize();
[email protected]f702d572012-12-04 15:56:20366 EXPECT_FALSE(stream_->IsConnectionReusable());
367}
368
[email protected]9d9e7932013-02-25 18:31:05369TEST_F(QuicHttpStreamTest, GetRequest) {
[email protected]24e5bc52013-09-18 15:36:58370 SetRequestString("GET", "/", DEFAULT_PRIORITY);
[email protected]e8ff26842013-03-22 21:02:05371 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0,
[email protected]6cca996b2013-01-25 07:43:36372 request_data_));
[email protected]f702d572012-12-04 15:56:20373 Initialize();
374
375 request_.method = "GET";
376 request_.url = GURL("http://www.google.com/");
377
[email protected]262eec82013-03-19 21:01:36378 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
379 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20380 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
381 callback_.callback()));
382 EXPECT_EQ(&response_, stream_->GetResponseInfo());
383
384 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05385 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20386 ProcessPacket(*ack);
387
388 EXPECT_EQ(ERR_IO_PENDING,
389 stream_->ReadResponseHeaders(callback_.callback()));
390
391 // Send the response without a body.
[email protected]007b3f82013-04-09 08:46:45392 SetResponseString("404 Not Found", std::string());
[email protected]f702d572012-12-04 15:56:20393 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05394 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20395 ProcessPacket(*resp);
396
397 // Now that the headers have been processed, the callback will return.
398 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36399 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20400 EXPECT_EQ(404, response_.headers->response_code());
401 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
402
403 // There is no body, so this should return immediately.
404 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
405 read_buffer_->size(),
406 callback_.callback()));
407 EXPECT_TRUE(stream_->IsResponseBodyComplete());
408 EXPECT_TRUE(AtEof());
409}
410
[email protected]3e7dca62013-09-10 16:14:23411// Regression test for http://crbug.com/288128
412TEST_F(QuicHttpStreamTest, GetRequestLargeResponse) {
[email protected]24e5bc52013-09-18 15:36:58413 SetRequestString("GET", "/", DEFAULT_PRIORITY);
[email protected]3e7dca62013-09-10 16:14:23414 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0,
415 request_data_));
416 Initialize();
417
418 request_.method = "GET";
419 request_.url = GURL("http://www.google.com/");
420
421 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
422 net_log_, callback_.callback()));
423 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
424 callback_.callback()));
425 EXPECT_EQ(&response_, stream_->GetResponseInfo());
426
427 // Ack the request.
428 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
429 ProcessPacket(*ack);
430
431 EXPECT_EQ(ERR_IO_PENDING,
432 stream_->ReadResponseHeaders(callback_.callback()));
433
434 SpdyHeaderBlock headers;
435 headers[":status"] = "200 OK";
436 headers[":version"] = "HTTP/1.1";
437 headers["content-type"] = "text/plain";
438 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
439
440 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
441 EXPECT_LT(4096u, response.length());
442 stream_->OnDataReceived(response.data(), response.length());
443 stream_->OnClose(QUIC_NO_ERROR);
444
445 // Now that the headers have been processed, the callback will return.
446 EXPECT_EQ(OK, callback_.WaitForResult());
447 ASSERT_TRUE(response_.headers.get());
448 EXPECT_EQ(200, response_.headers->response_code());
449 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
450
451 // There is no body, so this should return immediately.
452 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
453 read_buffer_->size(),
454 callback_.callback()));
455 EXPECT_TRUE(stream_->IsResponseBodyComplete());
456 EXPECT_TRUE(AtEof());
457}
458
[email protected]9d9e7932013-02-25 18:31:05459TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) {
[email protected]24e5bc52013-09-18 15:36:58460 SetRequestString("GET", "/", DEFAULT_PRIORITY);
[email protected]e8ff26842013-03-22 21:02:05461 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
[email protected]f702d572012-12-04 15:56:20462 Initialize();
463
464 request_.method = "GET";
465 request_.url = GURL("http://www.google.com/");
466
[email protected]262eec82013-03-19 21:01:36467 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
468 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20469 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
470 callback_.callback()));
471 EXPECT_EQ(&response_, stream_->GetResponseInfo());
472
473 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05474 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20475 ProcessPacket(*ack);
476
477 EXPECT_EQ(ERR_IO_PENDING,
478 stream_->ReadResponseHeaders(callback_.callback()));
479
480 // Send the response with a body.
[email protected]6cca996b2013-01-25 07:43:36481 SetResponseString("200 OK", "hello world!");
[email protected]f702d572012-12-04 15:56:20482 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05483 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20484 ProcessPacket(*resp);
485
486 // Now that the headers have been processed, the callback will return.
487 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36488 ASSERT_TRUE(response_.headers.get());
[email protected]6cca996b2013-01-25 07:43:36489 EXPECT_EQ(200, response_.headers->response_code());
[email protected]f702d572012-12-04 15:56:20490 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
491
492 // There is no body, so this should return immediately.
493 // Since the body has already arrived, this should return immediately.
494 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(),
495 read_buffer_->size(),
496 callback_.callback()));
497 EXPECT_TRUE(stream_->IsResponseBodyComplete());
498 EXPECT_TRUE(AtEof());
499}
500
[email protected]9d9e7932013-02-25 18:31:05501TEST_F(QuicHttpStreamTest, SendPostRequest) {
[email protected]24e5bc52013-09-18 15:36:58502 SetRequestString("POST", "/", DEFAULT_PRIORITY);
[email protected]e8ff26842013-03-22 21:02:05503 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
504 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin,
505 request_data_.length(),
[email protected]f702d572012-12-04 15:56:20506 kUploadData));
[email protected]ec640112013-08-09 03:56:18507 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20508
509 Initialize();
510
[email protected]b2d26cfd2012-12-11 10:36:06511 ScopedVector<UploadElementReader> element_readers;
512 element_readers.push_back(
513 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
[email protected]96c77a72013-09-24 09:49:20514 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20515 request_.method = "POST";
516 request_.url = GURL("http://www.google.com/");
517 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24518 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20519
[email protected]262eec82013-03-19 21:01:36520 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
521 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20522 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
523 callback_.callback()));
524 EXPECT_EQ(&response_, stream_->GetResponseInfo());
525
526 // Ack both packets in the request.
[email protected]e8ff26842013-03-22 21:02:05527 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20528 ProcessPacket(*ack);
529
530 // Send the response headers (but not the body).
[email protected]007b3f82013-04-09 08:46:45531 SetResponseString("200 OK", std::string());
[email protected]f702d572012-12-04 15:56:20532 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05533 ConstructDataPacket(2, false, !kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20534 ProcessPacket(*resp);
535
536 // Since the headers have already arrived, this should return immediately.
537 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36538 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20539 EXPECT_EQ(200, response_.headers->response_code());
540 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
541
542 // Send the response body.
543 const char kResponseBody[] = "Hello world!";
544 scoped_ptr<QuicEncryptedPacket> resp_body(
[email protected]e8ff26842013-03-22 21:02:05545 ConstructDataPacket(3, false, kFin, response_data_.length(),
546 kResponseBody));
[email protected]f702d572012-12-04 15:56:20547 ProcessPacket(*resp_body);
548
549 // Since the body has already arrived, this should return immediately.
550 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
551 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
552 callback_.callback()));
553
554 EXPECT_TRUE(stream_->IsResponseBodyComplete());
555 EXPECT_TRUE(AtEof());
556}
557
[email protected]c9e49a02013-02-26 05:56:47558TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) {
[email protected]24e5bc52013-09-18 15:36:58559 SetRequestString("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47560 size_t chunk_size = strlen(kUploadData);
[email protected]e8ff26842013-03-22 21:02:05561 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_));
562 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin,
563 request_data_.length(),
[email protected]c9e49a02013-02-26 05:56:47564 kUploadData));
[email protected]e8ff26842013-03-22 21:02:05565 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin,
[email protected]c9e49a02013-02-26 05:56:47566 request_data_.length() + chunk_size,
567 kUploadData));
[email protected]ec640112013-08-09 03:56:18568 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47569
570 Initialize();
571
572 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
573 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
574
575 request_.method = "POST";
576 request_.url = GURL("http://www.google.com/");
577 request_.upload_data_stream = &upload_data_stream;
578 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
579
[email protected]262eec82013-03-19 21:01:36580 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
581 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47582 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
583 callback_.callback()));
584 EXPECT_EQ(&response_, stream_->GetResponseInfo());
585
586 upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
587
588 // Ack both packets in the request.
[email protected]e8ff26842013-03-22 21:02:05589 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47590 ProcessPacket(*ack);
591
592 // Send the response headers (but not the body).
[email protected]007b3f82013-04-09 08:46:45593 SetResponseString("200 OK", std::string());
[email protected]c9e49a02013-02-26 05:56:47594 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]e8ff26842013-03-22 21:02:05595 ConstructDataPacket(2, false, !kFin, 0, response_data_));
[email protected]c9e49a02013-02-26 05:56:47596 ProcessPacket(*resp);
597
598 // Since the headers have already arrived, this should return immediately.
599 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36600 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47601 EXPECT_EQ(200, response_.headers->response_code());
602 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
603
604 // Send the response body.
605 const char kResponseBody[] = "Hello world!";
606 scoped_ptr<QuicEncryptedPacket> resp_body(
[email protected]e8ff26842013-03-22 21:02:05607 ConstructDataPacket(3, false, kFin, response_data_.length(),
608 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47609 ProcessPacket(*resp_body);
610
611 // Since the body has already arrived, this should return immediately.
612 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
613 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
614 callback_.callback()));
615
616 EXPECT_TRUE(stream_->IsResponseBodyComplete());
617 EXPECT_TRUE(AtEof());
618}
619
[email protected]9d9e7932013-02-25 18:31:05620TEST_F(QuicHttpStreamTest, DestroyedEarly) {
[email protected]24e5bc52013-09-18 15:36:58621 SetRequestString("GET", "/", DEFAULT_PRIORITY);
[email protected]e8ff26842013-03-22 21:02:05622 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
[email protected]06ff5152013-08-29 01:03:05623 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00624 use_closing_stream_ = true;
625 Initialize();
626
627 request_.method = "GET";
628 request_.url = GURL("http://www.google.com/");
629
[email protected]262eec82013-03-19 21:01:36630 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
631 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00632 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58633 callback_.callback()));
[email protected]63534512012-12-23 18:49:00634 EXPECT_EQ(&response_, stream_->GetResponseInfo());
635
636 // Ack the request.
[email protected]e8ff26842013-03-22 21:02:05637 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00638 ProcessPacket(*ack);
639 EXPECT_EQ(ERR_IO_PENDING,
640 stream_->ReadResponseHeaders(callback_.callback()));
641
642 // Send the response with a body.
[email protected]c244c5a12013-05-07 20:55:04643 SetResponseString("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00644 scoped_ptr<QuicEncryptedPacket> resp(
[email protected]c244c5a12013-05-07 20:55:04645 ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]63534512012-12-23 18:49:00646
647 // In the course of processing this packet, the QuicHttpStream close itself.
648 ProcessPacket(*resp);
649
650 EXPECT_TRUE(AtEof());
651}
652
[email protected]24e5bc52013-09-18 15:36:58653TEST_F(QuicHttpStreamTest, Priority) {
654 SetRequestString("GET", "/", MEDIUM);
655 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_));
656 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2));
657 use_closing_stream_ = true;
658 Initialize();
659
660 request_.method = "GET";
661 request_.url = GURL("http://www.google.com/");
662
663 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
664 net_log_, callback_.callback()));
665
666 // Check that priority is highest.
667 QuicReliableClientStream* reliable_stream =
668 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
669 DCHECK(reliable_stream);
670 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority),
671 reliable_stream->EffectivePriority());
672
673 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
674 callback_.callback()));
675 EXPECT_EQ(&response_, stream_->GetResponseInfo());
676
677 // Check that priority has now dropped back to MEDIUM.
678 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
679 reliable_stream->EffectivePriority()));
680
681 // Ack the request.
682 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0));
683 ProcessPacket(*ack);
684 EXPECT_EQ(ERR_IO_PENDING,
685 stream_->ReadResponseHeaders(callback_.callback()));
686
687 // Send the response with a body.
688 SetResponseString("404 OK", "hello world!");
689 scoped_ptr<QuicEncryptedPacket> resp(
690 ConstructDataPacket(2, false, kFin, 0, response_data_));
691
692 // In the course of processing this packet, the QuicHttpStream close itself.
693 ProcessPacket(*resp);
694
695 EXPECT_TRUE(AtEof());
696}
697
[email protected]e1cca9a2013-09-20 17:14:44698// Regression test for http://crbug.com/294870
699TEST_F(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
700 SetRequestString("GET", "/", MEDIUM);
701 use_closing_stream_ = true;
702 Initialize();
703
704 request_.method = "GET";
705 request_.url = GURL("http://www.google.com/");
706
707 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
708 net_log_, callback_.callback()));
709
710 // Check that priority is highest.
711 QuicReliableClientStream* reliable_stream =
712 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
713 DCHECK(reliable_stream);
714 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
715 DCHECK(delegate);
716 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority),
717 reliable_stream->EffectivePriority());
718
719 // Set Delegate to NULL and make sure EffectivePriority returns highest
720 // priority.
721 reliable_stream->SetDelegate(NULL);
722 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority),
723 reliable_stream->EffectivePriority());
724 reliable_stream->SetDelegate(delegate);
725}
726
[email protected]f702d572012-12-04 15:56:20727} // namespace test
728
729} // namespace net