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_discovery/devtools_discovery_manager.h" | 25 #include "components/devtools_discovery/devtools_discovery_manager.h" |
26 #include "components/devtools_http_handler/devtools_http_handler.h" | 26 #include "components/devtools_http_handler/devtools_http_handler.h" |
27 #include "components/devtools_http_handler/devtools_http_handler_delegate.h" | 27 #include "components/devtools_http_handler/devtools_http_handler_delegate.h" |
28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/devtools_agent_host.h" | |
30 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 29 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
31 #include "content/public/common/url_constants.h" | 30 #include "content/public/common/url_constants.h" |
32 #include "content/public/common/user_agent.h" | 31 #include "content/public/common/user_agent.h" |
33 #include "net/base/escape.h" | 32 #include "net/base/escape.h" |
34 #include "net/base/io_buffer.h" | 33 #include "net/base/io_buffer.h" |
35 #include "net/base/ip_endpoint.h" | 34 #include "net/base/ip_endpoint.h" |
36 #include "net/base/net_errors.h" | 35 #include "net/base/net_errors.h" |
37 #include "net/server/http_server.h" | 36 #include "net/server/http_server.h" |
38 #include "net/server/http_server_request_info.h" | 37 #include "net/server/http_server_request_info.h" |
39 #include "net/server/http_server_response_info.h" | 38 #include "net/server/http_server_response_info.h" |
40 #include "net/socket/server_socket.h" | 39 #include "net/socket/server_socket.h" |
41 | 40 |
42 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
43 #include "base/android/build_info.h" | 42 #include "base/android/build_info.h" |
44 #endif | 43 #endif |
45 | 44 |
46 using content::BrowserThread; | 45 using content::BrowserThread; |
47 using content::DevToolsAgentHost; | 46 using content::DevToolsAgentHost; |
48 using content::DevToolsAgentHostClient; | 47 using content::DevToolsAgentHostClient; |
49 using devtools_discovery::DevToolsTargetDescriptor; | |
50 | 48 |
51 namespace devtools_http_handler { | 49 namespace devtools_http_handler { |
52 | 50 |
53 namespace { | 51 namespace { |
54 | 52 |
55 const base::FilePath::CharType kDevToolsActivePortFileName[] = | 53 const base::FilePath::CharType kDevToolsActivePortFileName[] = |
56 FILE_PATH_LITERAL("DevToolsActivePort"); | 54 FILE_PATH_LITERAL("DevToolsActivePort"); |
57 | 55 |
58 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 56 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
59 | 57 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 agent_host_->DispatchProtocolMessage(this, message); | 313 agent_host_->DispatchProtocolMessage(this, message); |
316 } | 314 } |
317 | 315 |
318 private: | 316 private: |
319 base::MessageLoop* const message_loop_; | 317 base::MessageLoop* const message_loop_; |
320 ServerWrapper* const server_wrapper_; | 318 ServerWrapper* const server_wrapper_; |
321 const int connection_id_; | 319 const int connection_id_; |
322 scoped_refptr<DevToolsAgentHost> agent_host_; | 320 scoped_refptr<DevToolsAgentHost> agent_host_; |
323 }; | 321 }; |
324 | 322 |
325 static bool TimeComparator(const DevToolsTargetDescriptor* desc1, | 323 static bool TimeComparator(scoped_refptr<DevToolsAgentHost> host1, |
326 const DevToolsTargetDescriptor* desc2) { | 324 scoped_refptr<DevToolsAgentHost> host2) { |
327 return desc1->GetAgentHost()->GetLastActivityTime() > | 325 return host1->GetLastActivityTime() > host2->GetLastActivityTime(); |
328 desc2->GetAgentHost()->GetLastActivityTime(); | |
329 } | 326 } |
330 | 327 |
331 // DevToolsHttpHandler::ServerSocketFactory ---------------------------------- | 328 // DevToolsHttpHandler::ServerSocketFactory ---------------------------------- |
332 | 329 |
333 std::unique_ptr<net::ServerSocket> | 330 std::unique_ptr<net::ServerSocket> |
334 DevToolsHttpHandler::ServerSocketFactory::CreateForHttpServer() { | 331 DevToolsHttpHandler::ServerSocketFactory::CreateForHttpServer() { |
335 return nullptr; | 332 return nullptr; |
336 } | 333 } |
337 | 334 |
338 std::unique_ptr<net::ServerSocket> | 335 std::unique_ptr<net::ServerSocket> |
339 DevToolsHttpHandler::ServerSocketFactory::CreateForTethering( | 336 DevToolsHttpHandler::ServerSocketFactory::CreateForTethering( |
340 std::string* name) { | 337 std::string* name) { |
341 return nullptr; | 338 return nullptr; |
342 } | 339 } |
343 | 340 |
344 // DevToolsHttpHandler ------------------------------------------------------- | 341 // DevToolsHttpHandler ------------------------------------------------------- |
345 | 342 |
346 DevToolsHttpHandler::~DevToolsHttpHandler() { | 343 DevToolsHttpHandler::~DevToolsHttpHandler() { |
347 TerminateOnUI(thread_, server_wrapper_, socket_factory_); | 344 TerminateOnUI(thread_, server_wrapper_, socket_factory_); |
348 base::STLDeleteValues(&descriptor_map_); | |
349 base::STLDeleteValues(&connection_to_client_); | |
350 } | 345 } |
351 | 346 |
352 GURL DevToolsHttpHandler::GetFrontendURL(const std::string& path) { | 347 GURL DevToolsHttpHandler::GetFrontendURL(const std::string& path) { |
353 if (!server_ip_address_) | 348 if (!server_ip_address_) |
354 return GURL(); | 349 return GURL(); |
355 return GURL(std::string("http://") + server_ip_address_->ToString() + | 350 return GURL(std::string("http://") + server_ip_address_->ToString() + |
356 (path.empty() ? frontend_url_ : path)); | 351 (path.empty() ? frontend_url_ : path)); |
357 } | 352 } |
358 | 353 |
359 static std::string PathWithoutParams(const std::string& path) { | 354 static std::string PathWithoutParams(const std::string& path) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 #if defined(OS_ANDROID) | 567 #if defined(OS_ANDROID) |
573 version.SetString("Android-Package", | 568 version.SetString("Android-Package", |
574 base::android::BuildInfo::GetInstance()->package_name()); | 569 base::android::BuildInfo::GetInstance()->package_name()); |
575 #endif | 570 #endif |
576 SendJson(connection_id, net::HTTP_OK, &version, std::string()); | 571 SendJson(connection_id, net::HTTP_OK, &version, std::string()); |
577 return; | 572 return; |
578 } | 573 } |
579 | 574 |
580 if (command == "list") { | 575 if (command == "list") { |
581 std::string host = info.headers["host"]; | 576 std::string host = info.headers["host"]; |
582 DevToolsTargetDescriptor::List descriptors = | 577 DevToolsAgentHost::List agent_host = |
583 devtools_discovery::DevToolsDiscoveryManager::GetInstance()-> | 578 devtools_discovery::DevToolsDiscoveryManager::GetInstance()-> |
584 GetDescriptors(); | 579 GetDescriptors(); |
585 std::sort(descriptors.begin(), descriptors.end(), TimeComparator); | 580 std::sort(agent_host.begin(), agent_host.end(), TimeComparator); |
586 base::STLDeleteValues(&descriptor_map_); | 581 agent_host_map_.clear(); |
587 base::ListValue list_value; | 582 base::ListValue list_value; |
588 for (DevToolsTargetDescriptor* descriptor : descriptors) { | 583 for (auto agent_host : agent_host) { |
589 descriptor_map_[descriptor->GetAgentHost()->GetId()] = descriptor; | 584 agent_host_map_[agent_host->GetId()] = agent_host; |
590 list_value.Append(SerializeDescriptor(*descriptor, host)); | 585 list_value.Append(SerializeDescriptor(agent_host, host)); |
591 } | 586 } |
592 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); | 587 SendJson(connection_id, net::HTTP_OK, &list_value, std::string()); |
593 return; | 588 return; |
594 } | 589 } |
595 | 590 |
596 if (command == "new") { | 591 if (command == "new") { |
597 GURL url(net::UnescapeURLComponent( | 592 GURL url(net::UnescapeURLComponent( |
598 query, net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS | | 593 query, net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS | |
599 net::UnescapeRule::PATH_SEPARATORS)); | 594 net::UnescapeRule::PATH_SEPARATORS)); |
600 if (!url.is_valid()) | 595 if (!url.is_valid()) |
601 url = GURL(url::kAboutBlankURL); | 596 url = GURL(url::kAboutBlankURL); |
602 std::unique_ptr<DevToolsTargetDescriptor> descriptor = | 597 scoped_refptr<DevToolsAgentHost> agent_host = |
603 devtools_discovery::DevToolsDiscoveryManager::GetInstance()->CreateNew( | 598 devtools_discovery::DevToolsDiscoveryManager::GetInstance()->CreateNew( |
604 url); | 599 url); |
605 if (!descriptor) { | 600 if (!agent_host) { |
606 SendJson(connection_id, | 601 SendJson(connection_id, |
607 net::HTTP_INTERNAL_SERVER_ERROR, | 602 net::HTTP_INTERNAL_SERVER_ERROR, |
608 NULL, | 603 NULL, |
609 "Could not create new page"); | 604 "Could not create new page"); |
610 return; | 605 return; |
611 } | 606 } |
612 std::string host = info.headers["host"]; | 607 std::string host = info.headers["host"]; |
613 std::unique_ptr<base::DictionaryValue> dictionary( | 608 std::unique_ptr<base::DictionaryValue> dictionary( |
614 SerializeDescriptor(*descriptor.get(), host)); | 609 SerializeDescriptor(agent_host, host)); |
615 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); | 610 SendJson(connection_id, net::HTTP_OK, dictionary.get(), std::string()); |
616 const std::string target_id = descriptor->GetAgentHost()->GetId(); | 611 const std::string target_id = agent_host->GetId(); |
617 descriptor_map_[target_id] = descriptor.release(); | 612 agent_host_map_[target_id] = agent_host; |
618 return; | 613 return; |
619 } | 614 } |
620 | 615 |
621 if (command == "activate" || command == "close") { | 616 if (command == "activate" || command == "close") { |
622 DevToolsTargetDescriptor* descriptor = GetDescriptor(target_id); | 617 scoped_refptr<DevToolsAgentHost> agent_host = GetAgentHost(target_id); |
623 if (!descriptor) { | 618 if (!agent_host) { |
624 SendJson(connection_id, | 619 SendJson(connection_id, |
625 net::HTTP_NOT_FOUND, | 620 net::HTTP_NOT_FOUND, |
626 NULL, | 621 NULL, |
627 "No such target id: " + target_id); | 622 "No such target id: " + target_id); |
628 return; | 623 return; |
629 } | 624 } |
630 | 625 |
631 if (command == "activate") { | 626 if (command == "activate") { |
632 if (descriptor->GetAgentHost()->Activate()) { | 627 if (agent_host->Activate()) { |
633 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); | 628 SendJson(connection_id, net::HTTP_OK, NULL, "Target activated"); |
634 } else { | 629 } else { |
635 SendJson(connection_id, | 630 SendJson(connection_id, |
636 net::HTTP_INTERNAL_SERVER_ERROR, | 631 net::HTTP_INTERNAL_SERVER_ERROR, |
637 NULL, | 632 NULL, |
638 "Could not activate target id: " + target_id); | 633 "Could not activate target id: " + target_id); |
639 } | 634 } |
640 return; | 635 return; |
641 } | 636 } |
642 | 637 |
643 if (command == "close") { | 638 if (command == "close") { |
644 if (descriptor->GetAgentHost()->Close()) { | 639 if (agent_host->Close()) { |
645 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); | 640 SendJson(connection_id, net::HTTP_OK, NULL, "Target is closing"); |
646 } else { | 641 } else { |
647 SendJson(connection_id, | 642 SendJson(connection_id, |
648 net::HTTP_INTERNAL_SERVER_ERROR, | 643 net::HTTP_INTERNAL_SERVER_ERROR, |
649 NULL, | 644 NULL, |
650 "Could not close target id: " + target_id); | 645 "Could not close target id: " + target_id); |
651 } | 646 } |
652 return; | 647 return; |
653 } | 648 } |
654 } | 649 } |
655 SendJson(connection_id, | 650 SendJson(connection_id, |
656 net::HTTP_NOT_FOUND, | 651 net::HTTP_NOT_FOUND, |
657 NULL, | 652 NULL, |
658 "Unknown command: " + command); | 653 "Unknown command: " + command); |
659 return; | 654 return; |
660 } | 655 } |
661 | 656 |
662 DevToolsTargetDescriptor* DevToolsHttpHandler::GetDescriptor( | 657 scoped_refptr<DevToolsAgentHost> DevToolsHttpHandler::GetAgentHost( |
663 const std::string& target_id) { | 658 const std::string& target_id) { |
664 DescriptorMap::const_iterator it = descriptor_map_.find(target_id); | 659 DescriptorMap::const_iterator it = agent_host_map_.find(target_id); |
665 if (it == descriptor_map_.end()) | 660 return it != agent_host_map_.end() ? it->second : nullptr; |
666 return nullptr; | |
667 return it->second; | |
668 } | 661 } |
669 | 662 |
670 void DevToolsHttpHandler::OnThumbnailRequest( | 663 void DevToolsHttpHandler::OnThumbnailRequest( |
671 int connection_id, const std::string& target_id) { | 664 int connection_id, const std::string& target_id) { |
672 DevToolsTargetDescriptor* descriptor = GetDescriptor(target_id); | 665 scoped_refptr<DevToolsAgentHost> agent_host = GetAgentHost(target_id); |
673 GURL page_url; | 666 GURL page_url; |
674 if (descriptor) | 667 if (agent_host) |
675 page_url = descriptor->GetAgentHost()->GetURL(); | 668 page_url = agent_host->GetURL(); |
676 std::string data = delegate_->GetPageThumbnailData(page_url); | 669 std::string data = delegate_->GetPageThumbnailData(page_url); |
677 if (!data.empty()) | 670 if (!data.empty()) |
678 Send200(connection_id, data, "image/png"); | 671 Send200(connection_id, data, "image/png"); |
679 else | 672 else |
680 Send404(connection_id); | 673 Send404(connection_id); |
681 } | 674 } |
682 | 675 |
683 void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) { | 676 void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) { |
684 std::string response = delegate_->GetDiscoveryPageHTML(); | 677 std::string response = delegate_->GetDiscoveryPageHTML(); |
685 Send200(connection_id, response, "text/html; charset=UTF-8"); | 678 Send200(connection_id, response, "text/html; charset=UTF-8"); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 return; | 717 return; |
725 } | 718 } |
726 | 719 |
727 if (!base::StartsWith(request.path, kPageUrlPrefix, | 720 if (!base::StartsWith(request.path, kPageUrlPrefix, |
728 base::CompareCase::SENSITIVE)) { | 721 base::CompareCase::SENSITIVE)) { |
729 Send404(connection_id); | 722 Send404(connection_id); |
730 return; | 723 return; |
731 } | 724 } |
732 | 725 |
733 std::string target_id = request.path.substr(strlen(kPageUrlPrefix)); | 726 std::string target_id = request.path.substr(strlen(kPageUrlPrefix)); |
734 DevToolsTargetDescriptor* descriptor = GetDescriptor(target_id); | 727 scoped_refptr<DevToolsAgentHost> agent = GetAgentHost(target_id); |
735 scoped_refptr<DevToolsAgentHost> agent = | 728 if (!agent) { |
736 descriptor ? descriptor->GetAgentHost() : nullptr; | |
737 if (!agent.get()) { | |
738 Send500(connection_id, "No such target id: " + target_id); | 729 Send500(connection_id, "No such target id: " + target_id); |
739 return; | 730 return; |
740 } | 731 } |
741 | 732 |
742 if (agent->IsAttached()) { | 733 if (agent->IsAttached()) { |
743 Send500(connection_id, | 734 Send500(connection_id, |
744 "Target with given id is being inspected: " + target_id); | 735 "Target with given id is being inspected: " + target_id); |
745 return; | 736 return; |
746 } | 737 } |
747 | 738 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 const net::HttpServerRequestInfo& request) { | 881 const net::HttpServerRequestInfo& request) { |
891 if (!thread_) | 882 if (!thread_) |
892 return; | 883 return; |
893 thread_->task_runner()->PostTask( | 884 thread_->task_runner()->PostTask( |
894 FROM_HERE, | 885 FROM_HERE, |
895 base::Bind(&ServerWrapper::AcceptWebSocket, | 886 base::Bind(&ServerWrapper::AcceptWebSocket, |
896 base::Unretained(server_wrapper_), connection_id, request)); | 887 base::Unretained(server_wrapper_), connection_id, request)); |
897 } | 888 } |
898 | 889 |
899 base::DictionaryValue* DevToolsHttpHandler::SerializeDescriptor( | 890 base::DictionaryValue* DevToolsHttpHandler::SerializeDescriptor( |
900 const DevToolsTargetDescriptor& descriptor, | 891 scoped_refptr<DevToolsAgentHost> agent_host, |
901 const std::string& host) { | 892 const std::string& host) { |
902 base::DictionaryValue* dictionary = new base::DictionaryValue; | 893 base::DictionaryValue* dictionary = new base::DictionaryValue; |
903 scoped_refptr<content::DevToolsAgentHost> agent_host = | |
904 descriptor.GetAgentHost(); | |
905 std::string id = agent_host->GetId(); | 894 std::string id = agent_host->GetId(); |
906 dictionary->SetString(kTargetIdField, id); | 895 dictionary->SetString(kTargetIdField, id); |
907 std::string parent_id = agent_host->GetParentId(); | 896 std::string parent_id = agent_host->GetParentId(); |
908 if (!parent_id.empty()) | 897 if (!parent_id.empty()) |
909 dictionary->SetString(kTargetParentIdField, parent_id); | 898 dictionary->SetString(kTargetParentIdField, parent_id); |
910 dictionary->SetString(kTargetTypeField, agent_host->GetType()); | 899 dictionary->SetString(kTargetTypeField, agent_host->GetType()); |
911 dictionary->SetString(kTargetTitleField, | 900 dictionary->SetString(kTargetTitleField, |
912 net::EscapeForHTML(agent_host->GetTitle())); | 901 net::EscapeForHTML(agent_host->GetTitle())); |
913 dictionary->SetString(kTargetDescriptionField, agent_host->GetDescription()); | 902 dictionary->SetString(kTargetDescriptionField, agent_host->GetDescription()); |
914 | 903 |
(...skipping 19 matching lines...) Expand all Loading... |
934 id.c_str(), | 923 id.c_str(), |
935 host); | 924 host); |
936 dictionary->SetString( | 925 dictionary->SetString( |
937 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | 926 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
938 } | 927 } |
939 | 928 |
940 return dictionary; | 929 return dictionary; |
941 } | 930 } |
942 | 931 |
943 } // namespace devtools_http_handler | 932 } // namespace devtools_http_handler |
OLD | NEW |