1 // Copyright 2013 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 "content/test/weburl_loader_mock_factory.h"
7 #include "base/files/file_util.h"
8 #include "base/logging.h"
9 #include "base/run_loop.h"
10 #include "content/test/weburl_loader_mock.h"
11 #include "third_party/WebKit/public/platform/WebString.h"
12 #include "third_party/WebKit/public/platform/WebURLError.h"
13 #include "third_party/WebKit/public/platform/WebURLRequest.h"
14 #include "third_party/WebKit/public/platform/WebURLResponse.h"
15 #include "third_party/WebKit/public/web/WebCache.h"
17 using blink::WebCache
;
19 using blink::WebString
;
21 using blink::WebURLError
;
22 using blink::WebURLLoader
;
23 using blink::WebURLRequest
;
24 using blink::WebURLResponse
;
26 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {}
28 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {}
30 void WebURLLoaderMockFactory::RegisterURL(const WebURL
& url
,
31 const WebURLResponse
& response
,
32 const WebString
& file_path
) {
33 ResponseInfo response_info
;
34 response_info
.response
= response
;
35 if (!file_path
.isNull() && !file_path
.isEmpty()) {
37 // TODO(jcivelli): On Linux, UTF8 might not be correct.
38 response_info
.file_path
=
39 base::FilePath(static_cast<std::string
>(file_path
.utf8()));
41 base::string16 file_path_16
= file_path
;
42 response_info
.file_path
= base::FilePath(std::wstring(
43 file_path_16
.data(), file_path_16
.length()));
45 DCHECK(base::PathExists(response_info
.file_path
))
46 << response_info
.file_path
.MaybeAsASCII() << " does not exist.";
49 DCHECK(url_to_reponse_info_
.find(url
) == url_to_reponse_info_
.end());
50 url_to_reponse_info_
[url
] = response_info
;
54 void WebURLLoaderMockFactory::RegisterErrorURL(const WebURL
& url
,
55 const WebURLResponse
& response
,
56 const WebURLError
& error
) {
57 DCHECK(url_to_reponse_info_
.find(url
) == url_to_reponse_info_
.end());
58 RegisterURL(url
, response
, WebString());
59 url_to_error_info_
[url
] = error
;
62 void WebURLLoaderMockFactory::UnregisterURL(const blink::WebURL
& url
) {
63 URLToResponseMap::iterator iter
= url_to_reponse_info_
.find(url
);
64 DCHECK(iter
!= url_to_reponse_info_
.end());
65 url_to_reponse_info_
.erase(iter
);
67 URLToErrorMap::iterator error_iter
= url_to_error_info_
.find(url
);
68 if (error_iter
!= url_to_error_info_
.end())
69 url_to_error_info_
.erase(error_iter
);
72 void WebURLLoaderMockFactory::UnregisterAllURLs() {
73 url_to_reponse_info_
.clear();
74 url_to_error_info_
.clear();
78 void WebURLLoaderMockFactory::ServeAsynchronousRequests() {
79 last_handled_asynchronous_request_
.reset();
80 // Serving a request might trigger more requests, so we cannot iterate on
81 // pending_loaders_ as it might get modified.
82 while (!pending_loaders_
.empty()) {
83 LoaderToRequestMap::iterator iter
= pending_loaders_
.begin();
84 WebURLLoaderMock
* loader
= iter
->first
;
85 const WebURLRequest
& request
= iter
->second
;
86 WebURLResponse response
;
89 last_handled_asynchronous_request_
= request
;
90 LoadRequest(request
, &response
, &error
, &data
);
91 // Follow any redirects while the loader is still active.
92 while (response
.httpStatusCode() >= 300 &&
93 response
.httpStatusCode() < 400) {
94 WebURLRequest newRequest
= loader
->ServeRedirect(response
);
95 if (!IsPending(loader
) || loader
->isDeferred())
97 last_handled_asynchronous_request_
= newRequest
;
98 LoadRequest(newRequest
, &response
, &error
, &data
);
100 // Serve the request if the loader is still active.
101 if (IsPending(loader
) && !loader
->isDeferred())
102 loader
->ServeAsynchronousRequest(response
, data
, error
);
103 // The loader might have already been removed.
104 pending_loaders_
.erase(loader
);
106 base::RunLoop().RunUntilIdle();
110 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() {
111 return last_handled_asynchronous_request_
;
114 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL
& url
) {
115 return url_to_reponse_info_
.find(url
) != url_to_reponse_info_
.end();
118 void WebURLLoaderMockFactory::CancelLoad(WebURLLoaderMock
* loader
) {
119 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
120 DCHECK(iter
!= pending_loaders_
.end());
121 pending_loaders_
.erase(iter
);
124 WebURLLoader
* WebURLLoaderMockFactory::CreateURLLoader(
125 WebURLLoader
* default_loader
) {
126 DCHECK(default_loader
);
127 return new WebURLLoaderMock(this, default_loader
);
130 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest
& request
,
131 WebURLResponse
* response
,
134 LoadRequest(request
, response
, error
, data
);
137 void WebURLLoaderMockFactory::LoadAsynchronouly(const WebURLRequest
& request
,
138 WebURLLoaderMock
* loader
) {
139 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
140 DCHECK(iter
== pending_loaders_
.end());
141 pending_loaders_
[loader
] = request
;
144 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest
& request
,
145 WebURLResponse
* response
,
148 URLToErrorMap::const_iterator error_iter
=
149 url_to_error_info_
.find(request
.url());
150 if (error_iter
!= url_to_error_info_
.end())
151 *error
= error_iter
->second
;
153 URLToResponseMap::const_iterator iter
=
154 url_to_reponse_info_
.find(request
.url());
155 if (iter
== url_to_reponse_info_
.end()) {
156 // Non mocked URLs should not have been passed to the default URLLoader.
161 if (!error
->reason
&& !ReadFile(iter
->second
.file_path
, data
)) {
166 *response
= iter
->second
.response
;
169 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock
* loader
) {
170 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
171 return iter
!= pending_loaders_
.end();
175 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath
& file_path
,
178 if (!base::GetFileSize(file_path
, &file_size
))
181 int size
= static_cast<int>(file_size
);
182 scoped_ptr
<char[]> buffer(new char[size
]);
184 int read_count
= base::ReadFile(file_path
, buffer
.get(), size
);
185 if (read_count
== -1)
187 DCHECK(read_count
== size
);
188 data
->assign(buffer
.get(), size
);