blob: 316f1143fec1efe9cc353b230c9343f0f1142573 [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]17bf15c2014-03-14 10:08:0419#include "net/quic/crypto/quic_server_info.h"
[email protected]f702d572012-12-04 15:56:2020#include "net/quic/quic_client_session.h"
21#include "net/quic/quic_connection.h"
22#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3923#include "net/quic/quic_default_packet_writer.h"
[email protected]24e5bc52013-09-18 15:36:5824#include "net/quic/quic_http_utils.h"
25#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1426#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2327#include "net/quic/spdy_utils.h"
[email protected]f702d572012-12-04 15:56:2028#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0529#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0330#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3931#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2032#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2033#include "net/quic/test_tools/quic_test_utils.h"
34#include "net/quic/test_tools/test_task_runner.h"
35#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3636#include "net/spdy/spdy_frame_builder.h"
37#include "net/spdy/spdy_framer.h"
38#include "net/spdy/spdy_http_utils.h"
39#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2040#include "testing/gmock/include/gmock/gmock.h"
41#include "testing/gtest/include/gtest/gtest.h"
42
43using testing::_;
[email protected]06ff5152013-08-29 01:03:0544using testing::AnyNumber;
45using testing::Return;
[email protected]f702d572012-12-04 15:56:2046
47namespace net {
[email protected]f702d572012-12-04 15:56:2048namespace test {
[email protected]f702d572012-12-04 15:56:2049namespace {
50
51const char kUploadData[] = "hello world!";
52
53class TestQuicConnection : public QuicConnection {
54 public:
[email protected]1e960032013-12-20 19:00:2055 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4356 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2057 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3958 QuicConnectionHelper* helper,
59 QuicPacketWriter* writer)
[email protected]3aa9ca72014-02-27 19:39:4360 : QuicConnection(connection_id, address, helper, writer, false,
61 versions) {
[email protected]f702d572012-12-04 15:56:2062 }
63
[email protected]fee17f72013-02-03 07:47:4164 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
65 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2066 }
[email protected]26f3f8e2012-12-13 21:07:1967
[email protected]fee17f72013-02-03 07:47:4168 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
69 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
[email protected]26f3f8e2012-12-13 21:07:1970 }
71};
72
[email protected]fee17f72013-02-03 07:47:4173class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
[email protected]26f3f8e2012-12-13 21:07:1974 public:
[email protected]1e960032013-12-20 19:00:2075 virtual bool GenerateCongestionFeedback(
76 QuicCongestionFeedbackFrame* /*congestion_feedback*/) {
77 return false;
[email protected]26f3f8e2012-12-13 21:07:1978 }
79
[email protected]6ae6e342014-02-06 02:21:4280 MOCK_METHOD3(RecordIncomingPacket,
81 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
[email protected]f702d572012-12-04 15:56:2082};
83
[email protected]63534512012-12-23 18:49:0084// Subclass of QuicHttpStream that closes itself when the first piece of data
85// is received.
86class AutoClosingStream : public QuicHttpStream {
87 public:
[email protected]0b2294d32013-08-02 00:46:3688 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
89 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0090 }
91
[email protected]46fadfd2013-02-06 09:40:1692 virtual int OnDataReceived(const char* data, int length) OVERRIDE {
[email protected]63534512012-12-23 18:49:0093 Close(false);
94 return OK;
95 }
96};
97
[email protected]f702d572012-12-04 15:56:2098} // namespace
99
[email protected]24e5bc52013-09-18 15:36:58100class QuicHttpStreamPeer {
101 public:
102 static QuicReliableClientStream* GetQuicReliableClientStream(
103 QuicHttpStream* stream) {
104 return stream->stream_;
105 }
106};
107
[email protected]1e960032013-12-20 19:00:20108class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20109 protected:
[email protected]1e960032013-12-20 19:00:20110 static const bool kFin = true;
111 static const bool kIncludeVersion = true;
112 static const bool kIncludeCongestionFeedback = true;
113
[email protected]f702d572012-12-04 15:56:20114 // Holds a packet to be written to the wire, and the IO mode that should
115 // be used by the mock socket when performing the write.
116 struct PacketToWrite {
117 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
118 : mode(mode),
119 packet(packet) {
120 }
121 IoMode mode;
122 QuicEncryptedPacket* packet;
123 };
124
125 QuicHttpStreamTest()
126 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00127 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20128 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43129 connection_id_(2),
[email protected]92bf17c2014-03-03 21:14:03130 stream_id_(5),
[email protected]3aa9ca72014-02-27 19:39:43131 maker_(GetParam(), connection_id_),
[email protected]1e960032013-12-20 19:00:20132 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20133 IPAddressNumber ip;
134 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
135 peer_addr_ = IPEndPoint(ip, 443);
136 self_addr_ = IPEndPoint(ip, 8435);
[email protected]f702d572012-12-04 15:56:20137 }
138
139 ~QuicHttpStreamTest() {
[email protected]4d283b32013-10-17 12:57:27140 session_->CloseSessionOnError(ERR_ABORTED);
[email protected]f702d572012-12-04 15:56:20141 for (size_t i = 0; i < writes_.size(); i++) {
142 delete writes_[i].packet;
143 }
144 }
145
146 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20147 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
148 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20149 }
150
151 // Returns the packet to be written at position |pos|.
152 QuicEncryptedPacket* GetWrite(size_t pos) {
153 return writes_[pos].packet;
154 }
155
156 bool AtEof() {
157 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
158 }
159
[email protected]1e960032013-12-20 19:00:20160 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
161 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20162 }
163
164 // Configures the test fixture to use the list of expected writes.
165 void Initialize() {
166 mock_writes_.reset(new MockWrite[writes_.size()]);
167 for (size_t i = 0; i < writes_.size(); i++) {
168 mock_writes_[i] = MockWrite(writes_[i].mode,
169 writes_[i].packet->data(),
170 writes_[i].packet->length());
171 };
172
173 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
174 writes_.size()));
175
[email protected]e13201d82012-12-12 05:00:32176 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
177 net_log_.net_log());
178 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20179 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41180 send_algorithm_ = new MockSendAlgorithm();
[email protected]1e960032013-12-20 19:00:20181 receive_algorithm_ = new TestReceiveAlgorithm();
[email protected]6ae6e342014-02-06 02:21:42182 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05183 Times(AnyNumber());
[email protected]efecff92013-09-24 07:49:23184 EXPECT_CALL(*send_algorithm_,
[email protected]c0680202013-12-18 04:52:34185 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56186 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05187 Return(QuicTime::Delta::Zero()));
[email protected]575cce62013-08-03 02:06:43188 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
[email protected]06ff5152013-08-29 01:03:05189 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45190 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05191 Return(QuicBandwidth::Zero()));
[email protected]62f90632013-11-01 13:07:11192 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44193 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
194 &random_generator_));
[email protected]cbd731e2013-10-24 00:20:39195 writer_.reset(new QuicDefaultPacketWriter(socket));
[email protected]3aa9ca72014-02-27 19:39:43196 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
197 connection_id_, peer_addr_,
198 helper_.get(), writer_.get());
[email protected]f702d572012-12-04 15:56:20199 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41200 connection_->SetSendAlgorithm(send_algorithm_);
201 connection_->SetReceiveAlgorithm(receive_algorithm_);
[email protected]ef95114d2013-04-17 17:57:01202 crypto_config_.SetDefaults();
[email protected]18ccfdb2013-08-15 00:13:44203 session_.reset(
204 new QuicClientSession(connection_,
[email protected]cbd731e2013-10-24 00:20:39205 scoped_ptr<DatagramClientSocket>(socket),
206 writer_.Pass(), NULL,
[email protected]17bf15c2014-03-14 10:08:04207 make_scoped_ptr((QuicServerInfo*)NULL),
[email protected]18ccfdb2013-08-15 00:13:44208 &crypto_client_stream_factory_,
209 "www.google.com", DefaultQuicConfig(),
210 &crypto_config_, NULL));
[email protected]ed3fc15d2013-03-08 18:37:44211 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48212 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36213 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36214 new AutoClosingStream(session_->GetWeakPtr()) :
215 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36216 }
217
[email protected]1e960032013-12-20 19:00:20218 void SetRequest(const std::string& method,
219 const std::string& path,
220 RequestPriority priority) {
221 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36222 }
223
[email protected]1e960032013-12-20 19:00:20224 void SetResponse(const std::string& status, const std::string& body) {
225 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03226 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36227 }
[email protected]f702d572012-12-04 15:56:20228
[email protected]1e960032013-12-20 19:00:20229 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]f702d572012-12-04 15:56:20230 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05231 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20232 bool fin,
233 QuicStreamOffset offset,
234 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20235 return maker_.MakeDataPacket(
236 sequence_number, stream_id_, should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20237 }
238
[email protected]1e960032013-12-20 19:00:20239 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
240 QuicPacketSequenceNumber sequence_number,
241 bool fin) {
242 return maker_.MakeRequestHeadersPacket(
243 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_);
244 }
245
246 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
247 QuicPacketSequenceNumber sequence_number,
248 bool fin) {
249 return maker_.MakeResponseHeadersPacket(
250 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
251 }
252
253 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
[email protected]06ff5152013-08-29 01:03:05254 QuicPacketSequenceNumber sequence_number) {
[email protected]1e960032013-12-20 19:00:20255 return maker_.MakeRstPacket(
[email protected]459a7402014-02-10 12:58:52256 sequence_number, true, stream_id_, QUIC_STREAM_NO_ERROR);
[email protected]06ff5152013-08-29 01:03:05257 }
258
[email protected]c5e1aca2014-01-30 04:03:04259 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
260 QuicPacketSequenceNumber sequence_number) {
261 return maker_.MakeAckAndRstPacket(
262 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
263 1, 1, !kIncludeCongestionFeedback);
264 }
265
[email protected]1e960032013-12-20 19:00:20266 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
[email protected]f702d572012-12-04 15:56:20267 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00268 QuicPacketSequenceNumber largest_received,
269 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20270 return maker_.MakeAckPacket(sequence_number, largest_received,
271 least_unacked, !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00272 }
273
[email protected]f702d572012-12-04 15:56:20274 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00275 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41276 MockSendAlgorithm* send_algorithm_;
277 TestReceiveAlgorithm* receive_algorithm_;
[email protected]f702d572012-12-04 15:56:20278 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17279 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20280 MockClock clock_;
281 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44282 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20283 testing::StrictMock<MockConnectionVisitor> visitor_;
284 scoped_ptr<QuicHttpStream> stream_;
[email protected]cbd731e2013-10-24 00:20:39285 scoped_ptr<QuicDefaultPacketWriter> writer_;
[email protected]f702d572012-12-04 15:56:20286 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01287 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20288 TestCompletionCallback callback_;
289 HttpRequestInfo request_;
290 HttpRequestHeaders headers_;
291 HttpResponseInfo response_;
292 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20293 SpdyHeaderBlock request_headers_;
294 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36295 std::string request_data_;
296 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20297
298 private:
[email protected]3aa9ca72014-02-27 19:39:43299 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20300 const QuicStreamId stream_id_;
301 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20302 IPEndPoint self_addr_;
303 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58304 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05305 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20306 scoped_ptr<StaticSocketDataProvider> socket_data_;
307 std::vector<PacketToWrite> writes_;
308};
309
[email protected]1e960032013-12-20 19:00:20310INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
311 ::testing::ValuesIn(QuicSupportedVersions()));
312
313TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44314 Initialize();
[email protected]f702d572012-12-04 15:56:20315 EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
316}
317
[email protected]1e960032013-12-20 19:00:20318TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44319 Initialize();
[email protected]f702d572012-12-04 15:56:20320 EXPECT_TRUE(stream_->CanFindEndOfResponse());
321}
322
[email protected]1e960032013-12-20 19:00:20323TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44324 Initialize();
[email protected]f702d572012-12-04 15:56:20325 EXPECT_FALSE(stream_->IsConnectionReusable());
326}
327
[email protected]1e960032013-12-20 19:00:20328TEST_P(QuicHttpStreamTest, GetRequest) {
329 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03330 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]f702d572012-12-04 15:56:20331 Initialize();
332
333 request_.method = "GET";
334 request_.url = GURL("http://www.google.com/");
335
[email protected]262eec82013-03-19 21:01:36336 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
337 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20338 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
339 callback_.callback()));
340 EXPECT_EQ(&response_, stream_->GetResponseInfo());
341
342 // Ack the request.
[email protected]1e960032013-12-20 19:00:20343 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20344
345 EXPECT_EQ(ERR_IO_PENDING,
346 stream_->ReadResponseHeaders(callback_.callback()));
347
[email protected]1e960032013-12-20 19:00:20348 SetResponse("404 Not Found", std::string());
[email protected]92bf17c2014-03-03 21:14:03349 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]f702d572012-12-04 15:56:20350
351 // Now that the headers have been processed, the callback will return.
352 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36353 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20354 EXPECT_EQ(404, response_.headers->response_code());
355 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
356
357 // There is no body, so this should return immediately.
358 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
359 read_buffer_->size(),
360 callback_.callback()));
361 EXPECT_TRUE(stream_->IsResponseBodyComplete());
362 EXPECT_TRUE(AtEof());
363}
364
[email protected]3e7dca62013-09-10 16:14:23365// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20366TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
367 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03368 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]3e7dca62013-09-10 16:14:23369 Initialize();
370
371 request_.method = "GET";
372 request_.url = GURL("http://www.google.com/");
373
374 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
375 net_log_, callback_.callback()));
376 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
377 callback_.callback()));
378 EXPECT_EQ(&response_, stream_->GetResponseInfo());
379
380 // Ack the request.
[email protected]1e960032013-12-20 19:00:20381 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23382
383 EXPECT_EQ(ERR_IO_PENDING,
384 stream_->ReadResponseHeaders(callback_.callback()));
385
386 SpdyHeaderBlock headers;
387 headers[":status"] = "200 OK";
388 headers[":version"] = "HTTP/1.1";
389 headers["content-type"] = "text/plain";
390 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
391
392 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
393 EXPECT_LT(4096u, response.length());
394 stream_->OnDataReceived(response.data(), response.length());
395 stream_->OnClose(QUIC_NO_ERROR);
396
397 // Now that the headers have been processed, the callback will return.
398 EXPECT_EQ(OK, callback_.WaitForResult());
399 ASSERT_TRUE(response_.headers.get());
400 EXPECT_EQ(200, 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]1e960032013-12-20 19:00:20411TEST_P(QuicHttpStreamTest, SendPostRequest) {
412 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03413 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
414 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20415 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20416
417 Initialize();
418
[email protected]b2d26cfd2012-12-11 10:36:06419 ScopedVector<UploadElementReader> element_readers;
420 element_readers.push_back(
421 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
[email protected]96c77a72013-09-24 09:49:20422 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20423 request_.method = "POST";
424 request_.url = GURL("http://www.google.com/");
425 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24426 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20427
[email protected]262eec82013-03-19 21:01:36428 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
429 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20430 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
431 callback_.callback()));
432 EXPECT_EQ(&response_, stream_->GetResponseInfo());
433
434 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20435 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20436
437 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20438 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03439 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20440
441 // Since the headers have already arrived, this should return immediately.
442 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36443 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20444 EXPECT_EQ(200, response_.headers->response_code());
445 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
446
447 // Send the response body.
448 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03449 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20450 // Since the body has already arrived, this should return immediately.
451 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
452 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
453 callback_.callback()));
454
455 EXPECT_TRUE(stream_->IsResponseBodyComplete());
456 EXPECT_TRUE(AtEof());
457}
458
[email protected]1e960032013-12-20 19:00:20459TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
460 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47461 size_t chunk_size = strlen(kUploadData);
[email protected]92bf17c2014-03-03 21:14:03462 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
463 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
464 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
465 kUploadData));
[email protected]1e960032013-12-20 19:00:20466 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47467 Initialize();
468
469 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
470 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
471
472 request_.method = "POST";
473 request_.url = GURL("http://www.google.com/");
474 request_.upload_data_stream = &upload_data_stream;
475 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
476
[email protected]262eec82013-03-19 21:01:36477 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
478 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47479 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
480 callback_.callback()));
481 EXPECT_EQ(&response_, stream_->GetResponseInfo());
482
483 upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
484
485 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20486 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47487
488 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20489 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03490 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47491
492 // Since the headers have already arrived, this should return immediately.
493 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36494 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47495 EXPECT_EQ(200, response_.headers->response_code());
496 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
497
498 // Send the response body.
499 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20500 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
501 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47502
503 // Since the body has already arrived, this should return immediately.
504 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
505 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
506 callback_.callback()));
507
508 EXPECT_TRUE(stream_->IsResponseBodyComplete());
509 EXPECT_TRUE(AtEof());
510}
511
[email protected]1e960032013-12-20 19:00:20512TEST_P(QuicHttpStreamTest, DestroyedEarly) {
513 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03514 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]c5e1aca2014-01-30 04:03:04515 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00516 use_closing_stream_ = true;
517 Initialize();
518
519 request_.method = "GET";
520 request_.url = GURL("http://www.google.com/");
521
[email protected]262eec82013-03-19 21:01:36522 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
523 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00524 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58525 callback_.callback()));
[email protected]63534512012-12-23 18:49:00526 EXPECT_EQ(&response_, stream_->GetResponseInfo());
527
528 // Ack the request.
[email protected]1e960032013-12-20 19:00:20529 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00530 EXPECT_EQ(ERR_IO_PENDING,
531 stream_->ReadResponseHeaders(callback_.callback()));
532
533 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20534 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00535 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03536 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00537
538 EXPECT_TRUE(AtEof());
539}
540
[email protected]1e960032013-12-20 19:00:20541TEST_P(QuicHttpStreamTest, Priority) {
542 SetRequest("GET", "/", MEDIUM);
[email protected]92bf17c2014-03-03 21:14:03543 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]c5e1aca2014-01-30 04:03:04544 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58545 use_closing_stream_ = true;
546 Initialize();
547
548 request_.method = "GET";
549 request_.url = GURL("http://www.google.com/");
550
551 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
552 net_log_, callback_.callback()));
553
554 // Check that priority is highest.
555 QuicReliableClientStream* reliable_stream =
556 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
557 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14558 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58559 reliable_stream->EffectivePriority());
560
561 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
562 callback_.callback()));
563 EXPECT_EQ(&response_, stream_->GetResponseInfo());
564
565 // Check that priority has now dropped back to MEDIUM.
566 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
567 reliable_stream->EffectivePriority()));
568
569 // Ack the request.
[email protected]1e960032013-12-20 19:00:20570 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58571 EXPECT_EQ(ERR_IO_PENDING,
572 stream_->ReadResponseHeaders(callback_.callback()));
573
574 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20575 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58576 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03577 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58578
579 EXPECT_TRUE(AtEof());
580}
581
[email protected]e1cca9a2013-09-20 17:14:44582// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20583TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
584 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44585 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52586
587 if (GetParam() > QUIC_VERSION_13) {
588 AddWrite(ConstructRstStreamPacket(1));
589 }
590
[email protected]e1cca9a2013-09-20 17:14:44591 Initialize();
592
593 request_.method = "GET";
594 request_.url = GURL("http://www.google.com/");
595
596 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
597 net_log_, callback_.callback()));
598
599 // Check that priority is highest.
600 QuicReliableClientStream* reliable_stream =
601 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
602 DCHECK(reliable_stream);
603 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
604 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14605 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44606 reliable_stream->EffectivePriority());
607
608 // Set Delegate to NULL and make sure EffectivePriority returns highest
609 // priority.
610 reliable_stream->SetDelegate(NULL);
[email protected]9f0dcd4e2014-01-16 15:58:14611 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44612 reliable_stream->EffectivePriority());
613 reliable_stream->SetDelegate(delegate);
614}
615
[email protected]f702d572012-12-04 15:56:20616} // namespace test
[email protected]f702d572012-12-04 15:56:20617} // namespace net