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.
5 #include "net/test/url_request/url_request_failed_job.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/macros.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/url_util.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_filter.h"
19 #include "net/url_request/url_request_interceptor.h"
25 const char kMockHostname
[] = "mock.failed.request";
27 // String names of failure phases matching FailurePhase enum.
28 const char* kFailurePhase
[]{
30 "readsync", // READ_SYNC
31 "readasync", // READ_ASYNC
34 static_assert(arraysize(kFailurePhase
) ==
35 URLRequestFailedJob::FailurePhase::MAX_FAILURE_PHASE
,
36 "kFailurePhase must match FailurePhase enum");
38 class MockJobInterceptor
: public URLRequestInterceptor
{
40 MockJobInterceptor() {}
41 ~MockJobInterceptor() override
{}
43 // URLRequestJobFactory::ProtocolHandler implementation:
44 URLRequestJob
* MaybeInterceptRequest(
46 NetworkDelegate
* network_delegate
) const override
{
48 URLRequestFailedJob::FailurePhase phase
=
49 URLRequestFailedJob::FailurePhase::MAX_FAILURE_PHASE
;
50 for (size_t i
= 0; i
< arraysize(kFailurePhase
); i
++) {
51 std::string phase_error_string
;
52 if (GetValueForKeyInQuery(request
->url(), kFailurePhase
[i
],
53 &phase_error_string
)) {
54 if (base::StringToInt(phase_error_string
, &net_error
)) {
55 phase
= static_cast<URLRequestFailedJob::FailurePhase
>(i
);
60 return new URLRequestFailedJob(request
, network_delegate
, phase
, net_error
);
64 DISALLOW_COPY_AND_ASSIGN(MockJobInterceptor
);
67 GURL
GetMockUrl(const std::string
& scheme
,
68 const std::string
& hostname
,
69 URLRequestFailedJob::FailurePhase phase
,
71 CHECK_GE(phase
, URLRequestFailedJob::FailurePhase::START
);
72 CHECK_LE(phase
, URLRequestFailedJob::FailurePhase::READ_ASYNC
);
73 CHECK_LT(net_error
, OK
);
74 return GURL(scheme
+ "://" + hostname
+ "/error?" + kFailurePhase
[phase
] +
75 "=" + base::IntToString(net_error
));
80 URLRequestFailedJob::URLRequestFailedJob(URLRequest
* request
,
81 NetworkDelegate
* network_delegate
,
84 : URLRequestJob(request
, network_delegate
),
86 net_error_(net_error
),
88 CHECK_GE(phase
, URLRequestFailedJob::FailurePhase::START
);
89 CHECK_LE(phase
, URLRequestFailedJob::FailurePhase::READ_ASYNC
);
90 CHECK_LT(net_error
, OK
);
93 URLRequestFailedJob::URLRequestFailedJob(URLRequest
* request
,
94 NetworkDelegate
* network_delegate
,
96 : URLRequestFailedJob(request
, network_delegate
, START
, net_error
) {
99 void URLRequestFailedJob::Start() {
100 if (phase_
== START
) {
101 if (net_error_
!= ERR_IO_PENDING
) {
102 NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED
, net_error_
));
105 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING
, 0));
108 response_info_
.headers
= new net::HttpResponseHeaders("HTTP/1.1 200 OK");
109 NotifyHeadersComplete();
112 bool URLRequestFailedJob::ReadRawData(IOBuffer
* buf
,
115 CHECK(phase_
== READ_SYNC
|| phase_
== READ_ASYNC
);
116 if (net_error_
!= ERR_IO_PENDING
&& phase_
== READ_SYNC
) {
117 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED
, net_error_
));
121 SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING
, 0));
123 if (net_error_
== ERR_IO_PENDING
)
126 DCHECK_EQ(READ_ASYNC
, phase_
);
127 DCHECK_NE(ERR_IO_PENDING
, net_error_
);
129 base::ThreadTaskRunnerHandle::Get()->PostTask(
131 base::Bind(&URLRequestFailedJob::NotifyDone
, weak_factory_
.GetWeakPtr(),
132 URLRequestStatus(URLRequestStatus::FAILED
, net_error_
)));
136 int URLRequestFailedJob::GetResponseCode() const {
137 // If we have headers, get the response code from them.
138 if (response_info_
.headers
)
139 return response_info_
.headers
->response_code();
140 return URLRequestJob::GetResponseCode();
143 void URLRequestFailedJob::GetResponseInfo(HttpResponseInfo
* info
) {
144 *info
= response_info_
;
148 void URLRequestFailedJob::AddUrlHandler() {
149 return AddUrlHandlerForHostname(kMockHostname
);
153 void URLRequestFailedJob::AddUrlHandlerForHostname(
154 const std::string
& hostname
) {
155 URLRequestFilter
* filter
= URLRequestFilter::GetInstance();
156 // Add |hostname| to URLRequestFilter for HTTP and HTTPS.
157 filter
->AddHostnameInterceptor(
159 scoped_ptr
<URLRequestInterceptor
>(new MockJobInterceptor()));
160 filter
->AddHostnameInterceptor(
162 scoped_ptr
<URLRequestInterceptor
>(new MockJobInterceptor()));
166 GURL
URLRequestFailedJob::GetMockHttpUrl(int net_error
) {
167 return GetMockHttpUrlForHostname(net_error
, kMockHostname
);
171 GURL
URLRequestFailedJob::GetMockHttpsUrl(int net_error
) {
172 return GetMockHttpsUrlForHostname(net_error
, kMockHostname
);
176 GURL
URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(FailurePhase phase
,
178 return GetMockUrl("http", kMockHostname
, phase
, net_error
);
182 GURL
URLRequestFailedJob::GetMockHttpUrlForHostname(
184 const std::string
& hostname
) {
185 return GetMockUrl("http", hostname
, START
, net_error
);
189 GURL
URLRequestFailedJob::GetMockHttpsUrlForHostname(
191 const std::string
& hostname
) {
192 return GetMockUrl("https", hostname
, START
, net_error
);
195 URLRequestFailedJob::~URLRequestFailedJob() {