// 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.

#include "content/browser/devtools/devtools_http_handler.h"

#include <stdint.h>

#include <memory>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_agent_host_impl.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_manager_delegate.h"
#include "content/public/browser/devtools_socket_factory.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_devtools_agent_host.h"
#include "content/public/test/test_utils.h"
#include "net/base/completion_once_callback.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/socket/server_socket.h"
#include "net/socket/tcp_server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

using ::testing::HasSubstr;
using ::testing::Not;
using ::testing::Return;

const uint16_t kDummyPort = 4321;

class DummyServerSocket : public net::ServerSocket {
 public:
  // net::ServerSocket "implementation"
  int Listen(const net::IPEndPoint& address,
             int backlog,
             std::optional<bool> ipv6_only) override {
    return net::OK;
  }

  int GetLocalAddress(net::IPEndPoint* address) const override {
    *address = net::IPEndPoint(net::IPAddress::IPv4Localhost(), kDummyPort);
    return net::OK;
  }

  int Accept(std::unique_ptr<net::StreamSocket>* socket,
             net::CompletionOnceCallback callback) override {
    return net::ERR_IO_PENDING;
  }
};

class DummyServerSocketFactory : public DevToolsSocketFactory {
 public:
  DummyServerSocketFactory(base::OnceClosure create_socket_callback,
                           base::OnceClosure shutdown_callback)
      : create_socket_callback_(std::move(create_socket_callback)),
        shutdown_callback_(std::move(shutdown_callback)) {}

  ~DummyServerSocketFactory() override {
    GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                        std::move(shutdown_callback_));
  }

 protected:
  std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
    GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                        std::move(create_socket_callback_));
    return std::make_unique<DummyServerSocket>();
  }

  std::unique_ptr<net::ServerSocket> CreateForTethering(
      std::string* out_name) override {
    return nullptr;
  }

  base::OnceClosure create_socket_callback_;
  base::OnceClosure shutdown_callback_;
};

class FailingServerSocketFactory : public DummyServerSocketFactory {
 public:
  FailingServerSocketFactory(base::OnceClosure create_socket_callback,
                             base::OnceClosure shutdown_callback)
      : DummyServerSocketFactory(std::move(create_socket_callback),
                                 std::move(shutdown_callback)) {}

 private:
  std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
    GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                        std::move(create_socket_callback_));
    return nullptr;
  }
};

class TCPServerSocketFactory : public DummyServerSocketFactory {
 public:
  TCPServerSocketFactory(base::OnceClosure create_socket_callback,
                         base::OnceClosure shutdown_callback)
      : DummyServerSocketFactory(std::move(create_socket_callback),
                                 std::move(shutdown_callback)) {}

  int port() { return port_; }

 private:
  std::unique_ptr<net::ServerSocket> CreateForHttpServer() override {
    std::unique_ptr<net::ServerSocket> socket(
        new net::TCPServerSocket(nullptr, net::NetLogSource()));
    while (socket->ListenWithAddressAndPort("127.0.0.1", port_, 10) !=
           net::OK) {
      if (++port_ > kDummyPort + 100)
        return nullptr;
    }
    GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                        std::move(create_socket_callback_));
    return socket;
  }

  int port_ = kDummyPort;
};

class MockDevToolsManagerDelegate : public DevToolsManagerDelegate {
 public:
  static MockDevToolsManagerDelegate* last_instance;
  MockDevToolsManagerDelegate() {
    last_instance = this;
    EXPECT_CALL(*this, SetActiveWebSocketConnections(testing::_))
        .Times(testing::AtLeast(0));
  }
  MOCK_METHOD(scoped_refptr<DevToolsAgentHost>,
              CreateNewTarget,
              (const GURL& url, TargetType target_type, bool new_window),
              (override));
  MOCK_METHOD(DevToolsAgentHost::List,
              RemoteDebuggingTargets,
              (TargetType target_type),
              (override));
  MOCK_METHOD(void,
              AcceptDebugging,
              (base::OnceCallback<void(AcceptConnectionResult)> callback),
              (override));
  MOCK_METHOD(void,
              SetActiveWebSocketConnections,
              (size_t count),
              (override));
};

MockDevToolsManagerDelegate* MockDevToolsManagerDelegate::last_instance =
    nullptr;

class MockDevToolsAgentHostWithType : public MockDevToolsAgentHost {
 public:
  explicit MockDevToolsAgentHostWithType(const std::string& type)
      : type_(type) {}

  std::string GetType() override { return type_; }

 private:
  ~MockDevToolsAgentHostWithType() override = default;

  std::string type_;
};

class BrowserClient : public ContentBrowserClient {
 public:
  BrowserClient() {}
  ~BrowserClient() override {}
  std::unique_ptr<content::DevToolsManagerDelegate>
  CreateDevToolsManagerDelegate() override {
    return std::make_unique<MockDevToolsManagerDelegate>();
  }
};

}

class DevToolsHttpHandlerTest : public testing::Test {
 public:
  DevToolsHttpHandlerTest()
      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}

  void SetUp() override {
    content_client_ = std::make_unique<ContentClient>();
    browser_content_client_ = std::make_unique<BrowserClient>();
    original_client_ =
        SetBrowserClientForTesting(browser_content_client_.get());
    DevToolsManager::ShutdownForTests();
  }

  void TearDown() override {
    SetBrowserClientForTesting(original_client_);
    DevToolsManager::ShutdownForTests();
  }

 private:
  std::unique_ptr<ContentClient> content_client_;
  std::unique_ptr<ContentBrowserClient> browser_content_client_;
  raw_ptr<ContentBrowserClient> original_client_ = nullptr;
  content::BrowserTaskEnvironment task_environment_;
};

TEST_F(DevToolsHttpHandlerTest, TestStartStop) {
  base::RunLoop run_loop, run_loop_2;
  auto factory = std::make_unique<DummyServerSocketFactory>(
      run_loop.QuitClosure(), run_loop_2.QuitClosure());
  DevToolsAgentHost::StartRemoteDebuggingServer(
      std::move(factory), base::FilePath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();
}

TEST_F(DevToolsHttpHandlerTest, TestServerSocketFailed) {
  base::RunLoop run_loop, run_loop_2;
  auto factory = std::make_unique<FailingServerSocketFactory>(
      run_loop.QuitClosure(), run_loop_2.QuitClosure());
  LOG(INFO) << "Following error message is expected:";
  DevToolsAgentHost::StartRemoteDebuggingServer(
      std::move(factory), base::FilePath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  for (int i = 0; i < 5; i++)
    RunAllPendingInMessageLoop(BrowserThread::UI);
  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();
}

TEST_F(DevToolsHttpHandlerTest, TestDevToolsActivePort) {
  base::RunLoop run_loop, run_loop_2;
  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
  auto factory = std::make_unique<DummyServerSocketFactory>(
      run_loop.QuitClosure(), run_loop_2.QuitClosure());

  DevToolsAgentHost::StartRemoteDebuggingServer(
      std::move(factory), temp_dir.GetPath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();

  // Now make sure the DevToolsActivePort was written into the
  // temporary directory and its contents are as expected.
  base::FilePath active_port_file =
      temp_dir.GetPath().Append(kDevToolsActivePortFileName);
  EXPECT_TRUE(base::PathExists(active_port_file));
  std::string file_contents;
  EXPECT_TRUE(base::ReadFileToString(active_port_file, &file_contents));
  std::vector<std::string> tokens = base::SplitString(
      file_contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  int port = 0;
  EXPECT_TRUE(base::StringToInt(tokens[0], &port));
  EXPECT_EQ(static_cast<int>(kDummyPort), port);
}

TEST_F(DevToolsHttpHandlerTest, MutatingActionsiRequireSafeVerb) {
  base::RunLoop run_loop, run_loop_2;
  auto* factory = new TCPServerSocketFactory(run_loop.QuitClosure(),
                                             run_loop_2.QuitClosure());
  DevToolsAgentHost::StartRemoteDebuggingServer(
      base::WrapUnique(factory), base::FilePath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  int port = factory->port();

  net::TestDelegate delegate;
  GURL url(base::StringPrintf("http://127.0.0.1:%d/json/new", port));
  auto request_context = net::CreateTestURLRequestContextBuilder()->Build();
  auto request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);
  EXPECT_EQ(405, request->response_info().headers->response_code());

  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("POST");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);
  EXPECT_EQ(405, request->response_info().headers->response_code());

  EXPECT_CALL(
      *MockDevToolsManagerDelegate::last_instance,
      CreateNewTarget(GURL("about:blank"), DevToolsManagerDelegate::kFrame,
                      /*new_window=*/false))
      .WillOnce(Return(base::MakeRefCounted<MockDevToolsAgentHost>()));

  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);
  EXPECT_EQ(200, request->response_info().headers->response_code());

  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();
}

TEST_F(DevToolsHttpHandlerTest, TestJsonNew) {
  base::RunLoop run_loop, run_loop_2;
  auto* factory = new TCPServerSocketFactory(run_loop.QuitClosure(),
                                             run_loop_2.QuitClosure());
  DevToolsAgentHost::StartRemoteDebuggingServer(
      base::WrapUnique(factory), base::FilePath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  int port = factory->port();
  net::TestDelegate delegate;

  EXPECT_CALL(
      *MockDevToolsManagerDelegate::last_instance,
      CreateNewTarget(GURL("about:blank"), DevToolsManagerDelegate::kFrame,
                      /*new_window=*/false));
  GURL url(base::StringPrintf("http://127.0.0.1:%d/json/new", port));
  auto request_context = net::CreateTestURLRequestContextBuilder()->Build();
  auto request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);

  EXPECT_CALL(
      *MockDevToolsManagerDelegate::last_instance,
      CreateNewTarget(GURL("http://example.com"),
                      DevToolsManagerDelegate::kFrame, /*new_window=*/false));
  url = GURL(base::StringPrintf(
      "http://127.0.0.1:%d/json/new?%s", port,
      base::EscapeQueryParamValue("http://example.com", true).c_str()));
  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);

  EXPECT_CALL(
      *MockDevToolsManagerDelegate::last_instance,
      CreateNewTarget(GURL("http://example.com"), DevToolsManagerDelegate::kTab,
                      /*new_window=*/false));
  url = GURL(base::StringPrintf(
      "http://127.0.0.1:%d/json/new?%s&for_tab", port,
      base::EscapeQueryParamValue("http://example.com", true).c_str()));
  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_GE(delegate.request_status(), 0);

  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();
}

TEST_F(DevToolsHttpHandlerTest, TestJsonList) {
  base::RunLoop run_loop, run_loop_2;
  auto* factory = new TCPServerSocketFactory(run_loop.QuitClosure(),
                                             run_loop_2.QuitClosure());
  DevToolsAgentHost::StartRemoteDebuggingServer(
      base::WrapUnique(factory), base::FilePath(), base::FilePath());
  // Our dummy socket factory will post a quit message once the server will
  // become ready.
  run_loop.Run();
  int port = factory->port();
  net::TestDelegate delegate;

  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance,
              RemoteDebuggingTargets(DevToolsManagerDelegate::kFrame));
  GURL url(base::StringPrintf("http://127.0.0.1:%d/json", port));
  auto request_context = net::CreateTestURLRequestContextBuilder()->Build();
  auto request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();

  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance,
              RemoteDebuggingTargets(DevToolsManagerDelegate::kFrame))
      .WillOnce(Return(std::vector<scoped_refptr<DevToolsAgentHost>>{
          base::MakeRefCounted<MockDevToolsAgentHostWithType>("service_worker"),
          base::MakeRefCounted<MockDevToolsAgentHostWithType>("tab")}));
  url = GURL(base::StringPrintf("http://127.0.0.1:%d/json/list", port));
  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_THAT(delegate.data_received(),
              HasSubstr(R"("type": "service_worker")"));
  EXPECT_THAT(delegate.data_received(), Not(HasSubstr(R"("type": "tab")")));

  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance,
              RemoteDebuggingTargets(DevToolsManagerDelegate::kTab))
      .WillOnce(Return(std::vector<scoped_refptr<DevToolsAgentHost>>{
          base::MakeRefCounted<MockDevToolsAgentHostWithType>("service_worker"),
          base::MakeRefCounted<MockDevToolsAgentHostWithType>("tab")}));
  url = GURL(base::StringPrintf("http://127.0.0.1:%d/json/list?for_tab", port));
  request = request_context->CreateRequest(
      url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
  request->set_method("PUT");
  request->Start();
  delegate.RunUntilComplete();
  EXPECT_THAT(delegate.data_received(),
              HasSubstr(R"("type": "service_worker")"));
  EXPECT_THAT(delegate.data_received(), HasSubstr(R"("type": "tab")"));

  DevToolsAgentHost::StopRemoteDebuggingServer();
  // Make sure the handler actually stops.
  run_loop_2.Run();
}

class DevToolsHttpHandlerWithServerTest : public DevToolsHttpHandlerTest {
 public:
  DevToolsHttpHandlerWithServerTest() = default;

  int StartServer(
      DevToolsAgentHost::RemoteDebuggingServerMode mode =
          DevToolsAgentHost::RemoteDebuggingServerMode::kDefault) {
    std::unique_ptr<TCPServerSocketFactory> factory =
        std::make_unique<TCPServerSocketFactory>(run_loop_.QuitClosure(),
                                                 run_loop_2_.QuitClosure());
    TCPServerSocketFactory* factory_raw = factory.get();

    DevToolsAgentHost::StartRemoteDebuggingServer(
        std::move(factory), base::FilePath(), base::FilePath(), mode);
    // Our dummy socket factory will post a quit message once the server will
    // become ready.
    run_loop_.Run();
    return factory_raw->port();
  }

  void StopServer() {
    DevToolsAgentHost::StopRemoteDebuggingServer();
    run_loop_2_.Run();
  }

  std::unique_ptr<net::URLRequest> RunRequestUntilCompletion(
      std::string url,
      std::map<std::string, std::string> headers = {}) {
    net::TestDelegate delegate;
    auto request = request_context_->CreateRequest(
        GURL(url), net::DEFAULT_PRIORITY, &delegate,
        TRAFFIC_ANNOTATION_FOR_TESTS);
    for (auto const& [key, value] : headers) {
      request->SetExtraRequestHeaderByName(key, value, true);
    }

    request->Start();
    delegate.RunUntilComplete();
    EXPECT_GE(delegate.request_status(), 0);
    return request;
  }

 protected:
  std::unique_ptr<net::URLRequestContext> request_context_ =
      net::CreateTestURLRequestContextBuilder()->Build();
  base::RunLoop run_loop_;
  base::RunLoop run_loop_2_;
};

class DevToolsWebSocketHandlerTest : public DevToolsHttpHandlerWithServerTest {
 public:
  DevToolsWebSocketHandlerTest() = default;

  std::string GetWebSocketDebuggingURL(int port) {
    GURL url(base::StringPrintf("http://127.0.0.1:%d/json/version", port));
    net::TestDelegate delegate;
    auto request = request_context_->CreateRequest(
        url, net::DEFAULT_PRIORITY, &delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
    request->Start();
    delegate.RunUntilComplete();
    EXPECT_GE(delegate.request_status(), 0);
    std::optional<base::Value> response = base::JSONReader::Read(
        delegate.data_received(), base::JSON_PARSE_CHROMIUM_EXTENSIONS);
    base::DictValue* dict = response->GetIfDict();
    // Compute HTTP upgrade request URL.
    std::string debugging_url = *dict->FindString("webSocketDebuggerUrl");
    std::string prefix = "ws://";
    return "http://" + debugging_url.substr(prefix.length());
  }
};

TEST_F(DevToolsWebSocketHandlerTest,
       TestRejectsWebSocketConnectionsWithOrigin) {
  int port = StartServer();

  std::string debugging_url = GetWebSocketDebuggingURL(port);

  // Accepts an upgrade request without an Origin header.
  auto request =
      RunRequestUntilCompletion(debugging_url, {
                                                   {"connection", "upgrade"},
                                                   {"upgrade", "websocket"},
                                               });
  // This error is expected because it's not a well-formed WS request.
  // It means that the request is accepted by the server though.
  EXPECT_EQ(request->GetResponseCode(), 500);

  // Denies an upgrade request with an Origin header.
  request = RunRequestUntilCompletion(debugging_url,
                                      {{"connection", "upgrade"},
                                       {"upgrade", "websocket"},
                                       {"origin", "http://localhost"}});
  EXPECT_EQ(request->GetResponseCode(), 403);

  StopServer();
}

TEST_F(DevToolsWebSocketHandlerTest, TestAllowsCLIOverrideAllowsOriginsStar) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kRemoteAllowOrigins, "*");
  int port = StartServer();

  std::string debugging_url = GetWebSocketDebuggingURL(port);

  auto request = RunRequestUntilCompletion(debugging_url,
                                           {
                                               {"connection", "upgrade"},
                                               {"upgrade", "websocket"},
                                               {"origin", "http://localhost"},
                                           });
  // This error is expected because it's not a well-formed WS request.
  // It means that the request is accepted by the server though.
  EXPECT_EQ(request->GetResponseCode(), 500);

  StopServer();
}

TEST_F(DevToolsWebSocketHandlerTest, TestRejectsForbiddenHostHeader) {
  int port = StartServer();

  std::string debugging_url = GetWebSocketDebuggingURL(port);

  auto request =
      RunRequestUntilCompletion(debugging_url, {
                                                   {"connection", "upgrade"},
                                                   {"upgrade", "websocket"},
                                                   {"host", "attacker.com"},
                                               });
  EXPECT_EQ(request->GetResponseCode(), 500);

  StopServer();
}

TEST_F(DevToolsWebSocketHandlerTest, TestAllowsCLIOverrideAllowsOrigins) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kRemoteAllowOrigins, "http://localhost");
  int port = StartServer();

  std::string debugging_url = GetWebSocketDebuggingURL(port);

  auto request = RunRequestUntilCompletion(debugging_url,
                                           {
                                               {"connection", "upgrade"},
                                               {"upgrade", "websocket"},
                                               {"origin", "http://localhost"},
                                           });
  // This error is expected because it's not a well-formed WS request.
  // It means that the request is accepted by the server though.
  EXPECT_EQ(request->GetResponseCode(), 500);

  request = RunRequestUntilCompletion(debugging_url,
                                      {
                                          {"connection", "upgrade"},
                                          {"upgrade", "websocket"},
                                          {"origin", "http://127.0.0.1"},
                                      });
  EXPECT_EQ(request->GetResponseCode(), 403);

  StopServer();
}

class DevToolsHttpHandlerWithApprovalTest
    : public DevToolsHttpHandlerWithServerTest {
 public:
  int StartServer() {
    return DevToolsHttpHandlerWithServerTest::StartServer(
        DevToolsAgentHost::RemoteDebuggingServerMode::kWithApprovalOnly);
  }
};

TEST_F(DevToolsHttpHandlerWithApprovalTest, JsonRequestsReturn404) {
  int port = StartServer();

  auto request = RunRequestUntilCompletion(
      base::StringPrintf("http://127.0.0.1:%d/json", port));
  EXPECT_EQ(404, request->response_info().headers->response_code());

  request = RunRequestUntilCompletion(
      base::StringPrintf("http://127.0.0.1:%d/json/list", port));
  EXPECT_EQ(404, request->response_info().headers->response_code());

  StopServer();
}

TEST_F(DevToolsHttpHandlerWithApprovalTest,
       DiscoveryAndFrontendPagesReturn404) {
  int port = StartServer();

  auto request = RunRequestUntilCompletion(
      base::StringPrintf("http://127.0.0.1:%d/", port));
  EXPECT_EQ(404, request->response_info().headers->response_code());

  request = RunRequestUntilCompletion(
      base::StringPrintf("http://127.0.0.1:%d/devtools/inspector.html", port));
  EXPECT_EQ(404, request->response_info().headers->response_code());

  StopServer();
}

TEST_F(DevToolsHttpHandlerWithApprovalTest,
       WebSocketConnectionRequiresApprovalAllow) {
  int port = StartServer();
  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance, AcceptDebugging)
      .WillOnce(
          [](base::OnceCallback<void(
                 DevToolsManagerDelegate::AcceptConnectionResult)> callback) {
            std::move(callback).Run(
                DevToolsManagerDelegate::AcceptConnectionResult::kAllow);
          });
  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance,
              SetActiveWebSocketConnections(1));

  std::string url =
      base::StringPrintf("http://127.0.0.1:%d/devtools/browser", port);
  auto request = RunRequestUntilCompletion(
      url, {{"connection", "upgrade"}, {"upgrade", "websocket"}});

  // This error is expected because it's not a well-formed WS request.
  // It means that the request is accepted by the server though.
  EXPECT_EQ(500, request->response_info().headers->response_code());

  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance,
              SetActiveWebSocketConnections(0));
  StopServer();
}

TEST_F(DevToolsHttpHandlerWithApprovalTest,
       WebSocketConnectionRequiresApprovalDeny) {
  int port = StartServer();
  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance, AcceptDebugging)
      .WillOnce(
          [](base::OnceCallback<void(
                 DevToolsManagerDelegate::AcceptConnectionResult)> callback) {
            std::move(callback).Run(
                DevToolsManagerDelegate::AcceptConnectionResult::kDeny);
          });

  std::string url =
      base::StringPrintf("http://127.0.0.1:%d/devtools/browser", port);
  auto request = RunRequestUntilCompletion(
      url, {{"connection", "upgrade"}, {"upgrade", "websocket"}});
  EXPECT_EQ(403, request->response_info().headers->response_code());

  StopServer();
}

TEST_F(DevToolsHttpHandlerWithApprovalTest,
       NonBrowserWebSocketConnectionIsRejected) {
  int port = StartServer();
  EXPECT_CALL(*MockDevToolsManagerDelegate::last_instance, AcceptDebugging)
      .Times(0);
  std::string url =
      base::StringPrintf("http://127.0.0.1:%d/devtools/page/test", port);
  auto request = RunRequestUntilCompletion(
      url, {{"connection", "upgrade"}, {"upgrade", "websocket"}});

  EXPECT_EQ(403, request->response_info().headers->response_code());

  StopServer();
}

}  // namespace content
