OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "headless/lib/browser/headless_browser_context_impl.h" | 5 #include "headless/lib/browser/headless_browser_context_impl.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
| 8 #include <string> |
| 9 #include <utility> |
| 10 #include <vector> |
8 | 11 |
9 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
10 #include "base/path_service.h" | 13 #include "base/path_service.h" |
11 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
12 #include "content/public/browser/resource_context.h" | 15 #include "content/public/browser/resource_context.h" |
13 #include "content/public/browser/storage_partition.h" | 16 #include "content/public/browser/storage_partition.h" |
| 17 #include "headless/lib/browser/headless_browser_context_options.h" |
14 #include "headless/lib/browser/headless_browser_impl.h" | 18 #include "headless/lib/browser/headless_browser_impl.h" |
15 #include "headless/lib/browser/headless_url_request_context_getter.h" | 19 #include "headless/lib/browser/headless_url_request_context_getter.h" |
16 #include "headless/public/util/black_hole_protocol_handler.h" | 20 #include "headless/public/util/black_hole_protocol_handler.h" |
17 #include "headless/public/util/in_memory_protocol_handler.h" | 21 #include "headless/public/util/in_memory_protocol_handler.h" |
18 #include "net/url_request/url_request_context.h" | 22 #include "net/url_request/url_request_context.h" |
19 | 23 |
20 namespace headless { | 24 namespace headless { |
21 | 25 |
22 namespace { | 26 namespace { |
23 const char kHeadlessMojomProtocol[] = "headless-mojom"; | 27 const char kHeadlessMojomProtocol[] = "headless-mojom"; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 CHECK(url_request_context_getter_); | 70 CHECK(url_request_context_getter_); |
67 return url_request_context_getter_->GetURLRequestContext()->host_resolver(); | 71 return url_request_context_getter_->GetURLRequestContext()->host_resolver(); |
68 } | 72 } |
69 | 73 |
70 net::URLRequestContext* HeadlessResourceContext::GetRequestContext() { | 74 net::URLRequestContext* HeadlessResourceContext::GetRequestContext() { |
71 CHECK(url_request_context_getter_); | 75 CHECK(url_request_context_getter_); |
72 return url_request_context_getter_->GetURLRequestContext(); | 76 return url_request_context_getter_->GetURLRequestContext(); |
73 } | 77 } |
74 | 78 |
75 HeadlessBrowserContextImpl::HeadlessBrowserContextImpl( | 79 HeadlessBrowserContextImpl::HeadlessBrowserContextImpl( |
76 ProtocolHandlerMap protocol_handlers, | 80 HeadlessBrowserImpl* browser, |
77 HeadlessBrowser::Options* options) | 81 HeadlessBrowserContextOptions context_options) |
78 : protocol_handlers_(std::move(protocol_handlers)), | 82 : browser_(browser), |
79 options_(options), | 83 context_options_(std::move(context_options)), |
80 resource_context_(new HeadlessResourceContext) { | 84 resource_context_(new HeadlessResourceContext) { |
81 InitWhileIOAllowed(); | 85 InitWhileIOAllowed(); |
82 } | 86 } |
83 | 87 |
84 HeadlessBrowserContextImpl::~HeadlessBrowserContextImpl() { | 88 HeadlessBrowserContextImpl::~HeadlessBrowserContextImpl() { |
| 89 auto all_web_contents = GetAllWebContents(); |
| 90 for (auto* web_contents : all_web_contents) { |
| 91 web_contents->Close(); |
| 92 } |
| 93 |
85 ShutdownStoragePartitions(); | 94 ShutdownStoragePartitions(); |
| 95 |
86 if (resource_context_) { | 96 if (resource_context_) { |
87 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, | 97 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, |
88 resource_context_.release()); | 98 resource_context_.release()); |
89 } | 99 } |
90 } | 100 } |
91 | 101 |
92 // static | 102 // static |
93 HeadlessBrowserContextImpl* HeadlessBrowserContextImpl::From( | 103 HeadlessBrowserContextImpl* HeadlessBrowserContextImpl::From( |
94 HeadlessBrowserContext* browser_context) { | 104 HeadlessBrowserContext* browser_context) { |
95 return reinterpret_cast<HeadlessBrowserContextImpl*>(browser_context); | 105 return reinterpret_cast<HeadlessBrowserContextImpl*>(browser_context); |
96 } | 106 } |
97 | 107 |
| 108 HeadlessWebContents::Builder |
| 109 HeadlessBrowserContextImpl::CreateWebContentsBuilder() { |
| 110 DCHECK(browser_->BrowserMainThread()->BelongsToCurrentThread()); |
| 111 return HeadlessWebContents::Builder(this); |
| 112 } |
| 113 |
98 void HeadlessBrowserContextImpl::InitWhileIOAllowed() { | 114 void HeadlessBrowserContextImpl::InitWhileIOAllowed() { |
99 // TODO(skyostil): Allow the embedder to override this. | 115 if (!context_options_.user_data_dir().empty()) { |
100 PathService::Get(base::DIR_EXE, &path_); | 116 path_ = context_options_.user_data_dir(); |
| 117 } else { |
| 118 PathService::Get(base::DIR_EXE, &path_); |
| 119 } |
101 BrowserContext::Initialize(this, path_); | 120 BrowserContext::Initialize(this, path_); |
102 } | 121 } |
103 | 122 |
104 std::unique_ptr<content::ZoomLevelDelegate> | 123 std::unique_ptr<content::ZoomLevelDelegate> |
105 HeadlessBrowserContextImpl::CreateZoomLevelDelegate( | 124 HeadlessBrowserContextImpl::CreateZoomLevelDelegate( |
106 const base::FilePath& partition_path) { | 125 const base::FilePath& partition_path) { |
107 return std::unique_ptr<content::ZoomLevelDelegate>(); | 126 return std::unique_ptr<content::ZoomLevelDelegate>(); |
108 } | 127 } |
109 | 128 |
110 base::FilePath HeadlessBrowserContextImpl::GetPath() const { | 129 base::FilePath HeadlessBrowserContextImpl::GetPath() const { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 175 |
157 net::URLRequestContextGetter* HeadlessBrowserContextImpl::CreateRequestContext( | 176 net::URLRequestContextGetter* HeadlessBrowserContextImpl::CreateRequestContext( |
158 content::ProtocolHandlerMap* protocol_handlers, | 177 content::ProtocolHandlerMap* protocol_handlers, |
159 content::URLRequestInterceptorScopedVector request_interceptors) { | 178 content::URLRequestInterceptorScopedVector request_interceptors) { |
160 scoped_refptr<HeadlessURLRequestContextGetter> url_request_context_getter( | 179 scoped_refptr<HeadlessURLRequestContextGetter> url_request_context_getter( |
161 new HeadlessURLRequestContextGetter( | 180 new HeadlessURLRequestContextGetter( |
162 content::BrowserThread::GetTaskRunnerForThread( | 181 content::BrowserThread::GetTaskRunnerForThread( |
163 content::BrowserThread::IO), | 182 content::BrowserThread::IO), |
164 content::BrowserThread::GetTaskRunnerForThread( | 183 content::BrowserThread::GetTaskRunnerForThread( |
165 content::BrowserThread::FILE), | 184 content::BrowserThread::FILE), |
166 protocol_handlers, std::move(protocol_handlers_), | 185 protocol_handlers, context_options_.TakeProtocolHandlers(), |
167 std::move(request_interceptors), options())); | 186 std::move(request_interceptors), &context_options_)); |
168 resource_context_->set_url_request_context_getter(url_request_context_getter); | 187 resource_context_->set_url_request_context_getter(url_request_context_getter); |
169 return url_request_context_getter.get(); | 188 return url_request_context_getter.get(); |
170 } | 189 } |
171 | 190 |
172 net::URLRequestContextGetter* | 191 net::URLRequestContextGetter* |
173 HeadlessBrowserContextImpl::CreateRequestContextForStoragePartition( | 192 HeadlessBrowserContextImpl::CreateRequestContextForStoragePartition( |
174 const base::FilePath& partition_path, | 193 const base::FilePath& partition_path, |
175 bool in_memory, | 194 bool in_memory, |
176 content::ProtocolHandlerMap* protocol_handlers, | 195 content::ProtocolHandlerMap* protocol_handlers, |
177 content::URLRequestInterceptorScopedVector request_interceptors) { | 196 content::URLRequestInterceptorScopedVector request_interceptors) { |
178 return nullptr; | 197 return nullptr; |
179 } | 198 } |
180 | 199 |
181 net::URLRequestContextGetter* | 200 net::URLRequestContextGetter* |
182 HeadlessBrowserContextImpl::CreateMediaRequestContext() { | 201 HeadlessBrowserContextImpl::CreateMediaRequestContext() { |
183 return resource_context_->url_request_context_getter(); | 202 return resource_context_->url_request_context_getter(); |
184 } | 203 } |
185 | 204 |
186 net::URLRequestContextGetter* | 205 net::URLRequestContextGetter* |
187 HeadlessBrowserContextImpl::CreateMediaRequestContextForStoragePartition( | 206 HeadlessBrowserContextImpl::CreateMediaRequestContextForStoragePartition( |
188 const base::FilePath& partition_path, | 207 const base::FilePath& partition_path, |
189 bool in_memory) { | 208 bool in_memory) { |
190 return nullptr; | 209 return nullptr; |
191 } | 210 } |
192 | 211 |
193 void HeadlessBrowserContextImpl::SetOptionsForTesting( | 212 std::vector<HeadlessWebContents*> |
194 HeadlessBrowser::Options* options) { | 213 HeadlessBrowserContextImpl::GetAllWebContents() { |
195 options_ = options; | 214 std::vector<HeadlessWebContents*> result; |
| 215 |
| 216 result.reserve(web_contents_map_.size()); |
| 217 |
| 218 for (const auto& web_contents_pair : web_contents_map_) { |
| 219 result.push_back(web_contents_pair.second); |
| 220 } |
| 221 |
| 222 return result; |
| 223 } |
| 224 |
| 225 void HeadlessBrowserContextImpl::RegisterWebContents( |
| 226 HeadlessWebContentsImpl* web_contents) { |
| 227 web_contents_map_[web_contents->GetDevtoolsAgentHostId()] = web_contents; |
| 228 } |
| 229 |
| 230 void HeadlessBrowserContextImpl::UnregisterWebContents( |
| 231 HeadlessWebContentsImpl* web_contents) { |
| 232 auto it = web_contents_map_.find(web_contents->GetDevtoolsAgentHostId()); |
| 233 DCHECK(it != web_contents_map_.end()); |
| 234 web_contents_map_.erase(it); |
| 235 } |
| 236 |
| 237 HeadlessBrowserImpl* HeadlessBrowserContextImpl::browser() const { |
| 238 return browser_; |
| 239 } |
| 240 |
| 241 const HeadlessBrowserContextOptions* HeadlessBrowserContextImpl::options() |
| 242 const { |
| 243 return &context_options_; |
196 } | 244 } |
197 | 245 |
198 HeadlessBrowserContext::Builder::Builder(HeadlessBrowserImpl* browser) | 246 HeadlessBrowserContext::Builder::Builder(HeadlessBrowserImpl* browser) |
199 : browser_(browser), enable_http_and_https_if_mojo_used_(false) {} | 247 : browser_(browser), |
| 248 options_(new HeadlessBrowserContextOptions(browser->options())), |
| 249 enable_http_and_https_if_mojo_used_(false) {} |
200 | 250 |
201 HeadlessBrowserContext::Builder::~Builder() = default; | 251 HeadlessBrowserContext::Builder::~Builder() = default; |
202 | 252 |
203 HeadlessBrowserContext::Builder::Builder(Builder&&) = default; | 253 HeadlessBrowserContext::Builder::Builder(Builder&&) = default; |
204 | 254 |
205 HeadlessBrowserContext::Builder& | 255 HeadlessBrowserContext::Builder& |
206 HeadlessBrowserContext::Builder::SetProtocolHandlers( | 256 HeadlessBrowserContext::Builder::SetProtocolHandlers( |
207 ProtocolHandlerMap protocol_handlers) { | 257 ProtocolHandlerMap protocol_handlers) { |
208 protocol_handlers_ = std::move(protocol_handlers); | 258 options_->protocol_handlers_ = std::move(protocol_handlers); |
209 return *this; | 259 return *this; |
210 } | 260 } |
211 | 261 |
| 262 HeadlessBrowserContext::Builder& HeadlessBrowserContext::Builder::SetUserAgent( |
| 263 const std::string& user_agent) { |
| 264 options_->user_agent_ = user_agent; |
| 265 return *this; |
| 266 } |
| 267 |
| 268 HeadlessBrowserContext::Builder& |
| 269 HeadlessBrowserContext::Builder::SetProxyServer( |
| 270 const net::HostPortPair& proxy_server) { |
| 271 options_->proxy_server_ = proxy_server; |
| 272 return *this; |
| 273 } |
| 274 |
| 275 HeadlessBrowserContext::Builder& |
| 276 HeadlessBrowserContext::Builder::SetHostResolverRules( |
| 277 const std::string& host_resolver_rules) { |
| 278 options_->host_resolver_rules_ = host_resolver_rules; |
| 279 return *this; |
| 280 } |
| 281 |
| 282 HeadlessBrowserContext::Builder& HeadlessBrowserContext::Builder::SetWindowSize( |
| 283 const gfx::Size& window_size) { |
| 284 options_->window_size_ = window_size; |
| 285 return *this; |
| 286 } |
| 287 |
| 288 HeadlessBrowserContext::Builder& |
| 289 HeadlessBrowserContext::Builder::SetUserDataDir( |
| 290 const base::FilePath& user_data_dir) { |
| 291 options_->user_data_dir_ = user_data_dir; |
| 292 return *this; |
| 293 } |
| 294 |
212 HeadlessBrowserContext::Builder& | 295 HeadlessBrowserContext::Builder& |
213 HeadlessBrowserContext::Builder::AddJsMojoBindings( | 296 HeadlessBrowserContext::Builder::AddJsMojoBindings( |
214 const std::string& mojom_name, | 297 const std::string& mojom_name, |
215 const std::string& js_bindings) { | 298 const std::string& js_bindings) { |
216 mojo_bindings_.emplace_back(mojom_name, js_bindings); | 299 mojo_bindings_.emplace_back(mojom_name, js_bindings); |
217 return *this; | 300 return *this; |
218 } | 301 } |
219 | 302 |
220 HeadlessBrowserContext::Builder& | 303 HeadlessBrowserContext::Builder& |
221 HeadlessBrowserContext::Builder::EnableUnsafeNetworkAccessWithMojoBindings( | 304 HeadlessBrowserContext::Builder::EnableUnsafeNetworkAccessWithMojoBindings( |
222 bool enable_http_and_https_if_mojo_used) { | 305 bool enable_http_and_https_if_mojo_used) { |
223 enable_http_and_https_if_mojo_used_ = enable_http_and_https_if_mojo_used; | 306 enable_http_and_https_if_mojo_used_ = enable_http_and_https_if_mojo_used; |
224 return *this; | 307 return *this; |
225 } | 308 } |
226 | 309 |
227 std::unique_ptr<HeadlessBrowserContext> | 310 std::unique_ptr<HeadlessBrowserContext> |
228 HeadlessBrowserContext::Builder::Build() { | 311 HeadlessBrowserContext::Builder::Build() { |
229 if (!mojo_bindings_.empty()) { | 312 if (!mojo_bindings_.empty()) { |
230 std::unique_ptr<InMemoryProtocolHandler> headless_mojom_protocol_handler( | 313 std::unique_ptr<InMemoryProtocolHandler> headless_mojom_protocol_handler( |
231 new InMemoryProtocolHandler()); | 314 new InMemoryProtocolHandler()); |
232 for (const MojoBindings& binding : mojo_bindings_) { | 315 for (const MojoBindings& binding : mojo_bindings_) { |
233 headless_mojom_protocol_handler->InsertResponse( | 316 headless_mojom_protocol_handler->InsertResponse( |
234 binding.mojom_name, | 317 binding.mojom_name, |
235 InMemoryProtocolHandler::Response(binding.js_bindings, | 318 InMemoryProtocolHandler::Response(binding.js_bindings, |
236 "application/javascript")); | 319 "application/javascript")); |
237 } | 320 } |
238 DCHECK(protocol_handlers_.find(kHeadlessMojomProtocol) == | 321 DCHECK(options_->protocol_handlers_.find(kHeadlessMojomProtocol) == |
239 protocol_handlers_.end()); | 322 options_->protocol_handlers_.end()); |
240 protocol_handlers_[kHeadlessMojomProtocol] = | 323 options_->protocol_handlers_[kHeadlessMojomProtocol] = |
241 std::move(headless_mojom_protocol_handler); | 324 std::move(headless_mojom_protocol_handler); |
242 | 325 |
243 // Unless you know what you're doing it's unsafe to allow http/https for a | 326 // Unless you know what you're doing it's unsafe to allow http/https for a |
244 // context with mojo bindings. | 327 // context with mojo bindings. |
245 if (!enable_http_and_https_if_mojo_used_) { | 328 if (!enable_http_and_https_if_mojo_used_) { |
246 protocol_handlers_[url::kHttpScheme] = | 329 options_->protocol_handlers_[url::kHttpScheme] = |
247 base::WrapUnique(new BlackHoleProtocolHandler()); | 330 base::WrapUnique(new BlackHoleProtocolHandler()); |
248 protocol_handlers_[url::kHttpsScheme] = | 331 options_->protocol_handlers_[url::kHttpsScheme] = |
249 base::WrapUnique(new BlackHoleProtocolHandler()); | 332 base::WrapUnique(new BlackHoleProtocolHandler()); |
250 } | 333 } |
251 } | 334 } |
252 | 335 |
253 return base::WrapUnique(new HeadlessBrowserContextImpl( | 336 return base::WrapUnique( |
254 std::move(protocol_handlers_), browser_->options())); | 337 new HeadlessBrowserContextImpl(browser_, std::move(*options_))); |
255 } | 338 } |
256 | 339 |
257 HeadlessBrowserContext::Builder::MojoBindings::MojoBindings() {} | 340 HeadlessBrowserContext::Builder::MojoBindings::MojoBindings() {} |
258 | 341 |
259 HeadlessBrowserContext::Builder::MojoBindings::MojoBindings( | 342 HeadlessBrowserContext::Builder::MojoBindings::MojoBindings( |
260 const std::string& mojom_name, | 343 const std::string& mojom_name, |
261 const std::string& js_bindings) | 344 const std::string& js_bindings) |
262 : mojom_name(mojom_name), js_bindings(js_bindings) {} | 345 : mojom_name(mojom_name), js_bindings(js_bindings) {} |
263 | 346 |
264 HeadlessBrowserContext::Builder::MojoBindings::~MojoBindings() {} | 347 HeadlessBrowserContext::Builder::MojoBindings::~MojoBindings() {} |
265 | 348 |
266 } // namespace headless | 349 } // namespace headless |
OLD | NEW |