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 "content/browser/devtools/devtools_http_handler_impl.h" | 5 #include "content/browser/devtools/devtools_http_handler_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
14 #include "base/lazy_instance.h" | |
15 #include "base/logging.h" | 14 #include "base/logging.h" |
16 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
17 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
18 #include "base/strings/string_number_conversions.h" | |
19 #include "base/strings/utf_string_conversions.h" | |
20 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
21 #include "base/values.h" | 18 #include "base/values.h" |
22 #include "content/browser/devtools/devtools_browser_target.h" | 19 #include "content/browser/devtools/devtools_browser_target.h" |
23 #include "content/browser/devtools/devtools_protocol.h" | 20 #include "content/browser/devtools/devtools_protocol.h" |
24 #include "content/browser/devtools/devtools_protocol_constants.h" | 21 #include "content/browser/devtools/devtools_protocol_constants.h" |
25 #include "content/browser/devtools/devtools_system_info_handler.h" | 22 #include "content/browser/devtools/devtools_system_info_handler.h" |
26 #include "content/browser/devtools/devtools_tracing_handler.h" | 23 #include "content/browser/devtools/devtools_tracing_handler.h" |
27 #include "content/browser/devtools/tethering_handler.h" | 24 #include "content/browser/devtools/tethering_handler.h" |
28 #include "content/browser/web_contents/web_contents_impl.h" | |
29 #include "content/common/devtools_messages.h" | 25 #include "content/common/devtools_messages.h" |
30 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
31 #include "content/public/browser/devtools_agent_host.h" | 27 #include "content/public/browser/devtools_agent_host.h" |
32 #include "content/public/browser/devtools_client_host.h" | 28 #include "content/public/browser/devtools_client_host.h" |
33 #include "content/public/browser/devtools_http_handler_delegate.h" | 29 #include "content/public/browser/devtools_http_handler_delegate.h" |
34 #include "content/public/browser/devtools_manager.h" | 30 #include "content/public/browser/devtools_manager.h" |
35 #include "content/public/browser/favicon_status.h" | |
36 #include "content/public/browser/navigation_entry.h" | |
37 #include "content/public/browser/notification_service.h" | |
38 #include "content/public/browser/notification_types.h" | |
39 #include "content/public/browser/render_view_host.h" | |
40 #include "content/public/common/content_client.h" | 31 #include "content/public/common/content_client.h" |
41 #include "content/public/common/url_constants.h" | 32 #include "content/public/common/url_constants.h" |
42 #include "grit/devtools_resources_map.h" | 33 #include "grit/devtools_resources_map.h" |
43 #include "net/base/escape.h" | |
44 #include "net/base/io_buffer.h" | 34 #include "net/base/io_buffer.h" |
45 #include "net/base/ip_endpoint.h" | 35 #include "net/base/ip_endpoint.h" |
46 #include "net/server/http_server_request_info.h" | 36 #include "net/server/http_server_request_info.h" |
47 #include "net/server/http_server_response_info.h" | 37 #include "net/server/http_server_response_info.h" |
48 #include "ui/base/layout.h" | |
49 #include "url/gurl.h" | |
50 #include "webkit/common/user_agent/user_agent.h" | 38 #include "webkit/common/user_agent/user_agent.h" |
51 #include "webkit/common/user_agent/user_agent_util.h" | 39 #include "webkit/common/user_agent/user_agent_util.h" |
52 | 40 |
53 namespace content { | 41 namespace content { |
54 | 42 |
55 namespace { | 43 namespace { |
56 | 44 |
57 const char kProtocolVersion[] = "1.0"; | 45 const char kProtocolVersion[] = "1.0"; |
58 | 46 |
59 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 47 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
60 | 48 |
61 const char kThumbUrlPrefix[] = "/thumb/"; | 49 const char kThumbUrlPrefix[] = "/thumb/"; |
62 const char kPageUrlPrefix[] = "/devtools/page/"; | 50 const char kPageUrlPrefix[] = "/devtools/page/"; |
63 | 51 |
64 const char kTargetIdField[] = "id"; | 52 const char kTargetIdField[] = "id"; |
65 const char kTargetTypeField[] = "type"; | 53 const char kTargetTypeField[] = "type"; |
66 const char kTargetTitleField[] = "title"; | 54 const char kTargetTitleField[] = "title"; |
67 const char kTargetDescriptionField[] = "description"; | 55 const char kTargetDescriptionField[] = "description"; |
68 const char kTargetUrlField[] = "url"; | 56 const char kTargetUrlField[] = "url"; |
69 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; | 57 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; |
70 const char kTargetFaviconUrlField[] = "faviconUrl"; | 58 const char kTargetFaviconUrlField[] = "faviconUrl"; |
71 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 59 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
72 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 60 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
73 | 61 |
74 const char kTargetTypePage[] = "page"; | |
75 const char kTargetTypeOther[] = "other"; | |
76 | |
77 class DevToolsDefaultBindingHandler | |
78 : public DevToolsHttpHandler::DevToolsAgentHostBinding { | |
79 public: | |
80 DevToolsDefaultBindingHandler() { | |
81 } | |
82 | |
83 virtual std::string GetIdentifier(DevToolsAgentHost* agent_host) OVERRIDE { | |
84 return agent_host->GetId(); | |
85 } | |
86 | |
87 virtual DevToolsAgentHost* ForIdentifier(const std::string& id) OVERRIDE { | |
88 return DevToolsAgentHost::GetForId(id).get(); | |
89 } | |
90 }; | |
91 | |
92 // An internal implementation of DevToolsClientHost that delegates | 62 // An internal implementation of DevToolsClientHost that delegates |
93 // messages sent for DevToolsClient to a DebuggerShell instance. | 63 // messages sent for DevToolsClient to a DebuggerShell instance. |
94 class DevToolsClientHostImpl : public DevToolsClientHost { | 64 class DevToolsClientHostImpl : public DevToolsClientHost { |
95 public: | 65 public: |
96 DevToolsClientHostImpl(base::MessageLoop* message_loop, | 66 DevToolsClientHostImpl(base::MessageLoop* message_loop, |
97 net::HttpServer* server, | 67 net::HttpServer* server, |
98 int connection_id) | 68 int connection_id) |
99 : message_loop_(message_loop), | 69 : message_loop_(message_loop), |
100 server_(server), | 70 server_(server), |
101 connection_id_(connection_id), | 71 connection_id_(connection_id), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 112 } |
143 | 113 |
144 private: | 114 private: |
145 base::MessageLoop* message_loop_; | 115 base::MessageLoop* message_loop_; |
146 net::HttpServer* server_; | 116 net::HttpServer* server_; |
147 int connection_id_; | 117 int connection_id_; |
148 bool is_closed_; | 118 bool is_closed_; |
149 std::string detach_reason_; | 119 std::string detach_reason_; |
150 }; | 120 }; |
151 | 121 |
152 static base::TimeTicks GetLastSelectedTime(RenderViewHost* rvh) { | 122 static bool TimeComparator(scoped_refptr<DevToolsTarget> target1, |
153 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | 123 scoped_refptr<DevToolsTarget> target2) { |
154 if (!web_contents) | 124 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); |
155 return base::TimeTicks(); | |
156 | |
157 return web_contents->GetLastSelectedTime(); | |
158 } | |
159 | |
160 typedef std::pair<RenderViewHost*, base::TimeTicks> PageInfo; | |
161 | |
162 static bool TimeComparator(const PageInfo& info1, const PageInfo& info2) { | |
163 return info1.second > info2.second; | |
164 } | 125 } |
165 | 126 |
166 } // namespace | 127 } // namespace |
167 | 128 |
168 // static | 129 // static |
169 bool DevToolsHttpHandler::IsSupportedProtocolVersion( | 130 bool DevToolsHttpHandler::IsSupportedProtocolVersion( |
170 const std::string& version) { | 131 const std::string& version) { |
171 return version == kProtocolVersion; | 132 return version == kProtocolVersion; |
172 } | 133 } |
173 | 134 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 | 197 |
237 void DevToolsHttpHandlerImpl::Stop() { | 198 void DevToolsHttpHandlerImpl::Stop() { |
238 if (!thread_) | 199 if (!thread_) |
239 return; | 200 return; |
240 BrowserThread::PostTaskAndReply( | 201 BrowserThread::PostTaskAndReply( |
241 BrowserThread::FILE, FROM_HERE, | 202 BrowserThread::FILE, FROM_HERE, |
242 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), | 203 base::Bind(&DevToolsHttpHandlerImpl::StopHandlerThread, this), |
243 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); | 204 base::Bind(&DevToolsHttpHandlerImpl::ResetHandlerThreadAndRelease, this)); |
244 } | 205 } |
245 | 206 |
246 void DevToolsHttpHandlerImpl::SetDevToolsAgentHostBinding( | 207 GURL DevToolsHttpHandlerImpl::GetFrontendURL() { |
247 DevToolsAgentHostBinding* binding) { | |
248 if (binding) | |
249 binding_ = binding; | |
250 else | |
251 binding_ = default_binding_.get(); | |
252 } | |
253 | |
254 GURL DevToolsHttpHandlerImpl::GetFrontendURL(DevToolsAgentHost* agent_host) { | |
255 net::IPEndPoint ip_address; | 208 net::IPEndPoint ip_address; |
256 if (server_->GetLocalAddress(&ip_address)) | 209 if (server_->GetLocalAddress(&ip_address)) |
257 return GURL(); | 210 return GURL(); |
258 if (!agent_host) { | 211 return GURL(std::string("http://") + ip_address.ToString() + |
259 return GURL(std::string("http://") + ip_address.ToString() + | 212 overridden_frontend_url_); |
260 overridden_frontend_url_); | |
261 } | |
262 std::string host = ip_address.ToString(); | |
263 std::string id = binding_->GetIdentifier(agent_host); | |
264 return GURL(std::string("http://") + | |
265 ip_address.ToString() + | |
266 GetFrontendURLInternal(id, host)); | |
267 } | 213 } |
268 | 214 |
269 static std::string PathWithoutParams(const std::string& path) { | 215 static std::string PathWithoutParams(const std::string& path) { |
270 size_t query_position = path.find("?"); | 216 size_t query_position = path.find("?"); |
271 if (query_position != std::string::npos) | 217 if (query_position != std::string::npos) |
272 return path.substr(0, query_position); | 218 return path.substr(0, query_position); |
273 return path; | 219 return path; |
274 } | 220 } |
275 | 221 |
276 static std::string GetMimeType(const std::string& filename) { | 222 static std::string GetMimeType(const std::string& filename) { |
(...skipping 22 matching lines...) Expand all Loading... |
299 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, | 245 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, |
300 this, | 246 this, |
301 connection_id, | 247 connection_id, |
302 info)); | 248 info)); |
303 return; | 249 return; |
304 } | 250 } |
305 | 251 |
306 if (info.path.find(kThumbUrlPrefix) == 0) { | 252 if (info.path.find(kThumbUrlPrefix) == 0) { |
307 // Thumbnail request. | 253 // Thumbnail request. |
308 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); | 254 const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix)); |
309 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | 255 scoped_refptr<DevToolsTarget> target = GetTarget(target_id); |
310 GURL page_url; | 256 GURL page_url; |
311 if (agent_host) { | 257 if (target) |
312 RenderViewHost* rvh = agent_host->GetRenderViewHost(); | 258 page_url = target->GetUrl(); |
313 if (rvh) | |
314 page_url = rvh->GetDelegate()->GetURL(); | |
315 } | |
316 BrowserThread::PostTask( | 259 BrowserThread::PostTask( |
317 BrowserThread::UI, | 260 BrowserThread::UI, |
318 FROM_HERE, | 261 FROM_HERE, |
319 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, | 262 base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI, |
320 this, | 263 this, |
321 connection_id, | 264 connection_id, |
322 page_url)); | 265 page_url)); |
323 return; | 266 return; |
324 } | 267 } |
325 | 268 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 version.SetString("Protocol-Version", kProtocolVersion); | 445 version.SetString("Protocol-Version", kProtocolVersion); |
503 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); | 446 version.SetString("WebKit-Version", webkit_glue::GetWebKitVersion()); |
504 version.SetString("Browser", content::GetContentClient()->GetProduct()); | 447 version.SetString("Browser", content::GetContentClient()->GetProduct()); |
505 version.SetString("User-Agent", | 448 version.SetString("User-Agent", |
506 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); | 449 webkit_glue::GetUserAgent(GURL(kAboutBlankURL))); |
507 SendJson(connection_id, net::HTTP_OK, &version, std::string()); | 450 SendJson(connection_id, net::HTTP_OK, &version, std::string()); |
508 return; | 451 return; |
509 } | 452 } |
510 | 453 |
511 if (command == "list") { | 454 if (command == "list") { |
512 typedef std::vector<PageInfo> PageList; | |
513 PageList page_list; | |
514 | |
515 std::vector<RenderViewHost*> rvh_list = | |
516 DevToolsAgentHost::GetValidRenderViewHosts(); | |
517 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); | |
518 it != rvh_list.end(); ++it) | |
519 page_list.push_back(PageInfo(*it, GetLastSelectedTime(*it))); | |
520 | |
521 std::sort(page_list.begin(), page_list.end(), TimeComparator); | |
522 | |
523 base::ListValue* target_list = new base::ListValue(); | |
524 std::string host = info.headers["host"]; | 455 std::string host = info.headers["host"]; |
525 for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i) | 456 AddRef(); // Balanced in OnTargetListReceived. |
526 target_list->Append(SerializePageInfo(i->first, host)); | 457 delegate_->EnumerateTargets( |
527 | 458 base::Bind(&DevToolsHttpHandlerImpl::OnTargetListReceived, |
528 AddRef(); // Balanced in SendTargetList. | 459 this, connection_id, host)); |
529 BrowserThread::PostTaskAndReply( | |
530 BrowserThread::IO, | |
531 FROM_HERE, | |
532 base::Bind(&DevToolsHttpHandlerImpl::CollectWorkerInfo, | |
533 base::Unretained(this), | |
534 target_list, | |
535 host), | |
536 base::Bind(&DevToolsHttpHandlerImpl::SendTargetList, | |
537 base::Unretained(this), | |
538 connection_id, | |
539 target_list)); | |
540 return; | 460 return; |
541 } | 461 } |
542 | 462 |
543 if (command == "new") { | 463 if (command == "new") { |
544 RenderViewHost* rvh = delegate_->CreateNewTarget(); | 464 scoped_refptr<DevToolsTarget> target = delegate_->CreateNewTarget(); |
545 if (!rvh) { | 465 if (!target) { |
546 SendJson(connection_id, | 466 SendJson(connection_id, |
547 net::HTTP_INTERNAL_SERVER_ERROR, | 467 net::HTTP_INTERNAL_SERVER_ERROR, |
548 NULL, | 468 NULL, |
549 "Could not create new page"); | 469 "Could not create new page"); |
550 return; | 470 return; |
551 } | 471 } |
| 472 target_map_[target->GetId()] = target; |
552 std::string host = info.headers["host"]; | 473 std::string host = info.headers["host"]; |
553 scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host)); | 474 scoped_ptr<base::DictionaryValue> dictionary( |
| 475 SerializeTarget(*target.get(), host)); |
554 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); | 476 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); |
555 return; | 477 return; |
556 } | 478 } |
557 | 479 |
558 if (command == "activate" || command == "close") { | 480 if (command == "activate" || command == "close") { |
559 DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id); | 481 DevToolsTarget* target = GetTarget(target_id); |
560 RenderViewHost* rvh = agent_host ? agent_host->GetRenderViewHost() : NULL; | 482 if (!target) { |
561 if (!rvh) { | |
562 SendJson(connection_id, | 483 SendJson(connection_id, |
563 net::HTTP_NOT_FOUND, | 484 net::HTTP_NOT_FOUND, |
564 NULL, | 485 NULL, |
565 "No such target id: " + target_id); | 486 "No such target id: " + target_id); |
566 return; | 487 return; |
567 } | 488 } |
568 | 489 |
569 if (command == "activate") { | 490 if (command == "activate") { |
570 rvh->GetDelegate()->Activate(); | 491 if (target->Activate()) { |
571 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); | 492 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); |
| 493 } else { |
| 494 SendJson(connection_id, |
| 495 net::HTTP_INTERNAL_SERVER_ERROR, |
| 496 NULL, |
| 497 "Could not activate target id: " + target_id); |
| 498 } |
572 return; | 499 return; |
573 } | 500 } |
574 | 501 |
575 if (command == "close") { | 502 if (command == "close") { |
576 rvh->ClosePage(); | 503 if (target->Close()) { |
577 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); | 504 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); |
| 505 } else { |
| 506 SendJson(connection_id, |
| 507 net::HTTP_INTERNAL_SERVER_ERROR, |
| 508 NULL, |
| 509 "Could not close target id: " + target_id); |
| 510 } |
578 return; | 511 return; |
579 } | 512 } |
580 } | 513 } |
581 SendJson(connection_id, | 514 SendJson(connection_id, |
582 net::HTTP_NOT_FOUND, | 515 net::HTTP_NOT_FOUND, |
583 NULL, | 516 NULL, |
584 "Unknown command: " + command); | 517 "Unknown command: " + command); |
585 return; | 518 return; |
586 } | 519 } |
587 | 520 |
588 void DevToolsHttpHandlerImpl::CollectWorkerInfo(base::ListValue* target_list, | 521 void DevToolsHttpHandlerImpl::OnTargetListReceived( |
589 std::string host) { | 522 int connection_id, |
| 523 const std::string& host, |
| 524 const DevToolsHttpHandlerDelegate::TargetList& targets) { |
| 525 DevToolsHttpHandlerDelegate::TargetList sorted_targets = targets; |
| 526 std::sort(sorted_targets.begin(), sorted_targets.end(), TimeComparator); |
590 | 527 |
591 std::vector<WorkerService::WorkerInfo> worker_info = | 528 target_map_.clear(); |
592 WorkerService::GetInstance()->GetWorkers(); | 529 base::ListValue list_value; |
593 | 530 for (DevToolsHttpHandlerDelegate::TargetList::const_iterator it = |
594 for (size_t i = 0; i < worker_info.size(); ++i) | 531 sorted_targets.begin(); it != sorted_targets.end(); ++it) { |
595 target_list->Append(SerializeWorkerInfo(worker_info[i], host)); | 532 scoped_refptr<DevToolsTarget> target = *it; |
| 533 target_map_[target->GetId()] = target; |
| 534 list_value.Append(SerializeTarget(*(target.get()), host)); |
| 535 } |
| 536 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
| 537 Release(); // Balanced in OnJsonRequestUI. |
596 } | 538 } |
597 | 539 |
598 void DevToolsHttpHandlerImpl::SendTargetList(int connection_id, | 540 DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { |
599 base::ListValue* target_list) { | 541 TargetMap::iterator it = target_map_.find(id); |
600 SendJson(connection_id, net::HTTP_OK, target_list, std::string()); | 542 if (it == target_map_.end()) |
601 delete target_list; | 543 return NULL; |
602 Release(); // Balanced OnJsonRequestUI. | 544 return it->second.get(); |
603 } | 545 } |
604 | 546 |
605 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( | 547 void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( |
606 int connection_id, const GURL& page_url) { | 548 int connection_id, const GURL& page_url) { |
607 std::string data = delegate_->GetPageThumbnailData(page_url); | 549 std::string data = delegate_->GetPageThumbnailData(page_url); |
608 if (!data.empty()) | 550 if (!data.empty()) |
609 Send200(connection_id, data, "image/png"); | 551 Send200(connection_id, data, "image/png"); |
610 else | 552 else |
611 Send404(connection_id); | 553 Send404(connection_id); |
612 } | 554 } |
613 | 555 |
614 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { | 556 void DevToolsHttpHandlerImpl::OnDiscoveryPageRequestUI(int connection_id) { |
615 std::string response = delegate_->GetDiscoveryPageHTML(); | 557 std::string response = delegate_->GetDiscoveryPageHTML(); |
616 Send200(connection_id, response, "text/html; charset=UTF-8"); | 558 Send200(connection_id, response, "text/html; charset=UTF-8"); |
617 } | 559 } |
618 | 560 |
619 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( | 561 void DevToolsHttpHandlerImpl::OnWebSocketRequestUI( |
620 int connection_id, | 562 int connection_id, |
621 const net::HttpServerRequestInfo& request) { | 563 const net::HttpServerRequestInfo& request) { |
622 if (!thread_) | 564 if (!thread_) |
623 return; | 565 return; |
624 | 566 |
625 size_t pos = request.path.find(kPageUrlPrefix); | 567 size_t pos = request.path.find(kPageUrlPrefix); |
626 if (pos != 0) { | 568 if (pos != 0) { |
627 Send404(connection_id); | 569 Send404(connection_id); |
628 return; | 570 return; |
629 } | 571 } |
630 | 572 |
631 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); | 573 std::string page_id = request.path.substr(strlen(kPageUrlPrefix)); |
632 DevToolsAgentHost* agent = binding_->ForIdentifier(page_id); | 574 DevToolsTarget* target = GetTarget(page_id); |
| 575 scoped_refptr<DevToolsAgentHost> agent = |
| 576 target ? target->GetAgentHost() : NULL; |
633 if (!agent) { | 577 if (!agent) { |
634 Send500(connection_id, "No such target id: " + page_id); | 578 Send500(connection_id, "No such target id: " + page_id); |
635 return; | 579 return; |
636 } | 580 } |
637 | 581 |
638 if (agent->IsAttached()) { | 582 if (agent->IsAttached()) { |
639 Send500(connection_id, | 583 Send500(connection_id, |
640 "Target with given id is being inspected: " + page_id); | 584 "Target with given id is being inspected: " + page_id); |
641 return; | 585 return; |
642 } | 586 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( | 622 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( |
679 const net::StreamListenSocketFactory* socket_factory, | 623 const net::StreamListenSocketFactory* socket_factory, |
680 const std::string& frontend_url, | 624 const std::string& frontend_url, |
681 DevToolsHttpHandlerDelegate* delegate) | 625 DevToolsHttpHandlerDelegate* delegate) |
682 : overridden_frontend_url_(frontend_url), | 626 : overridden_frontend_url_(frontend_url), |
683 socket_factory_(socket_factory), | 627 socket_factory_(socket_factory), |
684 delegate_(delegate) { | 628 delegate_(delegate) { |
685 if (overridden_frontend_url_.empty()) | 629 if (overridden_frontend_url_.empty()) |
686 overridden_frontend_url_ = "/devtools/devtools.html"; | 630 overridden_frontend_url_ = "/devtools/devtools.html"; |
687 | 631 |
688 default_binding_.reset(new DevToolsDefaultBindingHandler); | |
689 binding_ = default_binding_.get(); | |
690 | |
691 // Balanced in ResetHandlerThreadAndRelease(). | 632 // Balanced in ResetHandlerThreadAndRelease(). |
692 AddRef(); | 633 AddRef(); |
693 } | 634 } |
694 | 635 |
695 // Runs on the handler thread | 636 // Runs on the handler thread |
696 void DevToolsHttpHandlerImpl::Init() { | 637 void DevToolsHttpHandlerImpl::Init() { |
697 server_ = new net::HttpServer(*socket_factory_.get(), this); | 638 server_ = new net::HttpServer(*socket_factory_.get(), this); |
698 } | 639 } |
699 | 640 |
700 // Runs on the handler thread | 641 // Runs on the handler thread |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 int connection_id, | 720 int connection_id, |
780 const net::HttpServerRequestInfo& request) { | 721 const net::HttpServerRequestInfo& request) { |
781 if (!thread_) | 722 if (!thread_) |
782 return; | 723 return; |
783 thread_->message_loop()->PostTask( | 724 thread_->message_loop()->PostTask( |
784 FROM_HERE, | 725 FROM_HERE, |
785 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), | 726 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(), |
786 connection_id, request)); | 727 connection_id, request)); |
787 } | 728 } |
788 | 729 |
789 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo( | 730 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( |
790 RenderViewHost* rvh, | 731 const DevToolsTarget& target, |
791 const std::string& host) { | 732 const std::string& host) { |
792 base::DictionaryValue* dictionary = new base::DictionaryValue; | 733 base::DictionaryValue* dictionary = new base::DictionaryValue; |
793 | 734 |
794 scoped_refptr<DevToolsAgentHost> agent( | 735 std::string id = target.GetId(); |
795 DevToolsAgentHost::GetOrCreateFor(rvh)); | 736 dictionary->SetString(kTargetIdField, id); |
| 737 dictionary->SetString(kTargetTypeField, target.GetType()); |
| 738 dictionary->SetString(kTargetTitleField, target.GetTitle()); |
| 739 dictionary->SetString(kTargetDescriptionField, target.GetDescription()); |
796 | 740 |
797 std::string id = binding_->GetIdentifier(agent.get()); | 741 GURL url = target.GetUrl(); |
798 dictionary->SetString(kTargetIdField, id); | 742 dictionary->SetString(kTargetUrlField, url.spec()); |
799 | 743 |
800 switch (delegate_->GetTargetType(rvh)) { | 744 GURL favicon_url = target.GetFaviconUrl(); |
801 case DevToolsHttpHandlerDelegate::kTargetTypeTab: | 745 if (favicon_url.is_valid()) |
802 dictionary->SetString(kTargetTypeField, kTargetTypePage); | 746 dictionary->SetString(kTargetFaviconUrlField, favicon_url.spec()); |
803 break; | 747 |
804 default: | 748 if (!delegate_->GetPageThumbnailData(url).empty()) { |
805 dictionary->SetString(kTargetTypeField, kTargetTypeOther); | 749 dictionary->SetString(kTargetThumbnailUrlField, |
| 750 std::string(kThumbUrlPrefix) + id); |
806 } | 751 } |
807 | 752 |
808 WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents(); | 753 if (!target.IsAttached()) { |
809 if (web_contents) { | 754 dictionary->SetString(kTargetWebSocketDebuggerUrlField, |
810 dictionary->SetString(kTargetTitleField, UTF16ToUTF8( | 755 base::StringPrintf("ws://%s%s%s", |
811 net::EscapeForHTML(web_contents->GetTitle()))); | 756 host.c_str(), |
812 dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); | 757 kPageUrlPrefix, |
813 dictionary->SetString(kTargetThumbnailUrlField, | 758 id.c_str())); |
814 std::string(kThumbUrlPrefix) + id); | 759 std::string devtools_frontend_url = GetFrontendURLInternal( |
| 760 id.c_str(), |
| 761 host); |
| 762 dictionary->SetString( |
| 763 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
| 764 } |
815 | 765 |
816 NavigationController& controller = web_contents->GetController(); | |
817 NavigationEntry* entry = controller.GetActiveEntry(); | |
818 if (entry != NULL && entry->GetURL().is_valid()) { | |
819 dictionary->SetString(kTargetFaviconUrlField, | |
820 entry->GetFavicon().url.spec()); | |
821 } | |
822 } | |
823 dictionary->SetString(kTargetDescriptionField, | |
824 delegate_->GetViewDescription(rvh)); | |
825 | |
826 if (!agent->IsAttached()) | |
827 SerializeDebuggerURLs(dictionary, id, host); | |
828 return dictionary; | 766 return dictionary; |
829 } | 767 } |
830 | 768 |
831 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeWorkerInfo( | |
832 const WorkerService::WorkerInfo& worker, | |
833 const std::string& host) { | |
834 base::DictionaryValue* dictionary = new base::DictionaryValue; | |
835 | |
836 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker( | |
837 worker.process_id, worker.route_id)); | |
838 | |
839 std::string id = binding_->GetIdentifier(agent.get()); | |
840 | |
841 dictionary->SetString(kTargetIdField, id); | |
842 dictionary->SetString(kTargetTypeField, kTargetTypeOther); | |
843 dictionary->SetString(kTargetTitleField, | |
844 UTF16ToUTF8(net::EscapeForHTML(worker.name))); | |
845 dictionary->SetString(kTargetUrlField, worker.url.spec()); | |
846 dictionary->SetString(kTargetDescriptionField, | |
847 base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle))); | |
848 | |
849 if (!agent->IsAttached()) | |
850 SerializeDebuggerURLs(dictionary, id, host); | |
851 return dictionary; | |
852 } | |
853 | |
854 void DevToolsHttpHandlerImpl::SerializeDebuggerURLs( | |
855 base::DictionaryValue* dictionary, | |
856 const std::string& id, | |
857 const std::string& host) { | |
858 dictionary->SetString(kTargetWebSocketDebuggerUrlField, | |
859 base::StringPrintf("ws://%s%s%s", | |
860 host.c_str(), | |
861 kPageUrlPrefix, | |
862 id.c_str())); | |
863 std::string devtools_frontend_url = GetFrontendURLInternal( | |
864 id.c_str(), | |
865 host); | |
866 dictionary->SetString(kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | |
867 } | |
868 | |
869 } // namespace content | 769 } // namespace content |
OLD | NEW |