• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/test/weburl_loader_mock_factory.h"
6 
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"
16 
17 using blink::WebCache;
18 using blink::WebData;
19 using blink::WebString;
20 using blink::WebURL;
21 using blink::WebURLError;
22 using blink::WebURLLoader;
23 using blink::WebURLRequest;
24 using blink::WebURLResponse;
25 
WebURLLoaderMockFactory()26 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {}
27 
~WebURLLoaderMockFactory()28 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {}
29 
RegisterURL(const WebURL & url,const WebURLResponse & response,const WebString & file_path)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()) {
36 #if defined(OS_POSIX)
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()));
40 #elif defined(OS_WIN)
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()));
44 #endif
45     DCHECK(base::PathExists(response_info.file_path))
46         << response_info.file_path.MaybeAsASCII() << " does not exist.";
47   }
48 
49   DCHECK(url_to_reponse_info_.find(url) == url_to_reponse_info_.end());
50   url_to_reponse_info_[url] = response_info;
51 }
52 
53 
RegisterErrorURL(const WebURL & url,const WebURLResponse & response,const WebURLError & error)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;
60 }
61 
UnregisterURL(const blink::WebURL & url)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);
66 
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);
70 }
71 
UnregisterAllURLs()72 void WebURLLoaderMockFactory::UnregisterAllURLs() {
73   url_to_reponse_info_.clear();
74   url_to_error_info_.clear();
75   WebCache::clear();
76 }
77 
ServeAsynchronousRequests()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;
87     WebURLError error;
88     WebData data;
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())
96         break;
97       last_handled_asynchronous_request_ = newRequest;
98       LoadRequest(newRequest, &response, &error, &data);
99     }
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);
105   }
106   base::RunLoop().RunUntilIdle();
107 }
108 
109 blink::WebURLRequest
GetLastHandledAsynchronousRequest()110 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() {
111   return last_handled_asynchronous_request_;
112 }
113 
IsMockedURL(const blink::WebURL & url)114 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL& url) {
115   return url_to_reponse_info_.find(url) != url_to_reponse_info_.end();
116 }
117 
CancelLoad(WebURLLoaderMock * loader)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);
122 }
123 
CreateURLLoader(WebURLLoader * default_loader)124 WebURLLoader* WebURLLoaderMockFactory::CreateURLLoader(
125     WebURLLoader* default_loader) {
126   DCHECK(default_loader);
127   return new WebURLLoaderMock(this, default_loader);
128 }
129 
LoadSynchronously(const WebURLRequest & request,WebURLResponse * response,WebURLError * error,WebData * data)130 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest& request,
131                                                 WebURLResponse* response,
132                                                 WebURLError* error,
133                                                 WebData* data) {
134   LoadRequest(request, response, error, data);
135 }
136 
LoadAsynchronouly(const WebURLRequest & request,WebURLLoaderMock * loader)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;
142 }
143 
LoadRequest(const WebURLRequest & request,WebURLResponse * response,WebURLError * error,WebData * data)144 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest& request,
145                                           WebURLResponse* response,
146                                           WebURLError* error,
147                                           WebData* data) {
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;
152 
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.
157     NOTREACHED();
158     return;
159   }
160 
161   if (!error->reason && !ReadFile(iter->second.file_path, data)) {
162     NOTREACHED();
163     return;
164   }
165 
166   *response = iter->second.response;
167 }
168 
IsPending(WebURLLoaderMock * loader)169 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock* loader) {
170   LoaderToRequestMap::iterator iter = pending_loaders_.find(loader);
171   return iter != pending_loaders_.end();
172 }
173 
174 // static
ReadFile(const base::FilePath & file_path,WebData * data)175 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath& file_path,
176                                        WebData* data) {
177   int64 file_size = 0;
178   if (!base::GetFileSize(file_path, &file_size))
179     return false;
180 
181   int size = static_cast<int>(file_size);
182   scoped_ptr<char[]> buffer(new char[size]);
183   data->reset();
184   int read_count = base::ReadFile(file_path, buffer.get(), size);
185   if (read_count == -1)
186     return false;
187   DCHECK(read_count == size);
188   data->assign(buffer.get(), size);
189 
190   return true;
191 }
192