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/file_util.h" 8 #include "base/logging.h" 9 #include "base/run_loop.h" 10 #include "content/test/webkit_support.h" 11 #include "content/test/weburl_loader_mock.h" 12 #include "third_party/WebKit/public/platform/WebString.h" 13 #include "third_party/WebKit/public/platform/WebURLError.h" 14 #include "third_party/WebKit/public/platform/WebURLRequest.h" 15 #include "third_party/WebKit/public/platform/WebURLResponse.h" 16 #include "third_party/WebKit/public/web/WebCache.h" 17 18 using blink::WebCache; 19 using blink::WebData; 20 using blink::WebString; 21 using blink::WebURL; 22 using blink::WebURLError; 23 using blink::WebURLLoader; 24 using blink::WebURLRequest; 25 using blink::WebURLResponse; 26 27 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {} 28 29 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {} 30 31 void WebURLLoaderMockFactory::RegisterURL(const WebURL& url, 32 const WebURLResponse& response, 33 const WebString& file_path) { 34 ResponseInfo response_info; 35 response_info.response = response; 36 if (!file_path.isNull() && !file_path.isEmpty()) { 37 #if defined(OS_POSIX) 38 // TODO(jcivelli): On Linux, UTF8 might not be correct. 39 response_info.file_path = 40 base::FilePath(static_cast<std::string>(file_path.utf8())); 41 #elif defined(OS_WIN) 42 base::string16 file_path_16 = file_path; 43 response_info.file_path = base::FilePath(std::wstring( 44 file_path_16.data(), file_path_16.length())); 45 #endif 46 DCHECK(base::PathExists(response_info.file_path)) 47 << response_info.file_path.MaybeAsASCII() << " does not exist."; 48 } 49 50 DCHECK(url_to_reponse_info_.find(url) == url_to_reponse_info_.end()); 51 url_to_reponse_info_[url] = response_info; 52 } 53 54 55 void WebURLLoaderMockFactory::RegisterErrorURL(const WebURL& url, 56 const WebURLResponse& response, 57 const WebURLError& error) { 58 DCHECK(url_to_reponse_info_.find(url) == url_to_reponse_info_.end()); 59 RegisterURL(url, response, WebString()); 60 url_to_error_info_[url] = error; 61 } 62 63 void WebURLLoaderMockFactory::UnregisterURL(const blink::WebURL& url) { 64 URLToResponseMap::iterator iter = url_to_reponse_info_.find(url); 65 DCHECK(iter != url_to_reponse_info_.end()); 66 url_to_reponse_info_.erase(iter); 67 68 URLToErrorMap::iterator error_iter = url_to_error_info_.find(url); 69 if (error_iter != url_to_error_info_.end()) 70 url_to_error_info_.erase(error_iter); 71 } 72 73 void WebURLLoaderMockFactory::UnregisterAllURLs() { 74 url_to_reponse_info_.clear(); 75 url_to_error_info_.clear(); 76 WebCache::clear(); 77 } 78 79 void WebURLLoaderMockFactory::ServeAsynchronousRequests() { 80 last_handled_asynchronous_request_.reset(); 81 // Serving a request might trigger more requests, so we cannot iterate on 82 // pending_loaders_ as it might get modified. 83 while (!pending_loaders_.empty()) { 84 LoaderToRequestMap::iterator iter = pending_loaders_.begin(); 85 WebURLLoaderMock* loader = iter->first; 86 const WebURLRequest& request = iter->second; 87 WebURLResponse response; 88 WebURLError error; 89 WebData data; 90 last_handled_asynchronous_request_ = request; 91 LoadRequest(request, &response, &error, &data); 92 // Follow any redirects while the loader is still active. 93 while (response.httpStatusCode() >= 300 && 94 response.httpStatusCode() < 400) { 95 WebURLRequest newRequest = loader->ServeRedirect(response); 96 if (!IsPending(loader) || loader->isDeferred()) 97 break; 98 last_handled_asynchronous_request_ = newRequest; 99 LoadRequest(newRequest, &response, &error, &data); 100 } 101 // Serve the request if the loader is still active. 102 if (IsPending(loader) && !loader->isDeferred()) 103 loader->ServeAsynchronousRequest(response, data, error); 104 // The loader might have already been removed. 105 pending_loaders_.erase(loader); 106 } 107 base::RunLoop().RunUntilIdle(); 108 } 109 110 blink::WebURLRequest 111 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() { 112 return last_handled_asynchronous_request_; 113 } 114 115 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL& url) { 116 return url_to_reponse_info_.find(url) != url_to_reponse_info_.end(); 117 } 118 119 void WebURLLoaderMockFactory::CancelLoad(WebURLLoaderMock* loader) { 120 LoaderToRequestMap::iterator iter = pending_loaders_.find(loader); 121 DCHECK(iter != pending_loaders_.end()); 122 pending_loaders_.erase(iter); 123 } 124 125 WebURLLoader* WebURLLoaderMockFactory::CreateURLLoader( 126 WebURLLoader* default_loader) { 127 DCHECK(default_loader); 128 return new WebURLLoaderMock(this, default_loader); 129 } 130 131 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest& request, 132 WebURLResponse* response, 133 WebURLError* error, 134 WebData* data) { 135 LoadRequest(request, response, error, data); 136 } 137 138 void WebURLLoaderMockFactory::LoadAsynchronouly(const WebURLRequest& request, 139 WebURLLoaderMock* loader) { 140 LoaderToRequestMap::iterator iter = pending_loaders_.find(loader); 141 DCHECK(iter == pending_loaders_.end()); 142 pending_loaders_[loader] = request; 143 } 144 145 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest& request, 146 WebURLResponse* response, 147 WebURLError* error, 148 WebData* data) { 149 URLToErrorMap::const_iterator error_iter = 150 url_to_error_info_.find(request.url()); 151 if (error_iter != url_to_error_info_.end()) 152 *error = error_iter->second; 153 154 URLToResponseMap::const_iterator iter = 155 url_to_reponse_info_.find(request.url()); 156 if (iter == url_to_reponse_info_.end()) { 157 // Non mocked URLs should not have been passed to the default URLLoader. 158 NOTREACHED(); 159 return; 160 } 161 162 if (!error->reason && !ReadFile(iter->second.file_path, data)) { 163 NOTREACHED(); 164 return; 165 } 166 167 *response = iter->second.response; 168 } 169 170 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock* loader) { 171 LoaderToRequestMap::iterator iter = pending_loaders_.find(loader); 172 return iter != pending_loaders_.end(); 173 } 174 175 // static 176 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath& file_path, 177 WebData* data) { 178 int64 file_size = 0; 179 if (!base::GetFileSize(file_path, &file_size)) 180 return false; 181 182 int size = static_cast<int>(file_size); 183 scoped_ptr<char[]> buffer(new char[size]); 184 data->reset(); 185 int read_count = base::ReadFile(file_path, buffer.get(), size); 186 if (read_count == -1) 187 return false; 188 DCHECK(read_count == size); 189 data->assign(buffer.get(), size); 190 191 return true; 192 } 193