url_request_test_util.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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.
4
5#include "net/url_request/url_request_test_util.h"
6
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_server_properties_impl.h"
17#include "net/http/transport_security_state.h"
18#include "net/ssl/default_server_bound_cert_store.h"
19#include "net/ssl/server_bound_cert_service.h"
20#include "net/url_request/static_http_user_agent_settings.h"
21#include "net/url_request/url_request_job_factory_impl.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace net {
25
26namespace {
27
28// These constants put the NetworkDelegate events of TestNetworkDelegate
29// into an order. They are used in conjunction with
30// |TestNetworkDelegate::next_states_| to check that we do not send
31// events in the wrong order.
32const int kStageBeforeURLRequest = 1 << 0;
33const int kStageBeforeSendHeaders = 1 << 1;
34const int kStageSendHeaders = 1 << 2;
35const int kStageHeadersReceived = 1 << 3;
36const int kStageAuthRequired = 1 << 4;
37const int kStageBeforeRedirect = 1 << 5;
38const int kStageResponseStarted = 1 << 6;
39const int kStageCompletedSuccess = 1 << 7;
40const int kStageCompletedError = 1 << 8;
41const int kStageURLRequestDestroyed = 1 << 9;
42const int kStageDestruction = 1 << 10;
43
44}  // namespace
45
46TestURLRequestContext::TestURLRequestContext()
47    : initialized_(false),
48      client_socket_factory_(NULL),
49      context_storage_(this) {
50  Init();
51}
52
53TestURLRequestContext::TestURLRequestContext(bool delay_initialization)
54    : initialized_(false),
55      client_socket_factory_(NULL),
56      context_storage_(this) {
57  if (!delay_initialization)
58    Init();
59}
60
61TestURLRequestContext::~TestURLRequestContext() {
62  DCHECK(initialized_);
63}
64
65void TestURLRequestContext::Init() {
66  DCHECK(!initialized_);
67  initialized_ = true;
68
69  if (!host_resolver())
70    context_storage_.set_host_resolver(
71        scoped_ptr<HostResolver>(new MockCachingHostResolver()));
72  if (!proxy_service())
73    context_storage_.set_proxy_service(ProxyService::CreateDirect());
74  if (!cert_verifier())
75    context_storage_.set_cert_verifier(CertVerifier::CreateDefault());
76  if (!transport_security_state())
77    context_storage_.set_transport_security_state(new TransportSecurityState);
78  if (!ssl_config_service())
79    context_storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
80  if (!http_auth_handler_factory()) {
81    context_storage_.set_http_auth_handler_factory(
82        HttpAuthHandlerFactory::CreateDefault(host_resolver()));
83  }
84  if (!http_server_properties()) {
85    context_storage_.set_http_server_properties(
86        scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
87  }
88  if (!transport_security_state()) {
89    context_storage_.set_transport_security_state(
90        new TransportSecurityState());
91  }
92  if (http_transaction_factory()) {
93    // Make sure we haven't been passed an object we're not going to use.
94    EXPECT_FALSE(client_socket_factory_);
95  } else {
96    HttpNetworkSession::Params params;
97    params.client_socket_factory = client_socket_factory();
98    params.host_resolver = host_resolver();
99    params.cert_verifier = cert_verifier();
100    params.transport_security_state = transport_security_state();
101    params.proxy_service = proxy_service();
102    params.ssl_config_service = ssl_config_service();
103    params.http_auth_handler_factory = http_auth_handler_factory();
104    params.network_delegate = network_delegate();
105    params.http_server_properties = http_server_properties();
106    params.net_log = net_log();
107    context_storage_.set_http_transaction_factory(new HttpCache(
108        new HttpNetworkSession(params),
109        HttpCache::DefaultBackend::InMemory(0)));
110  }
111  // In-memory cookie store.
112  if (!cookie_store())
113    context_storage_.set_cookie_store(new CookieMonster(NULL, NULL));
114  // In-memory origin bound cert service.
115  if (!server_bound_cert_service()) {
116    context_storage_.set_server_bound_cert_service(
117        new ServerBoundCertService(
118            new DefaultServerBoundCertStore(NULL),
119            base::WorkerPool::GetTaskRunner(true)));
120  }
121  if (!http_user_agent_settings()) {
122    context_storage_.set_http_user_agent_settings(
123        new StaticHttpUserAgentSettings("en-us,fr", EmptyString()));
124  }
125  if (!job_factory())
126    context_storage_.set_job_factory(new URLRequestJobFactoryImpl);
127}
128
129TestURLRequest::TestURLRequest(const GURL& url,
130                               Delegate* delegate,
131                               TestURLRequestContext* context,
132                               NetworkDelegate* network_delegate)
133    : URLRequest(url, delegate, context, network_delegate) {
134}
135
136TestURLRequest::~TestURLRequest() {
137}
138
139TestURLRequestContextGetter::TestURLRequestContextGetter(
140    const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner)
141    : network_task_runner_(network_task_runner) {
142  DCHECK(network_task_runner_.get());
143}
144
145TestURLRequestContextGetter::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());
150}
151
152TestURLRequestContextGetter::~TestURLRequestContextGetter() {}
153
154TestURLRequestContext* TestURLRequestContextGetter::GetURLRequestContext() {
155  if (!context_.get())
156    context_.reset(new TestURLRequestContext);
157  return context_.get();
158}
159
160scoped_refptr<base::SingleThreadTaskRunner>
161TestURLRequestContextGetter::GetNetworkTaskRunner() const {
162  return network_task_runner_;
163}
164
165TestDelegate::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      allow_certificate_errors_(false),
173      response_started_count_(0),
174      received_bytes_count_(0),
175      received_redirect_count_(0),
176      received_data_before_response_(false),
177      request_failed_(false),
178      have_certificate_errors_(false),
179      certificate_errors_are_fatal_(false),
180      auth_required_(false),
181      have_full_request_headers_(false),
182      buf_(new IOBuffer(kBufferSize)) {
183}
184
185TestDelegate::~TestDelegate() {}
186
187void TestDelegate::ClearFullRequestHeaders() {
188  full_request_headers_.Clear();
189  have_full_request_headers_ = false;
190}
191
192void TestDelegate::OnReceivedRedirect(URLRequest* request,
193                                      const GURL& new_url,
194                                      bool* defer_redirect) {
195  EXPECT_TRUE(request->is_redirecting());
196
197  have_full_request_headers_ =
198      request->GetFullRequestHeaders(&full_request_headers_);
199
200  received_redirect_count_++;
201  if (quit_on_redirect_) {
202    *defer_redirect = true;
203    base::MessageLoop::current()->PostTask(FROM_HERE,
204                                           base::MessageLoop::QuitClosure());
205  } else if (cancel_in_rr_) {
206    request->Cancel();
207  }
208}
209
210void TestDelegate::OnAuthRequired(URLRequest* request,
211                                  AuthChallengeInfo* auth_info) {
212  auth_required_ = true;
213  if (!credentials_.Empty()) {
214    request->SetAuth(credentials_);
215  } else {
216    request->CancelAuth();
217  }
218}
219
220void TestDelegate::OnSSLCertificateError(URLRequest* request,
221                                         const SSLInfo& ssl_info,
222                                         bool fatal) {
223  // The caller can control whether it needs all SSL requests to go through,
224  // independent of any possible errors, or whether it wants SSL errors to
225  // cancel the request.
226  have_certificate_errors_ = true;
227  certificate_errors_are_fatal_ = fatal;
228  if (allow_certificate_errors_)
229    request->ContinueDespiteLastError();
230  else
231    request->Cancel();
232}
233
234void TestDelegate::OnResponseStarted(URLRequest* request) {
235  // It doesn't make sense for the request to have IO pending at this point.
236  DCHECK(!request->status().is_io_pending());
237  EXPECT_FALSE(request->is_redirecting());
238
239  have_full_request_headers_ =
240      request->GetFullRequestHeaders(&full_request_headers_);
241
242  response_started_count_++;
243  if (cancel_in_rs_) {
244    request->Cancel();
245    OnResponseCompleted(request);
246  } else if (!request->status().is_success()) {
247    DCHECK(request->status().status() == URLRequestStatus::FAILED ||
248           request->status().status() == URLRequestStatus::CANCELED);
249    request_failed_ = true;
250    OnResponseCompleted(request);
251  } else {
252    // Initiate the first read.
253    int bytes_read = 0;
254    if (request->Read(buf_.get(), kBufferSize, &bytes_read))
255      OnReadCompleted(request, bytes_read);
256    else if (!request->status().is_io_pending())
257      OnResponseCompleted(request);
258  }
259}
260
261void TestDelegate::OnReadCompleted(URLRequest* request, int bytes_read) {
262  // It doesn't make sense for the request to have IO pending at this point.
263  DCHECK(!request->status().is_io_pending());
264
265  if (response_started_count_ == 0)
266    received_data_before_response_ = true;
267
268  if (cancel_in_rd_)
269    request->Cancel();
270
271  if (bytes_read >= 0) {
272    // There is data to read.
273    received_bytes_count_ += bytes_read;
274
275    // consume the data
276    data_received_.append(buf_->data(), bytes_read);
277  }
278
279  // If it was not end of stream, request to read more.
280  if (request->status().is_success() && bytes_read > 0) {
281    bytes_read = 0;
282    while (request->Read(buf_.get(), kBufferSize, &bytes_read)) {
283      if (bytes_read > 0) {
284        data_received_.append(buf_->data(), bytes_read);
285        received_bytes_count_ += bytes_read;
286      } else {
287        break;
288      }
289    }
290  }
291  if (!request->status().is_io_pending())
292    OnResponseCompleted(request);
293  else if (cancel_in_rd_pending_)
294    request->Cancel();
295}
296
297void TestDelegate::OnResponseCompleted(URLRequest* request) {
298  if (quit_on_complete_)
299    base::MessageLoop::current()->PostTask(FROM_HERE,
300                                           base::MessageLoop::QuitClosure());
301}
302
303TestNetworkDelegate::TestNetworkDelegate()
304    : last_error_(0),
305      error_count_(0),
306      created_requests_(0),
307      destroyed_requests_(0),
308      completed_requests_(0),
309      cookie_options_bit_mask_(0),
310      blocked_get_cookies_count_(0),
311      blocked_set_cookie_count_(0),
312      set_cookie_count_(0),
313      has_load_timing_info_before_redirect_(false),
314      has_load_timing_info_before_auth_(false) {
315}
316
317TestNetworkDelegate::~TestNetworkDelegate() {
318  for (std::map<int, int>::iterator i = next_states_.begin();
319       i != next_states_.end(); ++i) {
320    event_order_[i->first] += "~TestNetworkDelegate\n";
321    EXPECT_TRUE(i->second & kStageDestruction) << event_order_[i->first];
322  }
323}
324
325bool TestNetworkDelegate::GetLoadTimingInfoBeforeRedirect(
326    LoadTimingInfo* load_timing_info_before_redirect) const {
327  *load_timing_info_before_redirect = load_timing_info_before_redirect_;
328  return has_load_timing_info_before_redirect_;
329}
330
331bool TestNetworkDelegate::GetLoadTimingInfoBeforeAuth(
332    LoadTimingInfo* load_timing_info_before_auth) const {
333  *load_timing_info_before_auth = load_timing_info_before_auth_;
334  return has_load_timing_info_before_auth_;
335}
336
337void TestNetworkDelegate::InitRequestStatesIfNew(int request_id) {
338  if (next_states_.find(request_id) == next_states_.end()) {
339    next_states_[request_id] = kStageBeforeURLRequest;
340    event_order_[request_id] = "";
341  }
342}
343
344int TestNetworkDelegate::OnBeforeURLRequest(
345    URLRequest* request,
346    const CompletionCallback& callback,
347    GURL* new_url ) {
348  int req_id = request->identifier();
349  InitRequestStatesIfNew(req_id);
350  event_order_[req_id] += "OnBeforeURLRequest\n";
351  EXPECT_TRUE(next_states_[req_id] & kStageBeforeURLRequest) <<
352      event_order_[req_id];
353  next_states_[req_id] =
354      kStageBeforeSendHeaders |
355      kStageResponseStarted |  // data: URLs do not trigger sending headers
356      kStageBeforeRedirect |  // a delegate can trigger a redirection
357      kStageCompletedError |  // request canceled by delegate
358      kStageAuthRequired;  // Auth can come next for FTP requests
359  created_requests_++;
360  return OK;
361}
362
363int TestNetworkDelegate::OnBeforeSendHeaders(
364    URLRequest* request,
365    const CompletionCallback& callback,
366    HttpRequestHeaders* headers) {
367  int req_id = request->identifier();
368  InitRequestStatesIfNew(req_id);
369  event_order_[req_id] += "OnBeforeSendHeaders\n";
370  EXPECT_TRUE(next_states_[req_id] & kStageBeforeSendHeaders) <<
371      event_order_[req_id];
372  next_states_[req_id] =
373      kStageSendHeaders |
374      kStageCompletedError;  // request canceled by delegate
375
376  return OK;
377}
378
379void TestNetworkDelegate::OnSendHeaders(
380    URLRequest* request,
381    const HttpRequestHeaders& headers) {
382  int req_id = request->identifier();
383  InitRequestStatesIfNew(req_id);
384  event_order_[req_id] += "OnSendHeaders\n";
385  EXPECT_TRUE(next_states_[req_id] & kStageSendHeaders) <<
386      event_order_[req_id];
387  next_states_[req_id] =
388      kStageHeadersReceived |
389      kStageCompletedError;
390}
391
392int TestNetworkDelegate::OnHeadersReceived(
393    URLRequest* request,
394    const CompletionCallback& callback,
395    const HttpResponseHeaders* original_response_headers,
396    scoped_refptr<HttpResponseHeaders>* override_response_headers) {
397  int req_id = request->identifier();
398  event_order_[req_id] += "OnHeadersReceived\n";
399  InitRequestStatesIfNew(req_id);
400  EXPECT_TRUE(next_states_[req_id] & kStageHeadersReceived) <<
401      event_order_[req_id];
402  next_states_[req_id] =
403      kStageBeforeRedirect |
404      kStageResponseStarted |
405      kStageAuthRequired |
406      kStageCompletedError;  // e.g. proxy resolution problem
407
408  // Basic authentication sends a second request from the URLRequestHttpJob
409  // layer before the URLRequest reports that a response has started.
410  next_states_[req_id] |= kStageBeforeSendHeaders;
411
412  return OK;
413}
414
415void TestNetworkDelegate::OnBeforeRedirect(URLRequest* request,
416                                           const GURL& new_location) {
417  load_timing_info_before_redirect_ = LoadTimingInfo();
418  request->GetLoadTimingInfo(&load_timing_info_before_redirect_);
419  has_load_timing_info_before_redirect_ = true;
420  EXPECT_FALSE(load_timing_info_before_redirect_.request_start_time.is_null());
421  EXPECT_FALSE(load_timing_info_before_redirect_.request_start.is_null());
422
423  int req_id = request->identifier();
424  InitRequestStatesIfNew(req_id);
425  event_order_[req_id] += "OnBeforeRedirect\n";
426  EXPECT_TRUE(next_states_[req_id] & kStageBeforeRedirect) <<
427      event_order_[req_id];
428  next_states_[req_id] =
429      kStageBeforeURLRequest |  // HTTP redirects trigger this.
430      kStageBeforeSendHeaders |  // Redirects from the network delegate do not
431                                 // trigger onBeforeURLRequest.
432      kStageCompletedError;
433
434  // A redirect can lead to a file or a data URL. In this case, we do not send
435  // headers.
436  next_states_[req_id] |= kStageResponseStarted;
437}
438
439void TestNetworkDelegate::OnResponseStarted(URLRequest* request) {
440  LoadTimingInfo load_timing_info;
441  request->GetLoadTimingInfo(&load_timing_info);
442  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
443  EXPECT_FALSE(load_timing_info.request_start.is_null());
444
445  int req_id = request->identifier();
446  InitRequestStatesIfNew(req_id);
447  event_order_[req_id] += "OnResponseStarted\n";
448  EXPECT_TRUE(next_states_[req_id] & kStageResponseStarted) <<
449      event_order_[req_id];
450  next_states_[req_id] = kStageCompletedSuccess | kStageCompletedError;
451  if (request->status().status() == URLRequestStatus::FAILED) {
452    error_count_++;
453    last_error_ = request->status().error();
454  }
455}
456
457void TestNetworkDelegate::OnRawBytesRead(const URLRequest& request,
458                                         int bytes_read) {
459}
460
461void TestNetworkDelegate::OnCompleted(URLRequest* request, bool started) {
462  int req_id = request->identifier();
463  InitRequestStatesIfNew(req_id);
464  event_order_[req_id] += "OnCompleted\n";
465  // Expect "Success -> (next_states_ & kStageCompletedSuccess)"
466  // is logically identical to
467  // Expect "!(Success) || (next_states_ & kStageCompletedSuccess)"
468  EXPECT_TRUE(!request->status().is_success() ||
469              (next_states_[req_id] & kStageCompletedSuccess)) <<
470      event_order_[req_id];
471  EXPECT_TRUE(request->status().is_success() ||
472              (next_states_[req_id] & kStageCompletedError)) <<
473      event_order_[req_id];
474  next_states_[req_id] = kStageURLRequestDestroyed;
475  completed_requests_++;
476  if (request->status().status() == URLRequestStatus::FAILED) {
477    error_count_++;
478    last_error_ = request->status().error();
479  }
480}
481
482void TestNetworkDelegate::OnURLRequestDestroyed(URLRequest* request) {
483  int req_id = request->identifier();
484  InitRequestStatesIfNew(req_id);
485  event_order_[req_id] += "OnURLRequestDestroyed\n";
486  EXPECT_TRUE(next_states_[req_id] & kStageURLRequestDestroyed) <<
487      event_order_[req_id];
488  next_states_[req_id] = kStageDestruction;
489  destroyed_requests_++;
490}
491
492void TestNetworkDelegate::OnPACScriptError(int line_number,
493                                           const base::string16& error) {
494}
495
496NetworkDelegate::AuthRequiredResponse TestNetworkDelegate::OnAuthRequired(
497    URLRequest* request,
498    const AuthChallengeInfo& auth_info,
499    const AuthCallback& callback,
500    AuthCredentials* credentials) {
501  load_timing_info_before_auth_ = LoadTimingInfo();
502  request->GetLoadTimingInfo(&load_timing_info_before_auth_);
503  has_load_timing_info_before_auth_ = true;
504  EXPECT_FALSE(load_timing_info_before_auth_.request_start_time.is_null());
505  EXPECT_FALSE(load_timing_info_before_auth_.request_start.is_null());
506
507  int req_id = request->identifier();
508  InitRequestStatesIfNew(req_id);
509  event_order_[req_id] += "OnAuthRequired\n";
510  EXPECT_TRUE(next_states_[req_id] & kStageAuthRequired) <<
511      event_order_[req_id];
512  next_states_[req_id] = kStageBeforeSendHeaders |
513      kStageAuthRequired |  // For example, proxy auth followed by server auth.
514      kStageHeadersReceived |  // Request canceled by delegate simulates empty
515                               // response.
516      kStageResponseStarted |  // data: URLs do not trigger sending headers
517      kStageBeforeRedirect |   // a delegate can trigger a redirection
518      kStageCompletedError;    // request cancelled before callback
519  return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
520}
521
522bool TestNetworkDelegate::OnCanGetCookies(const URLRequest& request,
523                                          const CookieList& cookie_list) {
524  bool allow = true;
525  if (cookie_options_bit_mask_ & NO_GET_COOKIES)
526    allow = false;
527
528  if (!allow) {
529    blocked_get_cookies_count_++;
530  }
531
532  return allow;
533}
534
535bool TestNetworkDelegate::OnCanSetCookie(const URLRequest& request,
536                                         const std::string& cookie_line,
537                                         CookieOptions* options) {
538  bool allow = true;
539  if (cookie_options_bit_mask_ & NO_SET_COOKIE)
540    allow = false;
541
542  if (!allow) {
543    blocked_set_cookie_count_++;
544  } else {
545    set_cookie_count_++;
546  }
547
548  return allow;
549}
550
551bool TestNetworkDelegate::OnCanAccessFile(const URLRequest& request,
552                                          const base::FilePath& path) const {
553  return true;
554}
555
556bool TestNetworkDelegate::OnCanThrottleRequest(
557    const URLRequest& request) const {
558  return true;
559}
560
561int TestNetworkDelegate::OnBeforeSocketStreamConnect(
562    SocketStream* socket,
563    const CompletionCallback& callback) {
564  return OK;
565}
566
567void TestNetworkDelegate::OnRequestWaitStateChange(
568    const URLRequest& request,
569    RequestWaitState state) {
570}
571
572// static
573std::string ScopedCustomUrlRequestTestHttpHost::value_("127.0.0.1");
574
575ScopedCustomUrlRequestTestHttpHost::ScopedCustomUrlRequestTestHttpHost(
576  const std::string& new_value)
577    : old_value_(value_),
578      new_value_(new_value) {
579  value_ = new_value_;
580}
581
582ScopedCustomUrlRequestTestHttpHost::~ScopedCustomUrlRequestTestHttpHost() {
583  DCHECK_EQ(value_, new_value_);
584  value_ = old_value_;
585}
586
587// static
588const std::string& ScopedCustomUrlRequestTestHttpHost::value() {
589  return value_;
590}
591
592TestJobInterceptor::TestJobInterceptor() : main_intercept_job_(NULL) {
593}
594
595URLRequestJob* TestJobInterceptor::MaybeCreateJob(
596    URLRequest* request,
597    NetworkDelegate* network_delegate) const {
598  URLRequestJob* job = main_intercept_job_;
599  main_intercept_job_ = NULL;
600  return job;
601}
602
603void TestJobInterceptor::set_main_intercept_job(URLRequestJob* job) {
604  main_intercept_job_ = job;
605}
606
607}  // namespace net
608