1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131

content / browser / devtools / devtools_http_handler.h [blame]

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_HTTP_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_HTTP_HANDLER_H_

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>

#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "content/public/browser/devtools_agent_host.h"
#include "net/http/http_status_code.h"

namespace base {
class Thread;
}

namespace content {
class DevToolsManagerDelegate;
class DevToolsSocketFactory;
}

namespace net {
class IPEndPoint;
class HttpServerRequestInfo;
}

namespace content {

class DevToolsAgentHostClientImpl;
class ServerWrapper;

// This class is used for managing DevTools remote debugging server.
// Clients can connect to the specified ip:port and start debugging
// this browser.
class DevToolsHttpHandler {
 public:
  // Takes ownership over |socket_factory|.
  // |delegate| is only accessed on UI thread.
  // If |active_port_output_directory| is non-empty, it is assumed the
  // socket_factory was initialized with an ephemeral port (0). The
  // port selected by the OS will be written to a well-known file in
  // the output directory.
  DevToolsHttpHandler(
      DevToolsManagerDelegate* delegate,
      std::unique_ptr<DevToolsSocketFactory> server_socket_factory,
      const base::FilePath& active_port_output_directory,
      const base::FilePath& debug_frontend_dir);

  DevToolsHttpHandler(const DevToolsHttpHandler&) = delete;
  DevToolsHttpHandler& operator=(const DevToolsHttpHandler&) = delete;

  ~DevToolsHttpHandler();

 private:
  friend class ServerWrapper;
  friend void ServerStartedOnUI(
      base::WeakPtr<DevToolsHttpHandler> handler,
      base::Thread* thread,
      ServerWrapper* server_wrapper,
      DevToolsSocketFactory* socket_factory,
      std::unique_ptr<net::IPEndPoint> ip_address);

  void OnJsonRequest(int connection_id,
                     const net::HttpServerRequestInfo& info);
  void RespondToJsonList(int connection_id,
                         const std::string& host,
                         DevToolsAgentHost::List agent_hosts,
                         bool for_tab);
  void OnDiscoveryPageRequest(int connection_id);
  void OnFrontendResourceRequest(int connection_id, const std::string& path);
  void OnWebSocketRequest(int connection_id,
                          const net::HttpServerRequestInfo& info);
  void OnWebSocketMessage(int connection_id, std::string data);
  void OnClose(int connection_id);

  void ServerStarted(std::unique_ptr<base::Thread> thread,
                     std::unique_ptr<ServerWrapper> server_wrapper,
                     std::unique_ptr<DevToolsSocketFactory> socket_factory,
                     std::unique_ptr<net::IPEndPoint> ip_address);

  void SendJson(int connection_id,
                net::HttpStatusCode status_code,
                std::optional<base::ValueView> value,
                const std::string& message);
  void Send200(int connection_id,
               const std::string& data,
               const std::string& mime_type);
  void Send404(int connection_id);
  void Send403(int connection_id, const std::string& message);
  void Send500(int connection_id,
               const std::string& message);
  void AcceptWebSocket(int connection_id,
                       const net::HttpServerRequestInfo& request);

  void DecompressAndSendJsonProtocol(int connection_id);

  // Returns the front end url without the host at the beginning.
  std::string GetFrontendURLInternal(
      scoped_refptr<DevToolsAgentHost> agent_host,
      const std::string& target_id,
      const std::string& host);

  base::Value::Dict SerializeDescriptor(
      scoped_refptr<DevToolsAgentHost> agent_host,
      const std::string& host);

  std::set<std::string> remote_allow_origins_;
  // The thread used by the devtools handler to run server socket.
  std::unique_ptr<base::Thread> thread_;
  std::string browser_guid_;
  std::unique_ptr<ServerWrapper> server_wrapper_;
  std::unique_ptr<net::IPEndPoint> server_ip_address_;
  using ConnectionToClientMap =
      std::map<int, std::unique_ptr<DevToolsAgentHostClientImpl>>;
  ConnectionToClientMap connection_to_client_;
  raw_ptr<DevToolsManagerDelegate> delegate_;
  std::unique_ptr<DevToolsSocketFactory> socket_factory_;
  base::WeakPtrFactory<DevToolsHttpHandler> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_HTTP_HANDLER_H_