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 "webkit/support/weburl_loader_mock_factory.h"
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
10 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h"
11 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h"
12 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h"
13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h"
14 #include "webkit/support/webkit_support.h"
15 #include "webkit/support/weburl_loader_mock.h"
17 using WebKit::WebCache
;
18 using WebKit::WebData
;
19 using WebKit::WebString
;
21 using WebKit::WebURLError
;
22 using WebKit::WebURLLoader
;
23 using WebKit::WebURLRequest
;
24 using WebKit::WebURLResponse
;
26 struct WebURLLoaderMockFactory::ResponseInfo
{
27 WebKit::WebURLResponse response
;
28 base::FilePath file_path
;
31 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {}
33 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {}
35 void WebURLLoaderMockFactory::RegisterURL(const WebURL
& url
,
36 const WebURLResponse
& response
,
37 const WebString
& file_path
) {
38 ResponseInfo response_info
;
39 response_info
.response
= response
;
40 if (!file_path
.isNull() && !file_path
.isEmpty()) {
42 // TODO(jcivelli): On Linux, UTF8 might not be correct.
43 response_info
.file_path
=
44 base::FilePath(static_cast<std::string
>(file_path
.utf8()));
46 response_info
.file_path
=
47 base::FilePath(std::wstring(file_path
.data(), file_path
.length()));
49 DCHECK(file_util::PathExists(response_info
.file_path
))
50 << response_info
.file_path
.MaybeAsASCII() << " does not exist.";
53 DCHECK(url_to_reponse_info_
.find(url
) == url_to_reponse_info_
.end());
54 url_to_reponse_info_
[url
] = response_info
;
58 void WebURLLoaderMockFactory::RegisterErrorURL(const WebURL
& url
,
59 const WebURLResponse
& response
,
60 const WebURLError
& error
) {
61 DCHECK(url_to_reponse_info_
.find(url
) == url_to_reponse_info_
.end());
62 RegisterURL(url
, response
, WebString());
63 url_to_error_info_
[url
] = error
;
66 void WebURLLoaderMockFactory::UnregisterURL(const WebKit::WebURL
& url
) {
67 URLToResponseMap::iterator iter
= url_to_reponse_info_
.find(url
);
68 DCHECK(iter
!= url_to_reponse_info_
.end());
69 url_to_reponse_info_
.erase(iter
);
71 URLToErrorMap::iterator error_iter
= url_to_error_info_
.find(url
);
72 if (error_iter
!= url_to_error_info_
.end())
73 url_to_error_info_
.erase(error_iter
);
76 void WebURLLoaderMockFactory::UnregisterAllURLs() {
77 url_to_reponse_info_
.clear();
78 url_to_error_info_
.clear();
82 void WebURLLoaderMockFactory::ServeAsynchronousRequests() {
83 last_handled_asynchronous_request_
.reset();
84 // Serving a request might trigger more requests, so we cannot iterate on
85 // pending_loaders_ as it might get modified.
86 while (!pending_loaders_
.empty()) {
87 LoaderToRequestMap::iterator iter
= pending_loaders_
.begin();
88 WebURLLoaderMock
* loader
= iter
->first
;
89 const WebURLRequest
& request
= iter
->second
;
90 WebURLResponse response
;
93 last_handled_asynchronous_request_
= request
;
94 LoadRequest(request
, &response
, &error
, &data
);
95 // Follow any redirects while the loader is still active.
96 while (response
.httpStatusCode() >= 300 &&
97 response
.httpStatusCode() < 400) {
98 WebURLRequest newRequest
= loader
->ServeRedirect(response
);
99 if (!IsPending(loader
) || loader
->isDeferred())
101 last_handled_asynchronous_request_
= newRequest
;
102 LoadRequest(newRequest
, &response
, &error
, &data
);
104 // Serve the request if the loader is still active.
105 if (IsPending(loader
) && !loader
->isDeferred())
106 loader
->ServeAsynchronousRequest(response
, data
, error
);
107 // The loader might have already been removed.
108 pending_loaders_
.erase(loader
);
110 webkit_support::RunAllPendingMessages();
113 WebKit::WebURLRequest
114 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() {
115 return last_handled_asynchronous_request_
;
118 bool WebURLLoaderMockFactory::IsMockedURL(const WebKit::WebURL
& url
) {
119 return url_to_reponse_info_
.find(url
) != url_to_reponse_info_
.end();
122 void WebURLLoaderMockFactory::CancelLoad(WebURLLoaderMock
* loader
) {
123 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
124 DCHECK(iter
!= pending_loaders_
.end());
125 pending_loaders_
.erase(iter
);
128 WebURLLoader
* WebURLLoaderMockFactory::CreateURLLoader(
129 WebURLLoader
* default_loader
) {
130 DCHECK(default_loader
);
131 return new WebURLLoaderMock(this, default_loader
);
134 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest
& request
,
135 WebURLResponse
* response
,
138 LoadRequest(request
, response
, error
, data
);
141 void WebURLLoaderMockFactory::LoadAsynchronouly(const WebURLRequest
& request
,
142 WebURLLoaderMock
* loader
) {
143 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
144 DCHECK(iter
== pending_loaders_
.end());
145 pending_loaders_
[loader
] = request
;
148 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest
& request
,
149 WebURLResponse
* response
,
152 URLToErrorMap::const_iterator error_iter
=
153 url_to_error_info_
.find(request
.url());
154 if (error_iter
!= url_to_error_info_
.end())
155 *error
= error_iter
->second
;
157 URLToResponseMap::const_iterator iter
=
158 url_to_reponse_info_
.find(request
.url());
159 if (iter
== url_to_reponse_info_
.end()) {
160 // Non mocked URLs should not have been passed to the default URLLoader.
165 if (!error
->reason
&& !ReadFile(iter
->second
.file_path
, data
)) {
170 *response
= iter
->second
.response
;
173 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock
* loader
) {
174 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
175 return iter
!= pending_loaders_
.end();
179 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath
& file_path
,
182 if (!file_util::GetFileSize(file_path
, &file_size
))
185 int size
= static_cast<int>(file_size
);
186 scoped_ptr
<char[]> buffer(new char[size
]);
188 int read_count
= file_util::ReadFile(file_path
, buffer
.get(), size
);
189 if (read_count
== -1)
191 DCHECK(read_count
== size
);
192 data
->assign(buffer
.get(), size
);