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 26 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {} 27 28 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {} 29 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 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 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 72 void WebURLLoaderMockFactory::UnregisterAllURLs() { 73 url_to_reponse_info_.clear(); 74 url_to_error_info_.clear(); 75 WebCache::clear(); 76 } 77 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 110 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() { 111 return last_handled_asynchronous_request_; 112 } 113 114 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL& url) { 115 return url_to_reponse_info_.find(url) != url_to_reponse_info_.end(); 116 } 117 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 124 WebURLLoader* WebURLLoaderMockFactory::CreateURLLoader( 125 WebURLLoader* default_loader) { 126 DCHECK(default_loader); 127 return new WebURLLoaderMock(this, default_loader); 128 } 129 130 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest& request, 131 WebURLResponse* response, 132 WebURLError* error, 133 WebData* data) { 134 LoadRequest(request, response, error, data); 135 } 136 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 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 169 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock* loader) { 170 LoaderToRequestMap::iterator iter = pending_loaders_.find(loader); 171 return iter != pending_loaders_.end(); 172 } 173 174 // static 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