#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "chrome/test/chromedriver/server/http_handler.h"
#include <stddef.h>
#include <memory>
#include <optional>
#include <utility>
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/test/chromedriver/alert_commands.h"
#include "chrome/test/chromedriver/chrome/adb_impl.h"
#include "chrome/test/chromedriver/chrome/device_manager.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/command.h"
#include "chrome/test/chromedriver/commands.h"
#include "chrome/test/chromedriver/connection_session_map.h"
#include "chrome/test/chromedriver/constants/version.h"
#include "chrome/test/chromedriver/fedcm_commands.h"
#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "chrome/test/chromedriver/server/http_server.h"
#include "chrome/test/chromedriver/session.h"
#include "chrome/test/chromedriver/session_thread_map.h"
#include "chrome/test/chromedriver/util.h"
#include "chrome/test/chromedriver/webauthn_commands.h"
#include "chrome/test/chromedriver/window_commands.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/server/http_server_request_info.h"
#include "net/server/http_server_response_info.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/transitional_url_loader_factory_owner.h"
#include "url/url_util.h"
#if BUILDFLAG(IS_MAC)
#include "base/apple/scoped_nsautorelease_pool.h"
#endif
const char kCreateWebSocketPath[] = …;
const char kSendCommandFromWebSocket[] = …;
namespace {
const char kLocalStorage[] = …;
const char kSessionStorage[] = …;
const char kShutdownPath[] = …;
base::flat_set<std::string> kKnownBidiSessionCommands = …;
std::optional<base::Value> Clone(const std::optional<base::Value>& original) { … }
bool w3cMode(const std::string& session_id,
const SessionThreadMap& session_thread_map) { … }
net::HttpServerResponseInfo CreateWebSocketRejectResponse(
net::HttpStatusCode code,
const std::string& msg) { … }
void AddBidiConnectionOnSessionThread(int connection_id,
SendTextFunc send_response,
CloseFunc close_connection) { … }
void RemoveBidiConnectionOnSessionThread(int connection_id) { … }
bool MatchesMethod(HttpMethod command_method, const std::string& method) { … }
}
class WrapperURLLoaderFactory : public network::mojom::URLLoaderFactory { … };
CommandMapping::CommandMapping(HttpMethod method,
const std::string& path_pattern,
const Command& command)
: … { … }
CommandMapping::CommandMapping(const CommandMapping& other) = default;
CommandMapping::~CommandMapping() = default;
CommandMapping VendorPrefixedCommandMapping(HttpMethod method,
const char* path_pattern,
const Command& command) { … }
HttpHandler::HttpHandler(const std::string& url_base)
: … { … }
HttpHandler::HttpHandler(
const base::RepeatingClosure& quit_func,
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner> cmd_task_runner,
const std::string& url_base,
int adb_port)
: … { … }
HttpHandler::~HttpHandler() = default;
void HttpHandler::Handle(const net::HttpServerRequestInfo& request,
const HttpResponseSenderFunc& send_response_func) { … }
base::WeakPtr<HttpHandler> HttpHandler::WeakPtr() { … }
Command HttpHandler::WrapToCommand(const char* name,
const SessionCommand& session_command,
bool w3c_standard_command) { … }
Command HttpHandler::WrapToCommand(const char* name,
const WindowCommand& window_command,
bool w3c_standard_command) { … }
Command HttpHandler::WrapToCommand(const char* name,
const ElementCommand& element_command,
bool w3c_standard_command) { … }
void HttpHandler::HandleCommand(
const net::HttpServerRequestInfo& request,
const std::string& trimmed_path,
const HttpResponseSenderFunc& send_response_func) { … }
void HttpHandler::PrepareResponse(
const std::string& trimmed_path,
const HttpResponseSenderFunc& send_response_func,
const Status& status,
std::unique_ptr<base::Value> value,
const std::string& session_id,
bool w3c_compliant) { … }
std::unique_ptr<net::HttpServerResponseInfo> HttpHandler::PrepareLegacyResponse(
const std::string& trimmed_path,
const Status& status,
std::unique_ptr<base::Value> value,
const std::string& session_id) { … }
std::unique_ptr<net::HttpServerResponseInfo>
HttpHandler::PrepareStandardResponse(
const std::string& trimmed_path,
const Status& status,
std::unique_ptr<base::Value> value,
const std::string& session_id) { … }
void HttpHandler::OnWebSocketRequest(HttpServerInterface* http_server,
int connection_id,
const net::HttpServerRequestInfo& info) { … }
void HttpHandler::CloseConnectionOnCommandThread(
HttpServerInterface* http_server,
int connection_id) { … }
void HttpHandler::SendForwardedResponseOnCommandThread(
HttpServerInterface* http_server,
int connection_id,
std::string message) { … }
void HttpHandler::OnWebSocketAttachToSessionRequest(
HttpServerInterface* http_server,
int connection_id,
const std::string& session_id,
const net::HttpServerRequestInfo& info) { … }
void HttpHandler::OnWebSocketUnboundConnectionRequest(
HttpServerInterface* http_server,
int connection_id,
const net::HttpServerRequestInfo& info) { … }
void HttpHandler::SendResponseOverWebSocket(
HttpServerInterface* http_server,
int connection_id,
const std::optional<base::Value>& maybe_id,
const Status& status,
std::unique_ptr<base::Value> result,
const std::string& session_id,
bool w3c) { … }
Command HttpHandler::WrapCreateNewSessionCommand(Command command) { … }
void HttpHandler::OnNewSessionCreated(const CommandCallback& next_callback,
const Status& status,
std::unique_ptr<base::Value> result,
const std::string& session_id,
bool w3c) { … }
void HttpHandler::OnNewBidiSessionOnCmdThread(
HttpServerInterface* http_server,
int connection_id,
const std::optional<base::Value>& maybe_id,
const Status& status,
std::unique_ptr<base::Value> result,
const std::string& session_id,
bool w3c) { … }
void HttpHandler::OnWebSocketMessage(HttpServerInterface* http_server,
int connection_id,
const std::string& data) { … }
void HttpHandler::OnWebSocketResponseOnCmdThread(
HttpServerInterface* http_server,
int connection_id,
const std::string& data) { … }
void HttpHandler::OnWebSocketResponseOnSessionThread(
HttpServerInterface* http_server,
int connection_id,
const std::string& data) { … }
void HttpHandler::OnClose(HttpServerInterface* http_server, int connection_id) { … }
void HttpHandler::SendWebSocketRejectResponse(
base::RepeatingCallback<void(int,
const net::HttpServerResponseInfo&,
const net::NetworkTrafficAnnotationTag&)>
send_http_response,
int connection_id,
net::HttpStatusCode code,
const std::string& msg) { … }
const char internal::kNewSessionPathPattern[] = …;
bool internal::MatchesCommand(const std::string& method,
const std::string& path,
const CommandMapping& command,
std::string* session_id,
base::Value::Dict* out_params) { … }
bool internal::IsNewSession(const CommandMapping& command) { … }
Status internal::ParseBidiCommand(const std::string& data,
base::Value::Dict& parsed) { … }
base::Value::Dict internal::CreateBidiErrorResponse(
Status status,
std::optional<base::Value> maybe_id) { … }