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 "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 19 URLRequestMockNetErrorJob::URLMockInfoMap 20 URLRequestMockNetErrorJob::url_mock_info_map_; 21 22 struct 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 37 void 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 net::URLRequestFilter::GetInstance() 48 ->AddUrlHandler(url, &URLRequestMockNetErrorJob::Factory); 49 } 50 51 // static 52 void 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 net::URLRequestFilter::GetInstance()->RemoveUrlHandler(url); 57 } 58 59 // static 60 net::URLRequestJob* URLRequestMockNetErrorJob::Factory( 61 net::URLRequest* request, 62 const std::string& scheme) { 63 GURL url = request->url(); 64 65 URLMockInfoMap::const_iterator iter = url_mock_info_map_.find(url); 66 DCHECK(iter != url_mock_info_map_.end()); 67 68 MockInfo mock_info = iter->second; 69 70 // URLRequestMockNetErrorJob derives from net::URLRequestFileJob. We pass a 71 // FilePath so that the net::URLRequestFileJob methods will do the loading 72 // from the files. 73 std::wstring file_url(L"file:///"); 74 file_url.append(mock_info.base); 75 file_url.append(UTF8ToWide(url.path())); 76 // Convert the file:/// URL to a path on disk. 77 FilePath file_path; 78 net::FileURLToFilePath(GURL(WideToUTF8(file_url)), &file_path); 79 return new URLRequestMockNetErrorJob(request, mock_info.errors, 80 mock_info.ssl_cert, 81 file_path); 82 } 83 84 URLRequestMockNetErrorJob::URLRequestMockNetErrorJob(net::URLRequest* request, 85 const std::vector<int>& errors, net::X509Certificate* cert, 86 const FilePath& file_path) 87 : URLRequestMockHTTPJob(request, file_path), 88 errors_(errors), 89 ssl_cert_(cert) { 90 } 91 92 URLRequestMockNetErrorJob::~URLRequestMockNetErrorJob() { 93 } 94 95 void URLRequestMockNetErrorJob::Start() { 96 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( 97 this, &URLRequestMockNetErrorJob::StartAsync)); 98 } 99 100 void URLRequestMockNetErrorJob::StartAsync() { 101 if (errors_.empty()) { 102 URLRequestMockHTTPJob::Start(); 103 } else { 104 int error = errors_[0]; 105 errors_.erase(errors_.begin()); 106 107 if (net::IsCertificateError(error)) { 108 DCHECK(ssl_cert_); 109 request_->delegate()->OnSSLCertificateError(request_, error, 110 ssl_cert_.get()); 111 } else { 112 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 113 error)); 114 } 115 } 116 } 117 118 void URLRequestMockNetErrorJob::ContinueDespiteLastError() { 119 Start(); 120 } 121