Home | History | Annotate | Download | only in net
      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