blob: 6f9322c8dabdb724e93ae0929446c69b6670639d [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/public/cpp/websocket_utils.h"
#include <optional>
#include <string>
#include <vector>
#include "net/base/isolation_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace network {
namespace {
net::IsolationInfo CreateIsolationInfo(
net::IsolationInfo::RequestType request_type) {
url::Origin origin = url::Origin::Create(GURL("https://example.com"));
return net::IsolationInfo::Create(request_type, origin, origin,
net::SiteForCookies::FromOrigin(origin));
}
TEST(WebSocketUtilsTest, ValidParameters) {
auto isolation_info =
CreateIsolationInfo(net::IsolationInfo::RequestType::kOther);
EXPECT_EQ(std::nullopt, VerifyWebSocketConnectParameters(
GURL("ws://example.com/"), {}, isolation_info));
EXPECT_EQ(std::nullopt,
VerifyWebSocketConnectParameters(GURL("wss://example.com/"),
{"chat"}, isolation_info));
EXPECT_EQ(std::nullopt, VerifyWebSocketConnectParameters(
GURL("wss://example.com/"), {"chat", "superchat"},
isolation_info));
}
TEST(WebSocketUtilsTest, InvalidIsolationInfo) {
EXPECT_EQ(
"WebSocket's IsolationInfo::RequestType must be kOther",
VerifyWebSocketConnectParameters(
GURL("ws://example.com/"), {},
CreateIsolationInfo(net::IsolationInfo::RequestType::kMainFrame)));
EXPECT_EQ(
"WebSocket's IsolationInfo::RequestType must be kOther",
VerifyWebSocketConnectParameters(
GURL("ws://example.com/"), {},
CreateIsolationInfo(net::IsolationInfo::RequestType::kSubFrame)));
}
TEST(WebSocketUtilsTest, InvalidScheme) {
auto isolation_info =
CreateIsolationInfo(net::IsolationInfo::RequestType::kOther);
const std::string expected_error = "Invalid scheme.";
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("http://example.com/"), {},
isolation_info));
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("https://example.com/"), {},
isolation_info));
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ftp://example.com/"), {},
isolation_info));
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("data:text/plain,Hello"), {},
isolation_info));
}
TEST(WebSocketUtilsTest, InvalidProtocols) {
auto isolation_info =
CreateIsolationInfo(net::IsolationInfo::RequestType::kOther);
const std::string expected_error = "Invalid protocols.";
// Duplicates
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ws://example.com/"),
{"chat", "chat"}, isolation_info));
// Empty string
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ws://example.com/"), {""},
isolation_info));
// Invalid character: space
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ws://example.com/"),
{"chat room"}, isolation_info));
// Invalid character: separator
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ws://example.com/"),
{"chat,room"}, isolation_info));
// Invalid character: control character
EXPECT_EQ(expected_error,
VerifyWebSocketConnectParameters(GURL("ws://example.com/"),
{"chat\x01"}, isolation_info));
}
} // namespace
} // namespace network