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