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() : delegate_(nullptr) {}
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 // Serving a request might trigger more requests, so we cannot iterate on
80 // pending_loaders_ as it might get modified.
81 while (!pending_loaders_
.empty()) {
82 LoaderToRequestMap::iterator iter
= pending_loaders_
.begin();
83 WebURLLoaderMock
* loader
= iter
->first
;
84 const WebURLRequest
& request
= iter
->second
;
85 WebURLResponse response
;
88 LoadRequest(request
, &response
, &error
, &data
);
89 // Follow any redirects while the loader is still active.
90 while (response
.httpStatusCode() >= 300 &&
91 response
.httpStatusCode() < 400) {
92 WebURLRequest newRequest
= loader
->ServeRedirect(response
);
93 if (!IsPending(loader
) || loader
->isDeferred())
95 LoadRequest(newRequest
, &response
, &error
, &data
);
97 // Serve the request if the loader is still active.
98 if (IsPending(loader
) && !loader
->isDeferred())
99 loader
->ServeAsynchronousRequest(delegate_
, response
, data
, error
);
100 // The loader might have already been removed.
101 pending_loaders_
.erase(loader
);
103 base::RunLoop().RunUntilIdle();
106 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL
& url
) {
107 return url_to_reponse_info_
.find(url
) != url_to_reponse_info_
.end();
110 void WebURLLoaderMockFactory::CancelLoad(WebURLLoaderMock
* loader
) {
111 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
112 DCHECK(iter
!= pending_loaders_
.end());
113 pending_loaders_
.erase(iter
);
116 WebURLLoader
* WebURLLoaderMockFactory::CreateURLLoader(
117 WebURLLoader
* default_loader
) {
118 DCHECK(default_loader
);
119 return new WebURLLoaderMock(this, default_loader
);
122 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest
& request
,
123 WebURLResponse
* response
,
126 LoadRequest(request
, response
, error
, data
);
129 void WebURLLoaderMockFactory::LoadAsynchronouly(const WebURLRequest
& request
,
130 WebURLLoaderMock
* loader
) {
131 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
132 DCHECK(iter
== pending_loaders_
.end());
133 pending_loaders_
[loader
] = request
;
136 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest
& request
,
137 WebURLResponse
* response
,
140 URLToErrorMap::const_iterator error_iter
=
141 url_to_error_info_
.find(request
.url());
142 if (error_iter
!= url_to_error_info_
.end())
143 *error
= error_iter
->second
;
145 URLToResponseMap::const_iterator iter
=
146 url_to_reponse_info_
.find(request
.url());
147 if (iter
== url_to_reponse_info_
.end()) {
148 // Non mocked URLs should not have been passed to the default URLLoader.
153 if (!error
->reason
&& !ReadFile(iter
->second
.file_path
, data
)) {
158 *response
= iter
->second
.response
;
161 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock
* loader
) {
162 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
163 return iter
!= pending_loaders_
.end();
167 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath
& file_path
,
170 if (!base::GetFileSize(file_path
, &file_size
))
173 int size
= static_cast<int>(file_size
);
174 scoped_ptr
<char[]> buffer(new char[size
]);
176 int read_count
= base::ReadFile(file_path
, buffer
.get(), size
);
177 if (read_count
== -1)
179 DCHECK(read_count
== size
);
180 data
->assign(buffer
.get(), size
);