1// Copyright (c) 2011 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.h"
10#include "base/threading/thread.h"
11#include "net/http/http_network_session.h"
12
13TestCookiePolicy::TestCookiePolicy(int options_bit_mask)
14    : options_(options_bit_mask) {
15}
16
17TestCookiePolicy::~TestCookiePolicy() {}
18
19int TestCookiePolicy::CanGetCookies(const GURL& url,
20                                    const GURL& first_party) const {
21  if (options_ & NO_GET_COOKIES)
22    return net::ERR_ACCESS_DENIED;
23
24  return net::OK;
25}
26
27int TestCookiePolicy::CanSetCookie(const GURL& url,
28                                   const GURL& first_party,
29                                   const std::string& cookie_line) const {
30  if (options_ & NO_SET_COOKIE)
31    return net::ERR_ACCESS_DENIED;
32
33  if (options_ & FORCE_SESSION)
34    return net::OK_FOR_SESSION_ONLY;
35
36  return net::OK;
37}
38
39TestURLRequestContext::TestURLRequestContext()
40    : ALLOW_THIS_IN_INITIALIZER_LIST(context_storage_(this)) {
41  context_storage_.set_host_resolver(
42      net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism,
43                                    NULL, NULL));
44  context_storage_.set_proxy_service(net::ProxyService::CreateDirect());
45  Init();
46}
47
48TestURLRequestContext::TestURLRequestContext(const std::string& proxy)
49    : ALLOW_THIS_IN_INITIALIZER_LIST(context_storage_(this)) {
50  context_storage_.set_host_resolver(
51      net::CreateSystemHostResolver(net::HostResolver::kDefaultParallelism,
52                                    NULL, NULL));
53  net::ProxyConfig proxy_config;
54  proxy_config.proxy_rules().ParseFromString(proxy);
55  context_storage_.set_proxy_service(
56      net::ProxyService::CreateFixed(proxy_config));
57  Init();
58}
59
60TestURLRequestContext::TestURLRequestContext(const std::string& proxy,
61                                             net::HostResolver* host_resolver)
62    : ALLOW_THIS_IN_INITIALIZER_LIST(context_storage_(this)) {
63  context_storage_.set_host_resolver(host_resolver);
64  net::ProxyConfig proxy_config;
65  proxy_config.proxy_rules().ParseFromString(proxy);
66  context_storage_.set_proxy_service(
67      net::ProxyService::CreateFixed(proxy_config));
68  Init();
69}
70
71TestURLRequestContext::~TestURLRequestContext() {}
72
73void TestURLRequestContext::Init() {
74  context_storage_.set_cert_verifier(new net::CertVerifier);
75  context_storage_.set_ftp_transaction_factory(
76      new net::FtpNetworkLayer(host_resolver()));
77  context_storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults);
78  context_storage_.set_http_auth_handler_factory(
79      net::HttpAuthHandlerFactory::CreateDefault(host_resolver()));
80  net::HttpNetworkSession::Params params;
81  params.host_resolver = host_resolver();
82  params.cert_verifier = cert_verifier();
83  params.proxy_service = proxy_service();
84  params.ssl_config_service = ssl_config_service();
85  params.http_auth_handler_factory = http_auth_handler_factory();
86  params.network_delegate = network_delegate();
87
88  context_storage_.set_http_transaction_factory(new net::HttpCache(
89      new net::HttpNetworkSession(params),
90      net::HttpCache::DefaultBackend::InMemory(0)));
91  // In-memory cookie store.
92  context_storage_.set_cookie_store(new net::CookieMonster(NULL, NULL));
93  set_accept_language("en-us,fr");
94  set_accept_charset("iso-8859-1,*,utf-8");
95}
96
97
98TestURLRequest::TestURLRequest(const GURL& url, Delegate* delegate)
99    : net::URLRequest(url, delegate) {
100  set_context(new TestURLRequestContext());
101}
102
103TestURLRequest::~TestURLRequest() {}
104
105TestDelegate::TestDelegate()
106    : cancel_in_rr_(false),
107      cancel_in_rs_(false),
108      cancel_in_rd_(false),
109      cancel_in_rd_pending_(false),
110      cancel_in_getcookiesblocked_(false),
111      cancel_in_setcookieblocked_(false),
112      quit_on_complete_(true),
113      quit_on_redirect_(false),
114      allow_certificate_errors_(false),
115      response_started_count_(0),
116      received_bytes_count_(0),
117      received_redirect_count_(0),
118      blocked_get_cookies_count_(0),
119      blocked_set_cookie_count_(0),
120      set_cookie_count_(0),
121      received_data_before_response_(false),
122      request_failed_(false),
123      have_certificate_errors_(false),
124      buf_(new net::IOBuffer(kBufferSize)) {
125}
126
127TestDelegate::~TestDelegate() {}
128
129void TestDelegate::OnReceivedRedirect(net::URLRequest* request,
130                                      const GURL& new_url,
131                                      bool* defer_redirect) {
132  received_redirect_count_++;
133  if (quit_on_redirect_) {
134    *defer_redirect = true;
135    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
136  } else if (cancel_in_rr_) {
137    request->Cancel();
138  }
139}
140
141void TestDelegate::OnAuthRequired(net::URLRequest* request,
142                                  net::AuthChallengeInfo* auth_info) {
143  if (!username_.empty() || !password_.empty()) {
144    request->SetAuth(username_, password_);
145  } else {
146    request->CancelAuth();
147  }
148}
149
150void TestDelegate::OnSSLCertificateError(net::URLRequest* request,
151                                         int cert_error,
152                                         net::X509Certificate* cert) {
153  // The caller can control whether it needs all SSL requests to go through,
154  // independent of any possible errors, or whether it wants SSL errors to
155  // cancel the request.
156  have_certificate_errors_ = true;
157  if (allow_certificate_errors_)
158    request->ContinueDespiteLastError();
159  else
160    request->Cancel();
161}
162
163void TestDelegate::OnGetCookies(net::URLRequest* request,
164                                bool blocked_by_policy) {
165  if (blocked_by_policy) {
166    blocked_get_cookies_count_++;
167    if (cancel_in_getcookiesblocked_)
168      request->Cancel();
169  }
170}
171
172void TestDelegate::OnSetCookie(net::URLRequest* request,
173                               const std::string& cookie_line,
174                               const net::CookieOptions& options,
175                               bool blocked_by_policy) {
176  if (blocked_by_policy) {
177    blocked_set_cookie_count_++;
178    if (cancel_in_setcookieblocked_)
179      request->Cancel();
180  } else {
181    set_cookie_count_++;
182  }
183}
184
185void TestDelegate::OnResponseStarted(net::URLRequest* request) {
186  // It doesn't make sense for the request to have IO pending at this point.
187  DCHECK(!request->status().is_io_pending());
188
189  response_started_count_++;
190  if (cancel_in_rs_) {
191    request->Cancel();
192    OnResponseCompleted(request);
193  } else if (!request->status().is_success()) {
194    DCHECK(request->status().status() == net::URLRequestStatus::FAILED ||
195           request->status().status() == net::URLRequestStatus::CANCELED);
196    request_failed_ = true;
197    OnResponseCompleted(request);
198  } else {
199    // Initiate the first read.
200    int bytes_read = 0;
201    if (request->Read(buf_, kBufferSize, &bytes_read))
202      OnReadCompleted(request, bytes_read);
203    else if (!request->status().is_io_pending())
204      OnResponseCompleted(request);
205  }
206}
207
208void TestDelegate::OnReadCompleted(net::URLRequest* request, int bytes_read) {
209  // It doesn't make sense for the request to have IO pending at this point.
210  DCHECK(!request->status().is_io_pending());
211
212  if (response_started_count_ == 0)
213    received_data_before_response_ = true;
214
215  if (cancel_in_rd_)
216    request->Cancel();
217
218  if (bytes_read >= 0) {
219    // There is data to read.
220    received_bytes_count_ += bytes_read;
221
222    // consume the data
223    data_received_.append(buf_->data(), bytes_read);
224  }
225
226  // If it was not end of stream, request to read more.
227  if (request->status().is_success() && bytes_read > 0) {
228    bytes_read = 0;
229    while (request->Read(buf_, kBufferSize, &bytes_read)) {
230      if (bytes_read > 0) {
231        data_received_.append(buf_->data(), bytes_read);
232        received_bytes_count_ += bytes_read;
233      } else {
234        break;
235      }
236    }
237  }
238  if (!request->status().is_io_pending())
239    OnResponseCompleted(request);
240  else if (cancel_in_rd_pending_)
241    request->Cancel();
242}
243
244void TestDelegate::OnResponseCompleted(net::URLRequest* request) {
245  if (quit_on_complete_)
246    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
247}
248
249TestNetworkDelegate::TestNetworkDelegate()
250  : last_os_error_(0),
251    error_count_(0),
252    created_requests_(0),
253    destroyed_requests_(0) {
254}
255
256TestNetworkDelegate::~TestNetworkDelegate() {}
257
258int TestNetworkDelegate::OnBeforeURLRequest(
259    net::URLRequest* request,
260    net::CompletionCallback* callback,
261    GURL* new_url) {
262  created_requests_++;
263  return net::OK;
264}
265
266int TestNetworkDelegate::OnBeforeSendHeaders(
267    uint64 request_id,
268    net::CompletionCallback* callback,
269    net::HttpRequestHeaders* headers) {
270  return net::OK;
271}
272
273void TestNetworkDelegate::OnResponseStarted(net::URLRequest* request) {
274  if (request->status().status() == net::URLRequestStatus::FAILED) {
275    error_count_++;
276    last_os_error_ = request->status().os_error();
277  }
278}
279
280void TestNetworkDelegate::OnReadCompleted(net::URLRequest* request,
281                                              int bytes_read) {
282  if (request->status().status() == net::URLRequestStatus::FAILED) {
283    error_count_++;
284    last_os_error_ = request->status().os_error();
285  }
286}
287
288void TestNetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {
289  destroyed_requests_++;
290}
291
292net::URLRequestJob* TestNetworkDelegate::OnMaybeCreateURLRequestJob(
293    net::URLRequest* request) {
294  return NULL;
295}
296