1 // Copyright 2013 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.
5 #include "base/basictypes.h"
6 #include "base/compiler_specific.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "net/base/elements_upload_data_stream.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/base/upload_bytes_element_reader.h"
13 #include "net/base/upload_data_stream.h"
14 #include "net/cert/mock_cert_verifier.h"
15 #include "net/dns/mapped_host_resolver.h"
16 #include "net/dns/mock_host_resolver.h"
17 #include "net/http/http_auth_handler_factory.h"
18 #include "net/http/http_network_session.h"
19 #include "net/http/http_network_transaction.h"
20 #include "net/http/http_server_properties_impl.h"
21 #include "net/http/http_transaction_test_util.h"
22 #include "net/http/transport_security_state.h"
23 #include "net/proxy/proxy_service.h"
24 #include "net/quic/test_tools/quic_test_utils.h"
25 #include "net/ssl/ssl_config_service_defaults.h"
26 #include "net/tools/quic/quic_in_memory_cache.h"
27 #include "net/tools/quic/quic_server.h"
28 #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
29 #include "net/tools/quic/test_tools/server_thread.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "testing/platform_test.h"
33 using base::StringPiece
;
34 using net::tools::QuicInMemoryCache
;
35 using net::tools::QuicServer
;
36 using net::tools::test::QuicInMemoryCachePeer
;
37 using net::tools::test::ServerThread
;
44 const char kResponseBody
[] = "some arbitrary response body";
46 // Factory for creating HttpTransactions, used by TestTransactionConsumer.
47 class TestTransactionFactory
: public HttpTransactionFactory
{
49 TestTransactionFactory(const HttpNetworkSession::Params
& params
)
50 : session_(new HttpNetworkSession(params
)) {}
52 ~TestTransactionFactory() override
{}
54 // HttpTransactionFactory methods
55 int CreateTransaction(RequestPriority priority
,
56 scoped_ptr
<HttpTransaction
>* trans
) override
{
57 trans
->reset(new HttpNetworkTransaction(priority
, session_
.get()));
61 HttpCache
* GetCache() override
{ return nullptr; }
63 HttpNetworkSession
* GetSession() override
{ return session_
.get(); };
66 scoped_refptr
<HttpNetworkSession
> session_
;
71 class QuicEndToEndTest
: public PlatformTest
{
74 : host_resolver_impl_(CreateResolverImpl()),
75 host_resolver_(host_resolver_impl_
.Pass()),
76 ssl_config_service_(new SSLConfigServiceDefaults
),
77 proxy_service_(ProxyService::CreateDirect()),
78 auth_handler_factory_(
79 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
80 strike_register_no_startup_period_(false) {
81 request_
.method
= "GET";
82 request_
.url
= GURL("http://www.google.com/");
83 request_
.load_flags
= 0;
85 params_
.enable_quic
= true;
86 params_
.quic_clock
= nullptr;
87 params_
.quic_random
= nullptr;
88 params_
.host_resolver
= &host_resolver_
;
89 params_
.cert_verifier
= &cert_verifier_
;
90 params_
.transport_security_state
= &transport_security_state_
;
91 params_
.proxy_service
= proxy_service_
.get();
92 params_
.ssl_config_service
= ssl_config_service_
.get();
93 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
94 params_
.http_server_properties
= http_server_properties
.GetWeakPtr();
97 // Creates a mock host resolver in which www.google.com
98 // resolves to localhost.
99 static MockHostResolver
* CreateResolverImpl() {
100 MockHostResolver
* resolver
= new MockHostResolver();
101 resolver
->rules()->AddRule("www.google.com", "127.0.0.1");
105 void SetUp() override
{
106 QuicInMemoryCachePeer::ResetForTests();
109 // Use a mapped host resolver so that request for www.google.com (port 80)
110 // reach the server running on localhost.
111 std::string map_rule
= "MAP www.google.com www.google.com:" +
112 base::IntToString(server_thread_
->GetPort());
113 EXPECT_TRUE(host_resolver_
.AddRuleFromString(map_rule
));
115 // To simplify the test, and avoid the race with the HTTP request, we force
116 // QUIC for these requests.
117 params_
.origin_to_force_quic_on
=
118 HostPortPair::FromString("www.google.com:80");
120 transaction_factory_
.reset(new TestTransactionFactory(params_
));
123 void TearDown() override
{
125 QuicInMemoryCachePeer::ResetForTests();
128 // Starts the QUIC server listening on a random port.
130 net::IPAddressNumber ip
;
131 CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip
));
132 server_address_
= IPEndPoint(ip
, 0);
133 server_config_
.SetInitialFlowControlWindowToSend(
134 kInitialSessionFlowControlWindowForTest
);
135 server_config_
.SetInitialStreamFlowControlWindowToSend(
136 kInitialStreamFlowControlWindowForTest
);
137 server_config_
.SetInitialSessionFlowControlWindowToSend(
138 kInitialSessionFlowControlWindowForTest
);
139 server_thread_
.reset(new ServerThread(
140 new QuicServer(server_config_
, QuicSupportedVersions()),
142 strike_register_no_startup_period_
));
143 server_thread_
->Initialize();
144 server_address_
= IPEndPoint(server_address_
.address(),
145 server_thread_
->GetPort());
146 server_thread_
->Start();
147 server_started_
= true;
150 // Stops the QUIC server.
152 if (!server_started_
) {
155 if (server_thread_
.get()) {
156 server_thread_
->Quit();
157 server_thread_
->Join();
161 // Adds an entry to the cache used by the QUIC server to serve
163 void AddToCache(const StringPiece
& method
,
164 const StringPiece
& path
,
165 const StringPiece
& version
,
166 const StringPiece
& response_code
,
167 const StringPiece
& response_detail
,
168 const StringPiece
& body
) {
169 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
170 method
, path
, version
, response_code
, response_detail
, body
);
173 // Populates |request_body_| with |length_| ASCII bytes.
174 void GenerateBody(size_t length
) {
175 request_body_
.clear();
176 request_body_
.reserve(length
);
177 for (size_t i
= 0; i
< length
; ++i
) {
178 request_body_
.append(1, static_cast<char>(32 + i
% (126 - 32)));
182 // Initializes |request_| for a post of |length| bytes.
183 void InitializePostRequest(size_t length
) {
184 GenerateBody(length
);
185 ScopedVector
<UploadElementReader
> element_readers
;
186 element_readers
.push_back(
187 new UploadBytesElementReader(request_body_
.data(),
188 request_body_
.length()));
189 upload_data_stream_
.reset(
190 new ElementsUploadDataStream(element_readers
.Pass(), 0));
191 request_
.method
= "POST";
192 request_
.url
= GURL("http://www.google.com/");
193 request_
.upload_data_stream
= upload_data_stream_
.get();
194 ASSERT_EQ(OK
, request_
.upload_data_stream
->Init(CompletionCallback()));
197 // Checks that |consumer| completed and received |status_line| and |body|.
198 void CheckResponse(const TestTransactionConsumer
& consumer
,
199 const std::string
& status_line
,
200 const std::string
& body
) {
201 ASSERT_TRUE(consumer
.is_done());
202 EXPECT_EQ(OK
, consumer
.error());
203 EXPECT_EQ(status_line
,
204 consumer
.response_info()->headers
->GetStatusLine());
205 EXPECT_EQ(body
, consumer
.content());
208 scoped_ptr
<MockHostResolver
> host_resolver_impl_
;
209 MappedHostResolver host_resolver_
;
210 MockCertVerifier cert_verifier_
;
211 TransportSecurityState transport_security_state_
;
212 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
213 scoped_ptr
<ProxyService
> proxy_service_
;
214 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
215 HttpServerPropertiesImpl http_server_properties
;
216 HttpNetworkSession::Params params_
;
217 scoped_ptr
<TestTransactionFactory
> transaction_factory_
;
218 HttpRequestInfo request_
;
219 std::string request_body_
;
220 scoped_ptr
<UploadDataStream
> upload_data_stream_
;
221 scoped_ptr
<ServerThread
> server_thread_
;
222 IPEndPoint server_address_
;
223 std::string server_hostname_
;
224 QuicConfig server_config_
;
225 bool server_started_
;
226 bool strike_register_no_startup_period_
;
229 TEST_F(QuicEndToEndTest
, LargeGetWithNoPacketLoss
) {
230 std::string
response(10 * 1024, 'x');
232 AddToCache("GET", request_
.url
.spec(),
233 "HTTP/1.1", "200", "OK",
236 TestTransactionConsumer
consumer(DEFAULT_PRIORITY
,
237 transaction_factory_
.get());
238 consumer
.Start(&request_
, BoundNetLog());
240 // Will terminate when the last consumer completes.
241 base::MessageLoop::current()->Run();
243 CheckResponse(consumer
, "HTTP/1.1 200 OK", response
);
246 // http://crbug.com/307284
247 TEST_F(QuicEndToEndTest
, DISABLED_LargePostWithNoPacketLoss
) {
248 InitializePostRequest(10 * 1024 * 1024);
250 AddToCache("POST", request_
.url
.spec(),
251 "HTTP/1.1", "200", "OK",
254 TestTransactionConsumer
consumer(DEFAULT_PRIORITY
,
255 transaction_factory_
.get());
256 consumer
.Start(&request_
, BoundNetLog());
258 // Will terminate when the last consumer completes.
259 base::MessageLoop::current()->Run();
261 CheckResponse(consumer
, "HTTP/1.1 200 OK", kResponseBody
);
264 TEST_F(QuicEndToEndTest
, LargePostWithPacketLoss
) {
265 // FLAGS_fake_packet_loss_percentage = 30;
266 InitializePostRequest(1024 * 1024);
268 const char kResponseBody
[] = "some really big response body";
269 AddToCache("POST", request_
.url
.spec(),
270 "HTTP/1.1", "200", "OK",
273 TestTransactionConsumer
consumer(DEFAULT_PRIORITY
,
274 transaction_factory_
.get());
275 consumer
.Start(&request_
, BoundNetLog());
277 // Will terminate when the last consumer completes.
278 base::MessageLoop::current()->Run();
280 CheckResponse(consumer
, "HTTP/1.1 200 OK", kResponseBody
);
283 TEST_F(QuicEndToEndTest
, UberTest
) {
284 // FLAGS_fake_packet_loss_percentage = 30;
286 const char kResponseBody
[] = "some really big response body";
287 AddToCache("GET", request_
.url
.spec(),
288 "HTTP/1.1", "200", "OK",
291 std::vector
<TestTransactionConsumer
*> consumers
;
292 size_t num_requests
= 100;
293 for (size_t i
= 0; i
< num_requests
; ++i
) {
294 TestTransactionConsumer
* consumer
=
295 new TestTransactionConsumer(DEFAULT_PRIORITY
,
296 transaction_factory_
.get());
297 consumers
.push_back(consumer
);
298 consumer
->Start(&request_
, BoundNetLog());
301 // Will terminate when the last consumer completes.
302 base::MessageLoop::current()->Run();
304 for (size_t i
= 0; i
< num_requests
; ++i
) {
305 CheckResponse(*consumers
[i
], "HTTP/1.1 200 OK", kResponseBody
);
307 STLDeleteElements(&consumers
);