• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "libcef/browser/devtools/devtools_manager_delegate.h"
6 
7 #include <stdint.h>
8 
9 #include <vector>
10 
11 #include "base/atomicops.h"
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/files/file_path.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "build/build_config.h"
20 #include "cef/grit/cef_resources.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/devtools_agent_host.h"
23 #include "content/public/browser/devtools_frontend_host.h"
24 #include "content/public/browser/devtools_socket_factory.h"
25 #include "content/public/browser/favicon_status.h"
26 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/content_switches.h"
30 #include "content/public/common/url_constants.h"
31 #include "content/public/common/user_agent.h"
32 #include "net/base/net_errors.h"
33 #include "net/log/net_log_source.h"
34 #include "net/socket/tcp_server_socket.h"
35 #include "ui/base/resource/resource_bundle.h"
36 
37 namespace {
38 
39 const int kBackLog = 10;
40 
41 class TCPServerSocketFactory : public content::DevToolsSocketFactory {
42  public:
TCPServerSocketFactory(const std::string & address,uint16_t port)43   TCPServerSocketFactory(const std::string& address, uint16_t port)
44       : address_(address), port_(port) {}
45 
46   TCPServerSocketFactory(const TCPServerSocketFactory&) = delete;
47   TCPServerSocketFactory& operator=(const TCPServerSocketFactory&) = delete;
48 
49  private:
50   // content::DevToolsSocketFactory.
CreateForHttpServer()51   std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
52     std::unique_ptr<net::ServerSocket> socket(
53         new net::TCPServerSocket(nullptr, net::NetLogSource()));
54     if (socket->ListenWithAddressAndPort(address_, port_, kBackLog) != net::OK)
55       return std::unique_ptr<net::ServerSocket>();
56     return socket;
57   }
58 
CreateForTethering(std::string * out_name)59   std::unique_ptr<net::ServerSocket> CreateForTethering(
60       std::string* out_name) override {
61     return nullptr;
62   }
63 
64   std::string address_;
65   uint16_t port_;
66 };
67 
CreateSocketFactory()68 std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
69   const base::CommandLine& command_line =
70       *base::CommandLine::ForCurrentProcess();
71   // See if the user specified a port on the command line. Specifying 0 would
72   // result in the selection of an ephemeral port but that doesn't make sense
73   // for CEF where the URL is otherwise undiscoverable. Also, don't allow
74   // binding of ports between 0 and 1024 exclusive because they're normally
75   // restricted to root on Posix-based systems.
76   uint16_t port = 0;
77   if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
78     int temp_port;
79     std::string port_str =
80         command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
81     if (base::StringToInt(port_str, &temp_port) && temp_port >= 1024 &&
82         temp_port < 65535) {
83       port = static_cast<uint16_t>(temp_port);
84     } else {
85       DLOG(WARNING) << "Invalid http debugger port number " << temp_port;
86     }
87   }
88   if (port == 0)
89     return nullptr;
90   return std::unique_ptr<content::DevToolsSocketFactory>(
91       new TCPServerSocketFactory("127.0.0.1", port));
92 }
93 
94 }  //  namespace
95 
96 // CefDevToolsManagerDelegate ----------------------------------------------
97 
98 // static
StartHttpHandler(content::BrowserContext * browser_context)99 void CefDevToolsManagerDelegate::StartHttpHandler(
100     content::BrowserContext* browser_context) {
101   std::unique_ptr<content::DevToolsSocketFactory> socket_factory =
102       CreateSocketFactory();
103   if (!socket_factory)
104     return;
105   content::DevToolsAgentHost::StartRemoteDebuggingServer(
106       std::move(socket_factory), browser_context->GetPath(), base::FilePath());
107 
108   const base::CommandLine& command_line =
109       *base::CommandLine::ForCurrentProcess();
110   if (command_line.HasSwitch(switches::kRemoteDebuggingPipe)) {
111     content::DevToolsAgentHost::StartRemoteDebuggingPipeHandler(
112         base::OnceClosure());
113   }
114 }
115 
116 // static
StopHttpHandler()117 void CefDevToolsManagerDelegate::StopHttpHandler() {
118   // This is a no-op if the server was never started.
119   content::DevToolsAgentHost::StopRemoteDebuggingServer();
120 }
121 
CefDevToolsManagerDelegate()122 CefDevToolsManagerDelegate::CefDevToolsManagerDelegate() {}
123 
~CefDevToolsManagerDelegate()124 CefDevToolsManagerDelegate::~CefDevToolsManagerDelegate() {}
125 
126 scoped_refptr<content::DevToolsAgentHost>
CreateNewTarget(const GURL & url)127 CefDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
128   // This is reached when the user selects "Open link in new tab" from the
129   // DevTools interface.
130   // TODO(cef): Consider exposing new API to support this.
131   return nullptr;
132 }
133 
GetDiscoveryPageHTML()134 std::string CefDevToolsManagerDelegate::GetDiscoveryPageHTML() {
135   return ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
136       IDR_CEF_DEVTOOLS_DISCOVERY_PAGE);
137 }
138 
HasBundledFrontendResources()139 bool CefDevToolsManagerDelegate::HasBundledFrontendResources() {
140   return true;
141 }
142