#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include <stdint.h>
#include <optional>
#include <string>
#include "base/containers/span.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "content/browser/direct_sockets/direct_sockets_service_impl.h"
#include "content/browser/direct_sockets/direct_sockets_test_utils.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/net_buildflags.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/mojom/clear_data_filter.mojom.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/dbus/permission_broker/fake_permission_broker_client.h"
#endif
StartsWith;
namespace content {
namespace {
constexpr char kLocalhostAddress[] = …;
class ReadWriteWaiter { … };
}
class DirectSocketsTcpBrowserTest : public ContentBrowserTest { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, OpenTcp_Success) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, OpenTcp_Success_Global) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, CloseTcp) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, WriteTcp) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, WriteLargeTcpPacket) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, ReadTcp) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, ReadWriteTcp) { … }
class MockTcpNetworkContext : public content::test::MockNetworkContext { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, ReadTcpOnReadError) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, ReadTcpOnPeerClosed) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, WriteTcpOnWriteError) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest,
ReadWriteTcpOnSocketObserverError) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest,
BarrierCallbackFiresWithErrorOnReadWriteError) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest,
BarrierCallbackFiresWithOkOnReaderAndWriterClose) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest,
BarrierCallbackFiresWithOkOnPeerAndWriterClose) { … }
class DirectSocketsTcpServerBrowserTest : public DirectSocketsTcpBrowserTest { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, ExchangeTcpServer) { … }
#if BUILDFLAG(IS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, HasFirewallHole) {
class DelegateImpl : public chromeos::FakePermissionBrokerClient::Delegate {
public:
DelegateImpl(uint16_t port, base::OnceClosure quit_closure)
: port_(port), quit_closure_(std::move(quit_closure)) {}
void OnTcpPortReleased(uint16_t port,
const std::string& interface) override {
if (port == port_) {
ASSERT_EQ(interface, "");
ASSERT_TRUE(quit_closure_);
std::move(quit_closure_).Run();
}
}
private:
uint16_t port_;
base::OnceClosure quit_closure_;
};
auto* client = chromeos::FakePermissionBrokerClient::Get();
const std::string open_script = R"(
(async () => {
socket = new TCPServerSocket('127.0.0.1');
const { localPort } = await socket.opened;
return localPort;
})();
)";
const int32_t local_port = EvalJs(shell(), open_script).ExtractInt();
ASSERT_TRUE(client->HasTcpHole(local_port, "" ));
base::RunLoop run_loop;
auto delegate =
std::make_unique<DelegateImpl>(local_port, run_loop.QuitClosure());
client->AttachDelegate(delegate.get());
EXPECT_TRUE(EvalJs(shell(), content::test::WrapAsync("socket.close()"))
.error.empty());
run_loop.Run();
}
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, FirewallHoleDenied) {
auto* client = chromeos::FakePermissionBrokerClient::Get();
client->SetTcpDenyAll();
const std::string open_script = R"(
(async () => {
socket = new TCPServerSocket('127.0.0.1');
return await socket.opened.catch(err => err.message);
})();
)";
EXPECT_THAT(EvalJs(shell(), open_script).ExtractString(),
testing::HasSubstr("Firewall"));
}
#endif
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, OkOnClose) { … }
class MockNetworkContextWithTCPServerSocketReceiver
: public network::TestNetworkContext { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, ErrorOnRemoteReset) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpServerBrowserTest, Ipv6Only) { … }
class NoCoiPermissionIsolatedWebAppContentBrowserClient
: public test::IsolatedWebAppContentBrowserClient { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, NoCoiPermission) { … }
IN_PROC_BROWSER_TEST_F(DirectSocketsTcpBrowserTest, NotInCrossOriginIframe) { … }
class IsolatedContextContentBrowserClient
: public ContentBrowserTestContentBrowserClient { … };
class DirectSocketsIsolatedContextTcpBrowserTest
: public DirectSocketsTcpBrowserTest { … };
IN_PROC_BROWSER_TEST_F(DirectSocketsIsolatedContextTcpBrowserTest,
NotAvailableInSandboxedIframes) { … }
}