#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/browser/devtools/devtools_http_handler.h"
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <memory>
#include <optional>
#include <string_view>
#include <utility>
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_pump_type.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread.h"
#include "base/uuid.h"
#include "base/values.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/devtools_manager_delegate.h"
#include "content/public/browser/devtools_socket_factory.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/user_agent.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/http/http_request_headers.h"
#include "net/server/http_server.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
#include "net/socket/server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "v8/include/v8-version-string.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#endif
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
extern const int kCcompressedProtocolJSON;
#endif
namespace content {
namespace {
const base::FilePath::CharType kDevToolsActivePortFileName[] = …);
const char kDevToolsHandlerThreadName[] = …;
const char kPageUrlPrefix[] = …;
const char kBrowserUrlPrefix[] = …;
const char kTargetIdField[] = …;
const char kTargetParentIdField[] = …;
const char kTargetTypeField[] = …;
const char kTargetTitleField[] = …;
const char kTargetDescriptionField[] = …;
const char kTargetUrlField[] = …;
const char kTargetFaviconUrlField[] = …;
const char kTargetWebSocketDebuggerUrlField[] = …;
const char kTargetDevtoolsFrontendUrlField[] = …;
const int32_t kSendBufferSizeForDevTools = …;
const int32_t kReceiveBufferSizeForDevTools = …;
const char kRemoteUrlPattern[] = …"https://chrome-devtools-frontend.appspot.com/serve_internal_file/%s/"
"%s.html";
#else
"https://chrome-devtools-frontend.appspot.com/serve_rev/%s/%s.html";
#endif
constexpr net::NetworkTrafficAnnotationTag
kDevtoolsHttpHandlerTrafficAnnotation = …;
bool RequestIsSafeToServe(const net::HttpServerRequestInfo& info) { … }
}
class ServerWrapper : net::HttpServer::Delegate { … };
ServerWrapper::ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler,
std::unique_ptr<net::ServerSocket> socket,
const base::FilePath& debug_frontend_dir,
bool bundles_resources)
: … { … }
int ServerWrapper::GetLocalAddress(net::IPEndPoint* address) { … }
void ServerWrapper::AcceptWebSocket(int connection_id,
const net::HttpServerRequestInfo& request) { … }
void ServerWrapper::SendOverWebSocket(int connection_id, std::string message) { … }
void ServerWrapper::SendResponse(int connection_id,
const net::HttpServerResponseInfo& response) { … }
void ServerWrapper::Send200(int connection_id,
const std::string& data,
const std::string& mime_type) { … }
void ServerWrapper::Send404(int connection_id) { … }
void ServerWrapper::Send500(int connection_id,
const std::string& message) { … }
void ServerWrapper::Close(int connection_id) { … }
void TerminateOnUI(std::unique_ptr<base::Thread> thread,
std::unique_ptr<ServerWrapper> server_wrapper,
std::unique_ptr<DevToolsSocketFactory> socket_factory) { … }
void ServerStartedOnUI(base::WeakPtr<DevToolsHttpHandler> handler,
base::Thread* thread,
ServerWrapper* server_wrapper,
DevToolsSocketFactory* socket_factory,
std::unique_ptr<net::IPEndPoint> ip_address) { … }
void StartServerOnHandlerThread(
base::WeakPtr<DevToolsHttpHandler> handler,
std::unique_ptr<base::Thread> thread,
std::unique_ptr<DevToolsSocketFactory> socket_factory,
const base::FilePath& output_directory,
const base::FilePath& debug_frontend_dir,
const std::string& browser_guid,
bool bundles_resources) { … }
class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { … };
static bool TimeComparator(scoped_refptr<DevToolsAgentHost> host1,
scoped_refptr<DevToolsAgentHost> host2) { … }
DevToolsHttpHandler::~DevToolsHttpHandler() { … }
static std::string PathWithoutParams(const std::string& path) { … }
static std::string GetMimeType(const std::string& filename) { … }
void ServerWrapper::OnHttpRequest(int connection_id,
const net::HttpServerRequestInfo& info) { … }
void ServerWrapper::OnWebSocketRequest(
int connection_id,
const net::HttpServerRequestInfo& request) { … }
void ServerWrapper::OnWebSocketMessage(int connection_id, std::string data) { … }
void ServerWrapper::OnClose(int connection_id) { … }
std::string DevToolsHttpHandler::GetFrontendURLInternal(
scoped_refptr<DevToolsAgentHost> agent_host,
const std::string& id,
const std::string& host) { … }
static bool ParseJsonPath(
const std::string& path,
std::string* command,
std::string* target_id) { … }
void DevToolsHttpHandler::OnJsonRequest(
int connection_id,
const net::HttpServerRequestInfo& info) { … }
void DevToolsHttpHandler::DecompressAndSendJsonProtocol(int connection_id) { … }
void DevToolsHttpHandler::RespondToJsonList(int connection_id,
const std::string& host,
DevToolsAgentHost::List hosts,
bool for_tab) { … }
void DevToolsHttpHandler::OnDiscoveryPageRequest(int connection_id) { … }
void DevToolsHttpHandler::OnFrontendResourceRequest(
int connection_id, const std::string& path) { … }
void DevToolsHttpHandler::OnWebSocketRequest(
int connection_id,
const net::HttpServerRequestInfo& request) { … }
void DevToolsHttpHandler::OnWebSocketMessage(int connection_id,
std::string data) { … }
void DevToolsHttpHandler::OnClose(int connection_id) { … }
DevToolsHttpHandler::DevToolsHttpHandler(
DevToolsManagerDelegate* delegate,
std::unique_ptr<DevToolsSocketFactory> socket_factory,
const base::FilePath& output_directory,
const base::FilePath& debug_frontend_dir)
: … { … }
void DevToolsHttpHandler::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 DevToolsHttpHandler::SendJson(int connection_id,
net::HttpStatusCode status_code,
std::optional<base::ValueView> value,
const std::string& message) { … }
void DevToolsHttpHandler::Send200(int connection_id,
const std::string& data,
const std::string& mime_type) { … }
void DevToolsHttpHandler::Send404(int connection_id) { … }
void DevToolsHttpHandler::Send403(int connection_id,
const std::string& message) { … }
void DevToolsHttpHandler::Send500(int connection_id,
const std::string& message) { … }
void DevToolsHttpHandler::AcceptWebSocket(
int connection_id,
const net::HttpServerRequestInfo& request) { … }
base::Value::Dict DevToolsHttpHandler::SerializeDescriptor(
scoped_refptr<DevToolsAgentHost> agent_host,
const std::string& host) { … }
}