1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/url_request/url_request_test_util.h"
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/threading/thread.h"
11 #include "base/threading/worker_pool.h"
12 #include "net/base/host_port_pair.h"
13 #include "net/cert/cert_verifier.h"
14 #include "net/dns/mock_host_resolver.h"
15 #include "net/http/http_network_session.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/http/http_server_properties_impl.h"
18 #include "net/http/transport_security_state.h"
19 #include "net/ssl/default_server_bound_cert_store.h"
20 #include "net/ssl/server_bound_cert_service.h"
21 #include "net/url_request/static_http_user_agent_settings.h"
22 #include "net/url_request/url_request_job_factory_impl.h"
23 #include "testing/gtest/include/gtest/gtest.h"
29 // These constants put the NetworkDelegate events of TestNetworkDelegate
30 // into an order. They are used in conjunction with
31 // |TestNetworkDelegate::next_states_| to check that we do not send
32 // events in the wrong order.
33 const int kStageBeforeURLRequest
= 1 << 0;
34 const int kStageBeforeSendHeaders
= 1 << 1;
35 const int kStageSendHeaders
= 1 << 2;
36 const int kStageHeadersReceived
= 1 << 3;
37 const int kStageAuthRequired
= 1 << 4;
38 const int kStageBeforeRedirect
= 1 << 5;
39 const int kStageResponseStarted
= 1 << 6;
40 const int kStageCompletedSuccess
= 1 << 7;
41 const int kStageCompletedError
= 1 << 8;
42 const int kStageURLRequestDestroyed
= 1 << 9;
43 const int kStageDestruction
= 1 << 10;
47 TestURLRequestContext::TestURLRequestContext()
48 : initialized_(false),
49 client_socket_factory_(NULL
),
50 context_storage_(this) {
54 TestURLRequestContext::TestURLRequestContext(bool delay_initialization
)
55 : initialized_(false),
56 client_socket_factory_(NULL
),
57 context_storage_(this) {
58 if (!delay_initialization
)
62 TestURLRequestContext::~TestURLRequestContext() {
66 void TestURLRequestContext::Init() {
67 DCHECK(!initialized_
);
71 context_storage_
.set_host_resolver(
72 scoped_ptr
<HostResolver
>(new MockCachingHostResolver()));
74 context_storage_
.set_proxy_service(ProxyService::CreateDirect());
76 context_storage_
.set_cert_verifier(CertVerifier::CreateDefault());
77 if (!transport_security_state())
78 context_storage_
.set_transport_security_state(new TransportSecurityState
);
79 if (!ssl_config_service())
80 context_storage_
.set_ssl_config_service(new SSLConfigServiceDefaults
);
81 if (!http_auth_handler_factory()) {
82 context_storage_
.set_http_auth_handler_factory(
83 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
85 if (!http_server_properties()) {
86 context_storage_
.set_http_server_properties(
87 scoped_ptr
<HttpServerProperties
>(new HttpServerPropertiesImpl()));
89 if (!transport_security_state()) {
90 context_storage_
.set_transport_security_state(
91 new TransportSecurityState());
93 if (http_transaction_factory()) {
94 // Make sure we haven't been passed an object we're not going to use.
95 EXPECT_FALSE(client_socket_factory_
);
97 HttpNetworkSession::Params params
;
98 params
.client_socket_factory
= client_socket_factory();
99 params
.host_resolver
= host_resolver();
100 params
.cert_verifier
= cert_verifier();
101 params
.transport_security_state
= transport_security_state();
102 params
.proxy_service
= proxy_service();
103 params
.ssl_config_service
= ssl_config_service();
104 params
.http_auth_handler_factory
= http_auth_handler_factory();
105 params
.network_delegate
= network_delegate();
106 params
.http_server_properties
= http_server_properties();
107 params
.net_log
= net_log();
108 context_storage_
.set_http_transaction_factory(new HttpCache(
109 new HttpNetworkSession(params
),
110 HttpCache::DefaultBackend::InMemory(0)));
112 // In-memory cookie store.
114 context_storage_
.set_cookie_store(new CookieMonster(NULL
, NULL
));
115 // In-memory origin bound cert service.
116 if (!server_bound_cert_service()) {
117 context_storage_
.set_server_bound_cert_service(
118 new ServerBoundCertService(
119 new DefaultServerBoundCertStore(NULL
),
120 base::WorkerPool::GetTaskRunner(true)));
122 if (!http_user_agent_settings()) {
123 context_storage_
.set_http_user_agent_settings(
124 new StaticHttpUserAgentSettings("en-us,fr", std::string()));
127 context_storage_
.set_job_factory(new URLRequestJobFactoryImpl
);
130 TestURLRequest::TestURLRequest(const GURL
& url
,
131 RequestPriority priority
,
133 TestURLRequestContext
* context
)
134 : URLRequest(url
, priority
, delegate
, context
) {}
136 TestURLRequest::~TestURLRequest() {
139 TestURLRequestContextGetter::TestURLRequestContextGetter(
140 const scoped_refptr
<base::SingleThreadTaskRunner
>& network_task_runner
)
141 : network_task_runner_(network_task_runner
) {
142 DCHECK(network_task_runner_
.get());
145 TestURLRequestContextGetter::TestURLRequestContextGetter(
146 const scoped_refptr
<base::SingleThreadTaskRunner
>& network_task_runner
,
147 scoped_ptr
<TestURLRequestContext
> context
)
148 : network_task_runner_(network_task_runner
), context_(context
.Pass()) {
149 DCHECK(network_task_runner_
.get());
152 TestURLRequestContextGetter::~TestURLRequestContextGetter() {}
154 TestURLRequestContext
* TestURLRequestContextGetter::GetURLRequestContext() {
156 context_
.reset(new TestURLRequestContext
);
157 return context_
.get();
160 scoped_refptr
<base::SingleThreadTaskRunner
>
161 TestURLRequestContextGetter::GetNetworkTaskRunner() const {
162 return network_task_runner_
;
165 TestDelegate::TestDelegate()
166 : cancel_in_rr_(false),
167 cancel_in_rs_(false),
168 cancel_in_rd_(false),
169 cancel_in_rd_pending_(false),
170 quit_on_complete_(true),
171 quit_on_redirect_(false),
172 quit_on_before_network_start_(false),
173 allow_certificate_errors_(false),
174 response_started_count_(0),
175 received_bytes_count_(0),
176 received_redirect_count_(0),
177 received_before_network_start_count_(0),
178 received_data_before_response_(false),
179 request_failed_(false),
180 have_certificate_errors_(false),
181 certificate_errors_are_fatal_(false),
182 auth_required_(false),
183 have_full_request_headers_(false),
184 buf_(new IOBuffer(kBufferSize
)) {
187 TestDelegate::~TestDelegate() {}
189 void TestDelegate::ClearFullRequestHeaders() {
190 full_request_headers_
.Clear();
191 have_full_request_headers_
= false;
194 void TestDelegate::OnReceivedRedirect(URLRequest
* request
,
196 bool* defer_redirect
) {
197 EXPECT_TRUE(request
->is_redirecting());
199 have_full_request_headers_
=
200 request
->GetFullRequestHeaders(&full_request_headers_
);
202 received_redirect_count_
++;
203 if (quit_on_redirect_
) {
204 *defer_redirect
= true;
205 base::MessageLoop::current()->PostTask(FROM_HERE
,
206 base::MessageLoop::QuitClosure());
207 } else if (cancel_in_rr_
) {
212 void TestDelegate::OnBeforeNetworkStart(URLRequest
* request
, bool* defer
) {
213 received_before_network_start_count_
++;
214 if (quit_on_before_network_start_
) {
216 base::MessageLoop::current()->PostTask(FROM_HERE
,
217 base::MessageLoop::QuitClosure());
221 void TestDelegate::OnAuthRequired(URLRequest
* request
,
222 AuthChallengeInfo
* auth_info
) {
223 auth_required_
= true;
224 if (!credentials_
.Empty()) {
225 request
->SetAuth(credentials_
);
227 request
->CancelAuth();
231 void TestDelegate::OnSSLCertificateError(URLRequest
* request
,
232 const SSLInfo
& ssl_info
,
234 // The caller can control whether it needs all SSL requests to go through,
235 // independent of any possible errors, or whether it wants SSL errors to
236 // cancel the request.
237 have_certificate_errors_
= true;
238 certificate_errors_are_fatal_
= fatal
;
239 if (allow_certificate_errors_
)
240 request
->ContinueDespiteLastError();
245 void TestDelegate::OnResponseStarted(URLRequest
* request
) {
246 // It doesn't make sense for the request to have IO pending at this point.
247 DCHECK(!request
->status().is_io_pending());
248 EXPECT_FALSE(request
->is_redirecting());
250 have_full_request_headers_
=
251 request
->GetFullRequestHeaders(&full_request_headers_
);
253 response_started_count_
++;
256 OnResponseCompleted(request
);
257 } else if (!request
->status().is_success()) {
258 DCHECK(request
->status().status() == URLRequestStatus::FAILED
||
259 request
->status().status() == URLRequestStatus::CANCELED
);
260 request_failed_
= true;
261 OnResponseCompleted(request
);
263 // Initiate the first read.
265 if (request
->Read(buf_
.get(), kBufferSize
, &bytes_read
))
266 OnReadCompleted(request
, bytes_read
);
267 else if (!request
->status().is_io_pending())
268 OnResponseCompleted(request
);
272 void TestDelegate::OnReadCompleted(URLRequest
* request
, int bytes_read
) {
273 // It doesn't make sense for the request to have IO pending at this point.
274 DCHECK(!request
->status().is_io_pending());
276 if (response_started_count_
== 0)
277 received_data_before_response_
= true;
282 if (bytes_read
>= 0) {
283 // There is data to read.
284 received_bytes_count_
+= bytes_read
;
287 data_received_
.append(buf_
->data(), bytes_read
);
290 // If it was not end of stream, request to read more.
291 if (request
->status().is_success() && bytes_read
> 0) {
293 while (request
->Read(buf_
.get(), kBufferSize
, &bytes_read
)) {
294 if (bytes_read
> 0) {
295 data_received_
.append(buf_
->data(), bytes_read
);
296 received_bytes_count_
+= bytes_read
;
302 if (!request
->status().is_io_pending())
303 OnResponseCompleted(request
);
304 else if (cancel_in_rd_pending_
)
308 void TestDelegate::OnResponseCompleted(URLRequest
* request
) {
309 if (quit_on_complete_
)
310 base::MessageLoop::current()->PostTask(FROM_HERE
,
311 base::MessageLoop::QuitClosure());
314 TestNetworkDelegate::TestNetworkDelegate()
317 created_requests_(0),
318 destroyed_requests_(0),
319 completed_requests_(0),
320 canceled_requests_(0),
321 cookie_options_bit_mask_(0),
322 blocked_get_cookies_count_(0),
323 blocked_set_cookie_count_(0),
324 set_cookie_count_(0),
325 has_load_timing_info_before_redirect_(false),
326 has_load_timing_info_before_auth_(false),
327 can_access_files_(true),
328 can_throttle_requests_(true) {
331 TestNetworkDelegate::~TestNetworkDelegate() {
332 for (std::map
<int, int>::iterator i
= next_states_
.begin();
333 i
!= next_states_
.end(); ++i
) {
334 event_order_
[i
->first
] += "~TestNetworkDelegate\n";
335 EXPECT_TRUE(i
->second
& kStageDestruction
) << event_order_
[i
->first
];
339 bool TestNetworkDelegate::GetLoadTimingInfoBeforeRedirect(
340 LoadTimingInfo
* load_timing_info_before_redirect
) const {
341 *load_timing_info_before_redirect
= load_timing_info_before_redirect_
;
342 return has_load_timing_info_before_redirect_
;
345 bool TestNetworkDelegate::GetLoadTimingInfoBeforeAuth(
346 LoadTimingInfo
* load_timing_info_before_auth
) const {
347 *load_timing_info_before_auth
= load_timing_info_before_auth_
;
348 return has_load_timing_info_before_auth_
;
351 void TestNetworkDelegate::InitRequestStatesIfNew(int request_id
) {
352 if (next_states_
.find(request_id
) == next_states_
.end()) {
353 // TODO(davidben): Although the URLRequest documentation does not allow
354 // calling Cancel() before Start(), the ResourceLoader does so. URLRequest's
355 // destructor also calls Cancel. Either officially support this or fix the
356 // ResourceLoader code.
357 next_states_
[request_id
] = kStageBeforeURLRequest
| kStageCompletedError
;
358 event_order_
[request_id
] = "";
362 int TestNetworkDelegate::OnBeforeURLRequest(
364 const CompletionCallback
& callback
,
366 int req_id
= request
->identifier();
367 InitRequestStatesIfNew(req_id
);
368 event_order_
[req_id
] += "OnBeforeURLRequest\n";
369 EXPECT_TRUE(next_states_
[req_id
] & kStageBeforeURLRequest
) <<
370 event_order_
[req_id
];
371 next_states_
[req_id
] =
372 kStageBeforeSendHeaders
|
373 kStageResponseStarted
| // data: URLs do not trigger sending headers
374 kStageBeforeRedirect
| // a delegate can trigger a redirection
375 kStageCompletedError
| // request canceled by delegate
376 kStageAuthRequired
; // Auth can come next for FTP requests
381 int TestNetworkDelegate::OnBeforeSendHeaders(
383 const CompletionCallback
& callback
,
384 HttpRequestHeaders
* headers
) {
385 int req_id
= request
->identifier();
386 InitRequestStatesIfNew(req_id
);
387 event_order_
[req_id
] += "OnBeforeSendHeaders\n";
388 EXPECT_TRUE(next_states_
[req_id
] & kStageBeforeSendHeaders
) <<
389 event_order_
[req_id
];
390 next_states_
[req_id
] =
392 kStageCompletedError
; // request canceled by delegate
397 void TestNetworkDelegate::OnSendHeaders(
399 const HttpRequestHeaders
& headers
) {
400 int req_id
= request
->identifier();
401 InitRequestStatesIfNew(req_id
);
402 event_order_
[req_id
] += "OnSendHeaders\n";
403 EXPECT_TRUE(next_states_
[req_id
] & kStageSendHeaders
) <<
404 event_order_
[req_id
];
405 next_states_
[req_id
] =
406 kStageHeadersReceived
|
407 kStageCompletedError
;
410 int TestNetworkDelegate::OnHeadersReceived(
412 const CompletionCallback
& callback
,
413 const HttpResponseHeaders
* original_response_headers
,
414 scoped_refptr
<HttpResponseHeaders
>* override_response_headers
,
415 GURL
* allowed_unsafe_redirect_url
) {
416 int req_id
= request
->identifier();
417 event_order_
[req_id
] += "OnHeadersReceived\n";
418 InitRequestStatesIfNew(req_id
);
419 EXPECT_TRUE(next_states_
[req_id
] & kStageHeadersReceived
) <<
420 event_order_
[req_id
];
421 next_states_
[req_id
] =
422 kStageBeforeRedirect
|
423 kStageResponseStarted
|
425 kStageCompletedError
; // e.g. proxy resolution problem
427 // Basic authentication sends a second request from the URLRequestHttpJob
428 // layer before the URLRequest reports that a response has started.
429 next_states_
[req_id
] |= kStageBeforeSendHeaders
;
431 if (!redirect_on_headers_received_url_
.is_empty()) {
432 *override_response_headers
=
433 new net::HttpResponseHeaders(original_response_headers
->raw_headers());
434 (*override_response_headers
)->ReplaceStatusLine("HTTP/1.1 302 Found");
435 (*override_response_headers
)->RemoveHeader("Location");
436 (*override_response_headers
)->AddHeader(
437 "Location: " + redirect_on_headers_received_url_
.spec());
439 redirect_on_headers_received_url_
= GURL();
441 if (!allowed_unsafe_redirect_url_
.is_empty())
442 *allowed_unsafe_redirect_url
= allowed_unsafe_redirect_url_
;
448 void TestNetworkDelegate::OnBeforeRedirect(URLRequest
* request
,
449 const GURL
& new_location
) {
450 load_timing_info_before_redirect_
= LoadTimingInfo();
451 request
->GetLoadTimingInfo(&load_timing_info_before_redirect_
);
452 has_load_timing_info_before_redirect_
= true;
453 EXPECT_FALSE(load_timing_info_before_redirect_
.request_start_time
.is_null());
454 EXPECT_FALSE(load_timing_info_before_redirect_
.request_start
.is_null());
456 int req_id
= request
->identifier();
457 InitRequestStatesIfNew(req_id
);
458 event_order_
[req_id
] += "OnBeforeRedirect\n";
459 EXPECT_TRUE(next_states_
[req_id
] & kStageBeforeRedirect
) <<
460 event_order_
[req_id
];
461 next_states_
[req_id
] =
462 kStageBeforeURLRequest
| // HTTP redirects trigger this.
463 kStageBeforeSendHeaders
| // Redirects from the network delegate do not
464 // trigger onBeforeURLRequest.
465 kStageCompletedError
;
467 // A redirect can lead to a file or a data URL. In this case, we do not send
469 next_states_
[req_id
] |= kStageResponseStarted
;
472 void TestNetworkDelegate::OnResponseStarted(URLRequest
* request
) {
473 LoadTimingInfo load_timing_info
;
474 request
->GetLoadTimingInfo(&load_timing_info
);
475 EXPECT_FALSE(load_timing_info
.request_start_time
.is_null());
476 EXPECT_FALSE(load_timing_info
.request_start
.is_null());
478 int req_id
= request
->identifier();
479 InitRequestStatesIfNew(req_id
);
480 event_order_
[req_id
] += "OnResponseStarted\n";
481 EXPECT_TRUE(next_states_
[req_id
] & kStageResponseStarted
) <<
482 event_order_
[req_id
];
483 next_states_
[req_id
] = kStageCompletedSuccess
| kStageCompletedError
;
484 if (request
->status().status() == URLRequestStatus::FAILED
) {
486 last_error_
= request
->status().error();
490 void TestNetworkDelegate::OnRawBytesRead(const URLRequest
& request
,
494 void TestNetworkDelegate::OnCompleted(URLRequest
* request
, bool started
) {
495 int req_id
= request
->identifier();
496 InitRequestStatesIfNew(req_id
);
497 event_order_
[req_id
] += "OnCompleted\n";
498 // Expect "Success -> (next_states_ & kStageCompletedSuccess)"
499 // is logically identical to
500 // Expect "!(Success) || (next_states_ & kStageCompletedSuccess)"
501 EXPECT_TRUE(!request
->status().is_success() ||
502 (next_states_
[req_id
] & kStageCompletedSuccess
)) <<
503 event_order_
[req_id
];
504 EXPECT_TRUE(request
->status().is_success() ||
505 (next_states_
[req_id
] & kStageCompletedError
)) <<
506 event_order_
[req_id
];
507 next_states_
[req_id
] = kStageURLRequestDestroyed
;
508 completed_requests_
++;
509 if (request
->status().status() == URLRequestStatus::FAILED
) {
511 last_error_
= request
->status().error();
512 } else if (request
->status().status() == URLRequestStatus::CANCELED
) {
513 canceled_requests_
++;
515 DCHECK_EQ(URLRequestStatus::SUCCESS
, request
->status().status());
519 void TestNetworkDelegate::OnURLRequestDestroyed(URLRequest
* request
) {
520 int req_id
= request
->identifier();
521 InitRequestStatesIfNew(req_id
);
522 event_order_
[req_id
] += "OnURLRequestDestroyed\n";
523 EXPECT_TRUE(next_states_
[req_id
] & kStageURLRequestDestroyed
) <<
524 event_order_
[req_id
];
525 next_states_
[req_id
] = kStageDestruction
;
526 destroyed_requests_
++;
529 void TestNetworkDelegate::OnPACScriptError(int line_number
,
530 const base::string16
& error
) {
533 NetworkDelegate::AuthRequiredResponse
TestNetworkDelegate::OnAuthRequired(
535 const AuthChallengeInfo
& auth_info
,
536 const AuthCallback
& callback
,
537 AuthCredentials
* credentials
) {
538 load_timing_info_before_auth_
= LoadTimingInfo();
539 request
->GetLoadTimingInfo(&load_timing_info_before_auth_
);
540 has_load_timing_info_before_auth_
= true;
541 EXPECT_FALSE(load_timing_info_before_auth_
.request_start_time
.is_null());
542 EXPECT_FALSE(load_timing_info_before_auth_
.request_start
.is_null());
544 int req_id
= request
->identifier();
545 InitRequestStatesIfNew(req_id
);
546 event_order_
[req_id
] += "OnAuthRequired\n";
547 EXPECT_TRUE(next_states_
[req_id
] & kStageAuthRequired
) <<
548 event_order_
[req_id
];
549 next_states_
[req_id
] = kStageBeforeSendHeaders
|
550 kStageAuthRequired
| // For example, proxy auth followed by server auth.
551 kStageHeadersReceived
| // Request canceled by delegate simulates empty
553 kStageResponseStarted
| // data: URLs do not trigger sending headers
554 kStageBeforeRedirect
| // a delegate can trigger a redirection
555 kStageCompletedError
; // request cancelled before callback
556 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION
;
559 bool TestNetworkDelegate::OnCanGetCookies(const URLRequest
& request
,
560 const CookieList
& cookie_list
) {
562 if (cookie_options_bit_mask_
& NO_GET_COOKIES
)
566 blocked_get_cookies_count_
++;
572 bool TestNetworkDelegate::OnCanSetCookie(const URLRequest
& request
,
573 const std::string
& cookie_line
,
574 CookieOptions
* options
) {
576 if (cookie_options_bit_mask_
& NO_SET_COOKIE
)
580 blocked_set_cookie_count_
++;
588 bool TestNetworkDelegate::OnCanAccessFile(const URLRequest
& request
,
589 const base::FilePath
& path
) const {
590 return can_access_files_
;
593 bool TestNetworkDelegate::OnCanThrottleRequest(
594 const URLRequest
& request
) const {
595 return can_throttle_requests_
;
598 int TestNetworkDelegate::OnBeforeSocketStreamConnect(
599 SocketStream
* socket
,
600 const CompletionCallback
& callback
) {
605 std::string
ScopedCustomUrlRequestTestHttpHost::value_("127.0.0.1");
607 ScopedCustomUrlRequestTestHttpHost::ScopedCustomUrlRequestTestHttpHost(
608 const std::string
& new_value
)
609 : old_value_(value_
),
610 new_value_(new_value
) {
614 ScopedCustomUrlRequestTestHttpHost::~ScopedCustomUrlRequestTestHttpHost() {
615 DCHECK_EQ(value_
, new_value_
);
620 const std::string
& ScopedCustomUrlRequestTestHttpHost::value() {
624 TestJobInterceptor::TestJobInterceptor() : main_intercept_job_(NULL
) {
627 URLRequestJob
* TestJobInterceptor::MaybeCreateJob(
629 NetworkDelegate
* network_delegate
) const {
630 URLRequestJob
* job
= main_intercept_job_
;
631 main_intercept_job_
= NULL
;
635 void TestJobInterceptor::set_main_intercept_job(URLRequestJob
* job
) {
636 main_intercept_job_
= job
;