Chromium Code Reviews| 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_hosts = |
| 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_hosts.begin(), agent_hosts.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_hosts) { |
| 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, |
|
dcheng
2016/08/26 21:43:44
Btw, I might be missing something, but I'm a bit c
pfeldman
2016/08/26 22:31:32
Moving ownership is only essential for movable / u
| |
| 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 |