OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
19 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
22 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
23 #include "base/values.h" | 23 #include "base/values.h" |
24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
25 #include "components/devtools_http_handler/devtools_http_handler.h" | 25 #include "components/devtools_http_handler/devtools_http_handler.h" |
26 #include "components/devtools_http_handler/devtools_http_handler_delegate.h" | 26 #include "components/devtools_http_handler/devtools_http_handler_delegate.h" |
27 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
28 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 28 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
29 #include "content/public/browser/devtools_manager_delegate.h" | 29 #include "content/public/browser/devtools_manager_delegate.h" |
| 30 #include "content/public/browser/devtools_socket_factory.h" |
30 #include "content/public/common/url_constants.h" | 31 #include "content/public/common/url_constants.h" |
31 #include "content/public/common/user_agent.h" | 32 #include "content/public/common/user_agent.h" |
32 #include "net/base/escape.h" | 33 #include "net/base/escape.h" |
33 #include "net/base/io_buffer.h" | 34 #include "net/base/io_buffer.h" |
34 #include "net/base/ip_endpoint.h" | 35 #include "net/base/ip_endpoint.h" |
35 #include "net/base/net_errors.h" | 36 #include "net/base/net_errors.h" |
36 #include "net/server/http_server.h" | 37 #include "net/server/http_server.h" |
37 #include "net/server/http_server_request_info.h" | 38 #include "net/server/http_server_request_info.h" |
38 #include "net/server/http_server_response_info.h" | 39 #include "net/server/http_server_response_info.h" |
39 #include "net/socket/server_socket.h" | 40 #include "net/socket/server_socket.h" |
40 | 41 |
41 #if defined(OS_ANDROID) | 42 #if defined(OS_ANDROID) |
42 #include "base/android/build_info.h" | 43 #include "base/android/build_info.h" |
43 #endif | 44 #endif |
44 | 45 |
45 using content::BrowserThread; | 46 using content::BrowserThread; |
46 using content::DevToolsAgentHost; | 47 using content::DevToolsAgentHost; |
47 using content::DevToolsAgentHostClient; | 48 using content::DevToolsAgentHostClient; |
48 | 49 |
49 namespace devtools_http_handler { | 50 namespace devtools_http_handler { |
50 | 51 |
51 namespace { | 52 namespace { |
52 | 53 |
53 const base::FilePath::CharType kDevToolsActivePortFileName[] = | 54 const base::FilePath::CharType kDevToolsActivePortFileName[] = |
54 FILE_PATH_LITERAL("DevToolsActivePort"); | 55 FILE_PATH_LITERAL("DevToolsActivePort"); |
55 | 56 |
56 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 57 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
57 | 58 |
58 const char kThumbUrlPrefix[] = "/thumb/"; | |
59 const char kPageUrlPrefix[] = "/devtools/page/"; | 59 const char kPageUrlPrefix[] = "/devtools/page/"; |
60 | 60 |
61 const char kTargetIdField[] = "id"; | 61 const char kTargetIdField[] = "id"; |
62 const char kTargetParentIdField[] = "parentId"; | 62 const char kTargetParentIdField[] = "parentId"; |
63 const char kTargetTypeField[] = "type"; | 63 const char kTargetTypeField[] = "type"; |
64 const char kTargetTitleField[] = "title"; | 64 const char kTargetTitleField[] = "title"; |
65 const char kTargetDescriptionField[] = "description"; | 65 const char kTargetDescriptionField[] = "description"; |
66 const char kTargetUrlField[] = "url"; | 66 const char kTargetUrlField[] = "url"; |
67 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | |
68 const char kTargetFaviconUrlField[] = "faviconUrl"; | 67 const char kTargetFaviconUrlField[] = "faviconUrl"; |
69 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 68 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
70 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 69 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
71 | 70 |
72 // Maximum write buffer size of devtools http/websocket connections. | 71 // Maximum write buffer size of devtools http/websocket connections. |
73 // TODO(rmcilroy/pfieldman): Reduce this back to 100Mb when we have | 72 // TODO(rmcilroy/pfieldman): Reduce this back to 100Mb when we have |
74 // added back pressure on the TraceComplete message protocol - crbug.com/456845. | 73 // added back pressure on the TraceComplete message protocol - crbug.com/456845. |
75 const int32_t kSendBufferSizeForDevTools = 256 * 1024 * 1024; // 256Mb | 74 const int32_t kSendBufferSizeForDevTools = 256 * 1024 * 1024; // 256Mb |
76 | 75 |
77 } // namespace | 76 } // namespace |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 164 } |
166 | 165 |
167 void ServerWrapper::Close(int connection_id) { | 166 void ServerWrapper::Close(int connection_id) { |
168 server_->Close(connection_id); | 167 server_->Close(connection_id); |
169 } | 168 } |
170 | 169 |
171 // Thread and ServerWrapper lifetime management ------------------------------ | 170 // Thread and ServerWrapper lifetime management ------------------------------ |
172 | 171 |
173 void TerminateOnUI(base::Thread* thread, | 172 void TerminateOnUI(base::Thread* thread, |
174 ServerWrapper* server_wrapper, | 173 ServerWrapper* server_wrapper, |
175 DevToolsHttpHandler::ServerSocketFactory* socket_factory) { | 174 content::DevToolsSocketFactory* socket_factory) { |
176 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 175 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
177 if (server_wrapper) { | 176 if (server_wrapper) { |
178 DCHECK(thread); | 177 DCHECK(thread); |
179 thread->task_runner()->DeleteSoon(FROM_HERE, server_wrapper); | 178 thread->task_runner()->DeleteSoon(FROM_HERE, server_wrapper); |
180 } | 179 } |
181 if (socket_factory) { | 180 if (socket_factory) { |
182 DCHECK(thread); | 181 DCHECK(thread); |
183 thread->task_runner()->DeleteSoon(FROM_HERE, socket_factory); | 182 thread->task_runner()->DeleteSoon(FROM_HERE, socket_factory); |
184 } | 183 } |
185 if (thread) { | 184 if (thread) { |
186 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, thread); | 185 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, thread); |
187 } | 186 } |
188 } | 187 } |
189 | 188 |
190 void ServerStartedOnUI(base::WeakPtr<DevToolsHttpHandler> handler, | 189 void ServerStartedOnUI(base::WeakPtr<DevToolsHttpHandler> handler, |
191 base::Thread* thread, | 190 base::Thread* thread, |
192 ServerWrapper* server_wrapper, | 191 ServerWrapper* server_wrapper, |
193 DevToolsHttpHandler::ServerSocketFactory* socket_factory, | 192 content::DevToolsSocketFactory* socket_factory, |
194 std::unique_ptr<net::IPEndPoint> ip_address) { | 193 std::unique_ptr<net::IPEndPoint> ip_address) { |
195 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 194 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
196 if (handler && thread && server_wrapper) { | 195 if (handler && thread && server_wrapper) { |
197 handler->ServerStarted(thread, server_wrapper, socket_factory, | 196 handler->ServerStarted(thread, server_wrapper, socket_factory, |
198 std::move(ip_address)); | 197 std::move(ip_address)); |
199 } else { | 198 } else { |
200 TerminateOnUI(thread, server_wrapper, socket_factory); | 199 TerminateOnUI(thread, server_wrapper, socket_factory); |
201 } | 200 } |
202 } | 201 } |
203 | 202 |
204 void StartServerOnHandlerThread( | 203 void StartServerOnHandlerThread( |
205 base::WeakPtr<DevToolsHttpHandler> handler, | 204 base::WeakPtr<DevToolsHttpHandler> handler, |
206 base::Thread* thread, | 205 base::Thread* thread, |
207 DevToolsHttpHandler::ServerSocketFactory* server_socket_factory, | 206 content::DevToolsSocketFactory* socket_factory, |
208 const base::FilePath& output_directory, | 207 const base::FilePath& output_directory, |
209 const base::FilePath& frontend_dir, | 208 const base::FilePath& frontend_dir, |
210 bool bundles_resources) { | 209 bool bundles_resources) { |
211 DCHECK(thread->task_runner()->BelongsToCurrentThread()); | 210 DCHECK(thread->task_runner()->BelongsToCurrentThread()); |
212 ServerWrapper* server_wrapper = nullptr; | 211 ServerWrapper* server_wrapper = nullptr; |
213 std::unique_ptr<net::ServerSocket> server_socket = | 212 std::unique_ptr<net::ServerSocket> server_socket = |
214 server_socket_factory->CreateForHttpServer(); | 213 socket_factory->CreateForHttpServer(); |
215 std::unique_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); | 214 std::unique_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); |
216 if (server_socket) { | 215 if (server_socket) { |
217 server_wrapper = new ServerWrapper(handler, std::move(server_socket), | 216 server_wrapper = new ServerWrapper(handler, std::move(server_socket), |
218 frontend_dir, bundles_resources); | 217 frontend_dir, bundles_resources); |
219 if (!output_directory.empty()) | 218 if (!output_directory.empty()) |
220 server_wrapper->WriteActivePortToUserProfile(output_directory); | 219 server_wrapper->WriteActivePortToUserProfile(output_directory); |
221 | 220 |
222 if (server_wrapper->GetLocalAddress(ip_address.get()) != net::OK) | 221 if (server_wrapper->GetLocalAddress(ip_address.get()) != net::OK) |
223 ip_address.reset(); | 222 ip_address.reset(); |
224 } else { | 223 } else { |
225 ip_address.reset(); | 224 ip_address.reset(); |
226 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; | 225 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; |
227 } | 226 } |
228 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 227 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
229 base::Bind(&ServerStartedOnUI, | 228 base::Bind(&ServerStartedOnUI, |
230 handler, | 229 handler, |
231 thread, | 230 thread, |
232 server_wrapper, | 231 server_wrapper, |
233 server_socket_factory, | 232 socket_factory, |
234 base::Passed(&ip_address))); | 233 base::Passed(&ip_address))); |
235 } | 234 } |
236 | 235 |
237 void StartServerOnFile( | 236 void StartServerOnFile( |
238 base::WeakPtr<DevToolsHttpHandler> handler, | 237 base::WeakPtr<DevToolsHttpHandler> handler, |
239 DevToolsHttpHandler::ServerSocketFactory* server_socket_factory, | 238 content::DevToolsSocketFactory* socket_factory, |
240 const base::FilePath& output_directory, | 239 const base::FilePath& output_directory, |
241 const base::FilePath& frontend_dir, | 240 const base::FilePath& frontend_dir, |
242 bool bundles_resources) { | 241 bool bundles_resources) { |
243 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 242 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
244 std::unique_ptr<base::Thread> thread( | 243 std::unique_ptr<base::Thread> thread( |
245 new base::Thread(kDevToolsHandlerThreadName)); | 244 new base::Thread(kDevToolsHandlerThreadName)); |
246 base::Thread::Options options; | 245 base::Thread::Options options; |
247 options.message_loop_type = base::MessageLoop::TYPE_IO; | 246 options.message_loop_type = base::MessageLoop::TYPE_IO; |
248 if (thread->StartWithOptions(options)) { | 247 if (thread->StartWithOptions(options)) { |
249 base::MessageLoop* message_loop = thread->message_loop(); | 248 base::MessageLoop* message_loop = thread->message_loop(); |
250 message_loop->task_runner()->PostTask( | 249 message_loop->task_runner()->PostTask( |
251 FROM_HERE, | 250 FROM_HERE, |
252 base::Bind(&StartServerOnHandlerThread, handler, | 251 base::Bind(&StartServerOnHandlerThread, handler, |
253 base::Unretained(thread.release()), server_socket_factory, | 252 base::Unretained(thread.release()), socket_factory, |
254 output_directory, frontend_dir, bundles_resources)); | 253 output_directory, frontend_dir, bundles_resources)); |
255 } | 254 } |
256 } | 255 } |
257 | 256 |
258 // DevToolsAgentHostClientImpl ----------------------------------------------- | 257 // DevToolsAgentHostClientImpl ----------------------------------------------- |
259 // An internal implementation of DevToolsAgentHostClient that delegates | 258 // An internal implementation of DevToolsAgentHostClient that delegates |
260 // messages sent to a DebuggerShell instance. | 259 // messages sent to a DebuggerShell instance. |
261 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { | 260 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
262 public: | 261 public: |
263 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, | 262 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 ServerWrapper* const server_wrapper_; | 317 ServerWrapper* const server_wrapper_; |
319 const int connection_id_; | 318 const int connection_id_; |
320 scoped_refptr<DevToolsAgentHost> agent_host_; | 319 scoped_refptr<DevToolsAgentHost> agent_host_; |
321 }; | 320 }; |
322 | 321 |
323 static bool TimeComparator(scoped_refptr<DevToolsAgentHost> host1, | 322 static bool TimeComparator(scoped_refptr<DevToolsAgentHost> host1, |
324 scoped_refptr<DevToolsAgentHost> host2) { | 323 scoped_refptr<DevToolsAgentHost> host2) { |
325 return host1->GetLastActivityTime() > host2->GetLastActivityTime(); | 324 return host1->GetLastActivityTime() > host2->GetLastActivityTime(); |
326 } | 325 } |
327 | 326 |
328 // DevToolsHttpHandler::ServerSocketFactory ---------------------------------- | |
329 | |
330 std::unique_ptr<net::ServerSocket> | |
331 DevToolsHttpHandler::ServerSocketFactory::CreateForHttpServer() { | |
332 return nullptr; | |
333 } | |
334 | |
335 std::unique_ptr<net::ServerSocket> | |
336 DevToolsHttpHandler::ServerSocketFactory::CreateForTethering( | |
337 std::string* name) { | |
338 return nullptr; | |
339 } | |
340 | |
341 // DevToolsHttpHandler ------------------------------------------------------- | 327 // DevToolsHttpHandler ------------------------------------------------------- |
342 | 328 |
343 DevToolsHttpHandler::~DevToolsHttpHandler() { | 329 DevToolsHttpHandler::~DevToolsHttpHandler() { |
344 TerminateOnUI(thread_, server_wrapper_, socket_factory_); | 330 TerminateOnUI(thread_, server_wrapper_, socket_factory_); |
345 } | 331 } |
346 | 332 |
347 GURL DevToolsHttpHandler::GetFrontendURL(const std::string& path) { | |
348 if (!server_ip_address_) | |
349 return GURL(); | |
350 return GURL(std::string("http://") + server_ip_address_->ToString() + | |
351 (path.empty() ? frontend_url_ : path)); | |
352 } | |
353 | |
354 static std::string PathWithoutParams(const std::string& path) { | 333 static std::string PathWithoutParams(const std::string& path) { |
355 size_t query_position = path.find("?"); | 334 size_t query_position = path.find("?"); |
356 if (query_position != std::string::npos) | 335 if (query_position != std::string::npos) |
357 return path.substr(0, query_position); | 336 return path.substr(0, query_position); |
358 return path; | 337 return path; |
359 } | 338 } |
360 | 339 |
361 static std::string GetMimeType(const std::string& filename) { | 340 static std::string GetMimeType(const std::string& filename) { |
362 if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) { | 341 if (base::EndsWith(filename, ".html", base::CompareCase::INSENSITIVE_ASCII)) { |
363 return "text/html"; | 342 return "text/html"; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 BrowserThread::PostTask( | 374 BrowserThread::PostTask( |
396 BrowserThread::UI, | 375 BrowserThread::UI, |
397 FROM_HERE, | 376 FROM_HERE, |
398 base::Bind(&DevToolsHttpHandler::OnJsonRequest, | 377 base::Bind(&DevToolsHttpHandler::OnJsonRequest, |
399 handler_, | 378 handler_, |
400 connection_id, | 379 connection_id, |
401 info)); | 380 info)); |
402 return; | 381 return; |
403 } | 382 } |
404 | 383 |
405 if (base::StartsWith(info.path, kThumbUrlPrefix, | |
406 base::CompareCase::SENSITIVE)) { | |
407 // Thumbnail request. | |
408 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); | |
409 BrowserThread::PostTask( | |
410 BrowserThread::UI, | |
411 FROM_HERE, | |
412 base::Bind(&DevToolsHttpHandler::OnThumbnailRequest, | |
413 handler_, | |
414 connection_id, | |
415 target_id)); | |
416 return; | |
417 } | |
418 | |
419 if (info.path.empty() || info.path == "/") { | 384 if (info.path.empty() || info.path == "/") { |
420 // Discovery page request. | 385 // Discovery page request. |
421 BrowserThread::PostTask( | 386 BrowserThread::PostTask( |
422 BrowserThread::UI, | 387 BrowserThread::UI, |
423 FROM_HERE, | 388 FROM_HERE, |
424 base::Bind(&DevToolsHttpHandler::OnDiscoveryPageRequest, | 389 base::Bind(&DevToolsHttpHandler::OnDiscoveryPageRequest, |
425 handler_, | 390 handler_, |
426 connection_id)); | 391 connection_id)); |
427 return; | 392 return; |
428 } | 393 } |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 "Unknown command: " + command); | 619 "Unknown command: " + command); |
655 return; | 620 return; |
656 } | 621 } |
657 | 622 |
658 scoped_refptr<DevToolsAgentHost> DevToolsHttpHandler::GetAgentHost( | 623 scoped_refptr<DevToolsAgentHost> DevToolsHttpHandler::GetAgentHost( |
659 const std::string& target_id) { | 624 const std::string& target_id) { |
660 DescriptorMap::const_iterator it = agent_host_map_.find(target_id); | 625 DescriptorMap::const_iterator it = agent_host_map_.find(target_id); |
661 return it != agent_host_map_.end() ? it->second : nullptr; | 626 return it != agent_host_map_.end() ? it->second : nullptr; |
662 } | 627 } |
663 | 628 |
664 void DevToolsHttpHandler::OnThumbnailRequest( | |
665 int connection_id, const std::string& target_id) { | |
666 scoped_refptr<DevToolsAgentHost> agent_host = GetAgentHost(target_id); | |
667 GURL page_url; | |
668 if (agent_host) | |
669 page_url = agent_host->GetURL(); | |
670 std::string data = delegate_->GetPageThumbnailData(page_url); | |
671 if (!data.empty()) | |
672 Send200(connection_id, data, "image/png"); | |
673 else | |
674 Send404(connection_id); | |
675 } | |
676 | |
677 void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) { | 629 void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) { |
678 std::string response = delegate_->GetDiscoveryPageHTML(); | 630 std::string response = delegate_->GetDiscoveryPageHTML(); |
679 Send200(connection_id, response, "text/html; charset=UTF-8"); | 631 Send200(connection_id, response, "text/html; charset=UTF-8"); |
680 } | 632 } |
681 | 633 |
682 void DevToolsHttpHandler::OnFrontendResourceRequest( | 634 void DevToolsHttpHandler::OnFrontendResourceRequest( |
683 int connection_id, const std::string& path) { | 635 int connection_id, const std::string& path) { |
684 Send200(connection_id, | 636 Send200(connection_id, |
685 delegate_->GetFrontendResource(path), | 637 delegate_->GetFrontendResource(path), |
686 GetMimeType(path)); | 638 GetMimeType(path)); |
687 } | 639 } |
688 | 640 |
689 void DevToolsHttpHandler::OnWebSocketRequest( | 641 void DevToolsHttpHandler::OnWebSocketRequest( |
690 int connection_id, | 642 int connection_id, |
691 const net::HttpServerRequestInfo& request) { | 643 const net::HttpServerRequestInfo& request) { |
692 if (!thread_) | 644 if (!thread_) |
693 return; | 645 return; |
694 | 646 |
695 std::string browser_prefix = "/devtools/browser"; | 647 std::string browser_prefix = "/devtools/browser"; |
696 if (base::StartsWith(request.path, browser_prefix, | 648 if (base::StartsWith(request.path, browser_prefix, |
697 base::CompareCase::SENSITIVE)) { | 649 base::CompareCase::SENSITIVE)) { |
698 scoped_refptr<DevToolsAgentHost> browser_agent = | 650 scoped_refptr<DevToolsAgentHost> browser_agent = |
699 DevToolsAgentHost::CreateForBrowser( | 651 DevToolsAgentHost::CreateForBrowser( |
700 thread_->task_runner(), | 652 thread_->task_runner(), |
701 base::Bind(&ServerSocketFactory::CreateForTethering, | 653 base::Bind(&content::DevToolsSocketFactory::CreateForTethering, |
702 base::Unretained(socket_factory_))); | 654 base::Unretained(socket_factory_))); |
703 connection_to_client_[connection_id] = new DevToolsAgentHostClientImpl( | 655 connection_to_client_[connection_id] = new DevToolsAgentHostClientImpl( |
704 thread_->message_loop(), server_wrapper_, connection_id, browser_agent); | 656 thread_->message_loop(), server_wrapper_, connection_id, browser_agent); |
705 AcceptWebSocket(connection_id, request); | 657 AcceptWebSocket(connection_id, request); |
706 return; | 658 return; |
707 } | 659 } |
708 | 660 |
709 // Handle external connections (such as frontend api) on the embedder level. | |
710 content::DevToolsExternalAgentProxyDelegate* external_delegate = | |
711 delegate_->HandleWebSocketConnection(request.path); | |
712 if (external_delegate) { | |
713 scoped_refptr<DevToolsAgentHost> agent_host = | |
714 DevToolsAgentHost::Create(external_delegate); | |
715 connection_to_client_[connection_id] = new DevToolsAgentHostClientImpl( | |
716 thread_->message_loop(), server_wrapper_, connection_id, agent_host); | |
717 AcceptWebSocket(connection_id, request); | |
718 return; | |
719 } | |
720 | |
721 if (!base::StartsWith(request.path, kPageUrlPrefix, | 661 if (!base::StartsWith(request.path, kPageUrlPrefix, |
722 base::CompareCase::SENSITIVE)) { | 662 base::CompareCase::SENSITIVE)) { |
723 Send404(connection_id); | 663 Send404(connection_id); |
724 return; | 664 return; |
725 } | 665 } |
726 | 666 |
727 std::string target_id = request.path.substr(strlen(kPageUrlPrefix)); | 667 std::string target_id = request.path.substr(strlen(kPageUrlPrefix)); |
728 scoped_refptr<DevToolsAgentHost> agent = GetAgentHost(target_id); | 668 scoped_refptr<DevToolsAgentHost> agent = GetAgentHost(target_id); |
729 if (!agent) { | 669 if (!agent) { |
730 Send500(connection_id, "No such target id: " + target_id); | 670 Send500(connection_id, "No such target id: " + target_id); |
(...skipping 25 matching lines...) Expand all Loading... |
756 void DevToolsHttpHandler::OnClose(int connection_id) { | 696 void DevToolsHttpHandler::OnClose(int connection_id) { |
757 ConnectionToClientMap::iterator it = | 697 ConnectionToClientMap::iterator it = |
758 connection_to_client_.find(connection_id); | 698 connection_to_client_.find(connection_id); |
759 if (it != connection_to_client_.end()) { | 699 if (it != connection_to_client_.end()) { |
760 delete it->second; | 700 delete it->second; |
761 connection_to_client_.erase(connection_id); | 701 connection_to_client_.erase(connection_id); |
762 } | 702 } |
763 } | 703 } |
764 | 704 |
765 DevToolsHttpHandler::DevToolsHttpHandler( | 705 DevToolsHttpHandler::DevToolsHttpHandler( |
766 std::unique_ptr<ServerSocketFactory> server_socket_factory, | 706 std::unique_ptr<content::DevToolsSocketFactory> socket_factory, |
767 const std::string& frontend_url, | 707 const std::string& frontend_url, |
768 DevToolsHttpHandlerDelegate* delegate, | 708 DevToolsHttpHandlerDelegate* delegate, |
769 const base::FilePath& output_directory, | 709 const base::FilePath& output_directory, |
770 const base::FilePath& debug_frontend_dir, | 710 const base::FilePath& debug_frontend_dir, |
771 const std::string& product_name, | 711 const std::string& product_name, |
772 const std::string& user_agent) | 712 const std::string& user_agent) |
773 : thread_(nullptr), | 713 : thread_(nullptr), |
774 frontend_url_(frontend_url), | 714 frontend_url_(frontend_url), |
775 product_name_(product_name), | 715 product_name_(product_name), |
776 user_agent_(user_agent), | 716 user_agent_(user_agent), |
777 server_wrapper_(nullptr), | 717 server_wrapper_(nullptr), |
778 delegate_(delegate), | 718 delegate_(delegate), |
779 socket_factory_(nullptr), | 719 socket_factory_(nullptr), |
780 weak_factory_(this) { | 720 weak_factory_(this) { |
781 bool bundles_resources = frontend_url_.empty(); | 721 bool bundles_resources = frontend_url_.empty(); |
782 if (frontend_url_.empty()) | 722 if (frontend_url_.empty()) |
783 frontend_url_ = "/devtools/inspector.html"; | 723 frontend_url_ = "/devtools/inspector.html"; |
784 | 724 |
785 BrowserThread::PostTask( | 725 BrowserThread::PostTask( |
786 BrowserThread::FILE, FROM_HERE, | 726 BrowserThread::FILE, FROM_HERE, |
787 base::Bind(&StartServerOnFile, | 727 base::Bind(&StartServerOnFile, |
788 weak_factory_.GetWeakPtr(), | 728 weak_factory_.GetWeakPtr(), |
789 server_socket_factory.release(), | 729 socket_factory.release(), |
790 output_directory, | 730 output_directory, |
791 debug_frontend_dir, | 731 debug_frontend_dir, |
792 bundles_resources)); | 732 bundles_resources)); |
793 } | 733 } |
794 | 734 |
795 void DevToolsHttpHandler::ServerStarted( | 735 void DevToolsHttpHandler::ServerStarted( |
796 base::Thread* thread, | 736 base::Thread* thread, |
797 ServerWrapper* server_wrapper, | 737 ServerWrapper* server_wrapper, |
798 ServerSocketFactory* socket_factory, | 738 content::DevToolsSocketFactory* socket_factory, |
799 std::unique_ptr<net::IPEndPoint> ip_address) { | 739 std::unique_ptr<net::IPEndPoint> ip_address) { |
800 thread_ = thread; | 740 thread_ = thread; |
801 server_wrapper_ = server_wrapper; | 741 server_wrapper_ = server_wrapper; |
802 socket_factory_ = socket_factory; | 742 socket_factory_ = socket_factory; |
803 server_ip_address_.swap(ip_address); | 743 server_ip_address_.swap(ip_address); |
804 } | 744 } |
805 | 745 |
806 void ServerWrapper::WriteActivePortToUserProfile( | 746 void ServerWrapper::WriteActivePortToUserProfile( |
807 const base::FilePath& output_directory) { | 747 const base::FilePath& output_directory) { |
808 DCHECK(!output_directory.empty()); | 748 DCHECK(!output_directory.empty()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 net::EscapeForHTML(agent_host->GetTitle())); | 842 net::EscapeForHTML(agent_host->GetTitle())); |
903 dictionary->SetString(kTargetDescriptionField, agent_host->GetDescription()); | 843 dictionary->SetString(kTargetDescriptionField, agent_host->GetDescription()); |
904 | 844 |
905 GURL url = agent_host->GetURL(); | 845 GURL url = agent_host->GetURL(); |
906 dictionary->SetString(kTargetUrlField, url.spec()); | 846 dictionary->SetString(kTargetUrlField, url.spec()); |
907 | 847 |
908 GURL favicon_url = agent_host->GetFaviconURL(); | 848 GURL favicon_url = agent_host->GetFaviconURL(); |
909 if (favicon_url.is_valid()) | 849 if (favicon_url.is_valid()) |
910 dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec()); | 850 dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec()); |
911 | 851 |
912 if (!delegate_->GetPageThumbnailData(url).empty()) { | |
913 dictionary->SetString(kTargetThumbnailUrlField, | |
914 std::string(kThumbUrlPrefix) + id); | |
915 } | |
916 | |
917 if (!agent_host->IsAttached()) { | 852 if (!agent_host->IsAttached()) { |
918 dictionary->SetString(kTargetWebSocketDebuggerUrlField, | 853 dictionary->SetString(kTargetWebSocketDebuggerUrlField, |
919 base::StringPrintf("ws://%s%s%s", | 854 base::StringPrintf("ws://%s%s%s", |
920 host.c_str(), | 855 host.c_str(), |
921 kPageUrlPrefix, | 856 kPageUrlPrefix, |
922 id.c_str())); | 857 id.c_str())); |
923 std::string devtools_frontend_url = GetFrontendURLInternal( | 858 std::string devtools_frontend_url = GetFrontendURLInternal( |
924 id.c_str(), | 859 id.c_str(), |
925 host); | 860 host); |
926 dictionary->SetString( | 861 dictionary->SetString( |
927 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | 862 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
928 } | 863 } |
929 | 864 |
930 return dictionary; | 865 return dictionary; |
931 } | 866 } |
932 | 867 |
933 } // namespace devtools_http_handler | 868 } // namespace devtools_http_handler |
OLD | NEW |