1 // Copyright (c) 2012 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/test/url_request/url_request_failed_job.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/strings/string_number_conversions.h" 11 #include "net/base/net_errors.h" 12 #include "net/url_request/url_request.h" 13 #include "net/url_request/url_request_filter.h" 14 15 namespace net { 16 namespace { 17 18 const char kMockHostname[] = "mock.failed.request"; 19 20 // Gets the numeric net error code from URL of the form: 21 // scheme://kMockHostname/error_code. The error code must be a valid 22 // net error code, and not net::OK or net::ERR_IO_PENDING. 23 int GetErrorCode(net::URLRequest* request) { 24 int net_error; 25 std::string path = request->url().path(); 26 if (path[0] == '/' && base::StringToInt(path.c_str() + 1, &net_error)) { 27 CHECK_LT(net_error, 0); 28 CHECK_NE(net_error, net::ERR_IO_PENDING); 29 return net_error; 30 } 31 NOTREACHED(); 32 return net::ERR_UNEXPECTED; 33 } 34 35 GURL GetMockUrl(const std::string& scheme, 36 const std::string& hostname, 37 int net_error) { 38 CHECK_LT(net_error, 0); 39 CHECK_NE(net_error, net::ERR_IO_PENDING); 40 return GURL(scheme + "://" + hostname + "/" + base::IntToString(net_error)); 41 } 42 43 } // namespace 44 45 URLRequestFailedJob::URLRequestFailedJob(net::URLRequest* request, 46 net::NetworkDelegate* network_delegate, 47 int net_error) 48 : net::URLRequestJob(request, network_delegate), 49 net_error_(net_error), 50 weak_factory_(this) {} 51 52 void URLRequestFailedJob::Start() { 53 base::MessageLoop::current()->PostTask( 54 FROM_HERE, 55 base::Bind(&URLRequestFailedJob::StartAsync, weak_factory_.GetWeakPtr())); 56 } 57 58 // static 59 void URLRequestFailedJob::AddUrlHandler() { 60 return AddUrlHandlerForHostname(kMockHostname); 61 } 62 63 // static 64 void URLRequestFailedJob::AddUrlHandlerForHostname( 65 const std::string& hostname) { 66 // Add |hostname| to net::URLRequestFilter for HTTP and HTTPS. 67 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); 68 filter->AddHostnameHandler("http", hostname, URLRequestFailedJob::Factory); 69 filter->AddHostnameHandler("https", hostname, URLRequestFailedJob::Factory); 70 } 71 72 // static 73 GURL URLRequestFailedJob::GetMockHttpUrl(int net_error) { 74 return GetMockHttpUrlForHostname(net_error, kMockHostname); 75 } 76 77 // static 78 GURL URLRequestFailedJob::GetMockHttpsUrl(int net_error) { 79 return GetMockHttpsUrlForHostname(net_error, kMockHostname); 80 } 81 82 // static 83 GURL URLRequestFailedJob::GetMockHttpUrlForHostname( 84 int net_error, const std::string& hostname) { 85 return GetMockUrl("http", hostname, net_error); 86 } 87 88 // static 89 GURL URLRequestFailedJob::GetMockHttpsUrlForHostname( 90 int net_error, const std::string& hostname) { 91 return GetMockUrl("https", hostname, net_error); 92 } 93 94 URLRequestFailedJob::~URLRequestFailedJob() {} 95 96 // static 97 net::URLRequestJob* URLRequestFailedJob::Factory( 98 net::URLRequest* request, 99 net::NetworkDelegate* network_delegate, 100 const std::string& scheme) { 101 return new URLRequestFailedJob( 102 request, network_delegate, GetErrorCode(request)); 103 } 104 105 void URLRequestFailedJob::StartAsync() { 106 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 107 net_error_)); 108 } 109 110 } // namespace net 111