172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_request_mock_net_error_job.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/x509_certificate.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_filter.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochURLRequestMockNetErrorJob::URLMockInfoMap
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLRequestMockNetErrorJob::url_mock_info_map_;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstruct URLRequestMockNetErrorJob::MockInfo {
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockInfo() : ssl_cert(NULL) { }
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MockInfo(std::wstring base,
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           std::vector<int> errors,
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           net::X509Certificate* ssl_cert)
27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : base(base),
28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        errors(errors),
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        ssl_cert(ssl_cert) { }
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::wstring base;
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::vector<int> errors;
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<net::X509Certificate> ssl_cert;
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestMockNetErrorJob::AddMockedURL(const GURL& url,
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const std::wstring& base,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const std::vector<int>& errors,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             net::X509Certificate* ssl_cert) {
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NDEBUG
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLMockInfoMap::const_iterator iter = url_mock_info_map_.find(url);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(iter == url_mock_info_map_.end());
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_mock_info_map_[url] = MockInfo(base, errors, ssl_cert);
473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  net::URLRequestFilter::GetInstance()
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ->AddUrlHandler(url, &URLRequestMockNetErrorJob::Factory);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestMockNetErrorJob::RemoveMockedURL(const GURL& url) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLMockInfoMap::iterator iter = url_mock_info_map_.find(url);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(iter != url_mock_info_map_.end());
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_mock_info_map_.erase(iter);
563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  net::URLRequestFilter::GetInstance()->RemoveUrlHandler(url);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequestJob* URLRequestMockNetErrorJob::Factory(
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    net::URLRequest* request,
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const std::string& scheme) {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url = request->url();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLMockInfoMap::const_iterator iter = url_mock_info_map_.find(url);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(iter != url_mock_info_map_.end());
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockInfo mock_info = iter->second;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // URLRequestMockNetErrorJob derives from net::URLRequestFileJob.  We pass a
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // FilePath so that the net::URLRequestFileJob methods will do the loading
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // from the files.
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring file_url(L"file:///");
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_url.append(mock_info.base);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_url.append(UTF8ToWide(url.path()));
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Convert the file:/// URL to a path on disk.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath file_path;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::FileURLToFilePath(GURL(WideToUTF8(file_url)), &file_path);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new URLRequestMockNetErrorJob(request, mock_info.errors,
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       mock_info.ssl_cert,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       file_path);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenURLRequestMockNetErrorJob::URLRequestMockNetErrorJob(net::URLRequest* request,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<int>& errors, net::X509Certificate* cert,
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& file_path)
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : URLRequestMockHTTPJob(request, file_path),
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      errors_(errors),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ssl_cert_(cert) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochURLRequestMockNetErrorJob::~URLRequestMockNetErrorJob() {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestMockNetErrorJob::Start() {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      this, &URLRequestMockNetErrorJob::StartAsync));
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestMockNetErrorJob::StartAsync() {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (errors_.empty()) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLRequestMockHTTPJob::Start();
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int error =  errors_[0];
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    errors_.erase(errors_.begin());
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (net::IsCertificateError(error)) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(ssl_cert_);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_->delegate()->OnSSLCertificateError(request_, error,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                  ssl_cert_.get());
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                             error));
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid URLRequestMockNetErrorJob::ContinueDespiteLastError() {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Start();
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
121