url_request_mock_net_error_job.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1// Copyright (c) 2006-2008 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 "chrome/browser/net/url_request_mock_net_error_job.h"
6
7#include <string>
8#include <vector>
9
10#include "base/file_util.h"
11#include "base/message_loop.h"
12#include "base/utf_string_conversions.h"
13#include "net/base/net_errors.h"
14#include "net/base/net_util.h"
15#include "net/base/x509_certificate.h"
16#include "net/url_request/url_request_filter.h"
17
18// static
19URLRequestMockNetErrorJob::URLMockInfoMap
20    URLRequestMockNetErrorJob::url_mock_info_map_;
21
22struct URLRequestMockNetErrorJob::MockInfo {
23  MockInfo() : ssl_cert(NULL) { }
24  MockInfo(std::wstring base,
25           std::vector<int> errors,
26           net::X509Certificate* ssl_cert)
27      : base(base),
28        errors(errors),
29        ssl_cert(ssl_cert) { }
30
31  std::wstring base;
32  std::vector<int> errors;
33  scoped_refptr<net::X509Certificate> ssl_cert;
34};
35
36// static
37void URLRequestMockNetErrorJob::AddMockedURL(const GURL& url,
38                                             const std::wstring& base,
39                                             const std::vector<int>& errors,
40                                             net::X509Certificate* ssl_cert) {
41#ifndef NDEBUG
42  URLMockInfoMap::const_iterator iter = url_mock_info_map_.find(url);
43  DCHECK(iter == url_mock_info_map_.end());
44#endif
45
46  url_mock_info_map_[url] = MockInfo(base, errors, ssl_cert);
47  URLRequestFilter::GetInstance()
48      ->AddUrlHandler(url, &URLRequestMockNetErrorJob::Factory);
49}
50
51// static
52void URLRequestMockNetErrorJob::RemoveMockedURL(const GURL& url) {
53  URLMockInfoMap::iterator iter = url_mock_info_map_.find(url);
54  DCHECK(iter != url_mock_info_map_.end());
55  url_mock_info_map_.erase(iter);
56  URLRequestFilter::GetInstance()->RemoveUrlHandler(url);
57}
58
59// static
60URLRequestJob* URLRequestMockNetErrorJob::Factory(URLRequest* request,
61                                                  const std::string& scheme) {
62  GURL url = request->url();
63
64  URLMockInfoMap::const_iterator iter = url_mock_info_map_.find(url);
65  DCHECK(iter != url_mock_info_map_.end());
66
67  MockInfo mock_info = iter->second;
68
69  // URLRequestMockNetErrorJob derives from URLRequestFileJob.  We pass a
70  // FilePath so that the URLRequestFileJob methods will do the loading from
71  // the files.
72  std::wstring file_url(L"file:///");
73  file_url.append(mock_info.base);
74  file_url.append(UTF8ToWide(url.path()));
75  // Convert the file:/// URL to a path on disk.
76  FilePath file_path;
77  net::FileURLToFilePath(GURL(WideToUTF8(file_url)), &file_path);
78  return new URLRequestMockNetErrorJob(request, mock_info.errors,
79                                       mock_info.ssl_cert,
80                                       file_path);
81}
82
83URLRequestMockNetErrorJob::URLRequestMockNetErrorJob(URLRequest* request,
84    const std::vector<int>& errors, net::X509Certificate* cert,
85    const FilePath& file_path)
86    : URLRequestMockHTTPJob(request, file_path),
87      errors_(errors),
88      ssl_cert_(cert) {
89}
90
91URLRequestMockNetErrorJob::~URLRequestMockNetErrorJob() {
92}
93
94void URLRequestMockNetErrorJob::Start() {
95  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
96      this, &URLRequestMockNetErrorJob::StartAsync));
97}
98
99void URLRequestMockNetErrorJob::StartAsync() {
100  if (errors_.empty()) {
101    URLRequestMockHTTPJob::Start();
102  } else {
103    int error =  errors_[0];
104    errors_.erase(errors_.begin());
105
106    if (net::IsCertificateError(error)) {
107      DCHECK(ssl_cert_);
108      request_->delegate()->OnSSLCertificateError(request_, error,
109                                                  ssl_cert_.get());
110    } else {
111      NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error));
112    }
113  }
114}
115
116void URLRequestMockNetErrorJob::ContinueDespiteLastError() {
117  Start();
118}
119