1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/cast_channel/cast_socket.h"
- #include <stdint.h>
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/files/file_util.h"
- #include "base/location.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/path_service.h"
- #include "base/run_loop.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/sys_byteorder.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/test/bind.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/timer/mock_timer.h"
- #include "build/build_config.h"
- #include "components/cast_channel/cast_auth_util.h"
- #include "components/cast_channel/cast_framer.h"
- #include "components/cast_channel/cast_message_util.h"
- #include "components/cast_channel/cast_test_util.h"
- #include "components/cast_channel/cast_transport.h"
- #include "components/cast_channel/logger.h"
- #include "content/public/test/browser_task_environment.h"
- #include "crypto/rsa_private_key.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "net/base/address_list.h"
- #include "net/base/net_errors.h"
- #include "net/cert/pem.h"
- #include "net/socket/client_socket_factory.h"
- #include "net/socket/socket_test_util.h"
- #include "net/socket/ssl_client_socket.h"
- #include "net/socket/ssl_server_socket.h"
- #include "net/socket/tcp_client_socket.h"
- #include "net/socket/tcp_server_socket.h"
- #include "net/ssl/ssl_info.h"
- #include "net/ssl/ssl_server_config.h"
- #include "net/test/cert_test_util.h"
- #include "net/test/test_data_directory.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 "services/network/network_context.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h"
- const int64_t kDistantTimeoutMillis = 100000; // 100 seconds (never hit).
- using ::testing::A;
- using ::testing::DoAll;
- using ::testing::Invoke;
- using ::testing::InvokeArgument;
- using ::testing::NotNull;
- using ::testing::Return;
- using ::testing::SaveArg;
- using ::testing::_;
- using ::cast::channel::CastMessage;
- namespace cast_channel {
- namespace {
- const char kAuthNamespace[] = "urn:x-cast:com.google.cast.tp.deviceauth";
- // Returns an auth challenge message inline.
- CastMessage CreateAuthChallenge() {
- CastMessage output;
- CreateAuthChallengeMessage(&output, AuthContext::Create());
- return output;
- }
- // Returns an auth challenge response message inline.
- CastMessage CreateAuthReply() {
- CastMessage output;
- output.set_protocol_version(CastMessage::CASTV2_1_0);
- output.set_source_id("sender-0");
- output.set_destination_id("receiver-0");
- output.set_payload_type(CastMessage::BINARY);
- output.set_payload_binary("abcd");
- output.set_namespace_(kAuthNamespace);
- return output;
- }
- CastMessage CreateTestMessage() {
- CastMessage test_message;
- test_message.set_protocol_version(CastMessage::CASTV2_1_0);
- test_message.set_namespace_("ns");
- test_message.set_source_id("source");
- test_message.set_destination_id("dest");
- test_message.set_payload_type(CastMessage::STRING);
- test_message.set_payload_utf8("payload");
- return test_message;
- }
- base::FilePath GetTestCertsDirectory() {
- base::FilePath path;
- base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.Append(FILE_PATH_LITERAL("components"));
- path = path.Append(FILE_PATH_LITERAL("test"));
- path = path.Append(FILE_PATH_LITERAL("data"));
- path = path.Append(FILE_PATH_LITERAL("cast_channel"));
- return path;
- }
- class MockTCPSocket : public net::MockTCPClientSocket {
- public:
- MockTCPSocket(bool do_nothing, net::SocketDataProvider* socket_provider)
- : net::MockTCPClientSocket(net::AddressList(), nullptr, socket_provider) {
- do_nothing_ = do_nothing;
- set_enable_read_if_ready(true);
- }
- MockTCPSocket(const MockTCPSocket&) = delete;
- MockTCPSocket& operator=(const MockTCPSocket&) = delete;
- int Connect(net::CompletionOnceCallback callback) override {
- if (do_nothing_) {
- // Stall the I/O event loop.
- return net::ERR_IO_PENDING;
- }
- return net::MockTCPClientSocket::Connect(std::move(callback));
- }
- private:
- bool do_nothing_;
- };
- class CompleteHandler {
- public:
- CompleteHandler() {}
- CompleteHandler(const CompleteHandler&) = delete;
- CompleteHandler& operator=(const CompleteHandler&) = delete;
- MOCK_METHOD1(OnCloseComplete, void(int result));
- MOCK_METHOD1(OnConnectComplete, void(CastSocket* socket));
- MOCK_METHOD1(OnWriteComplete, void(int result));
- MOCK_METHOD1(OnReadComplete, void(int result));
- };
- class TestCastSocketBase : public CastSocketImpl {
- public:
- TestCastSocketBase(network::mojom::NetworkContext* network_context,
- const CastSocketOpenParams& open_params,
- Logger* logger)
- : CastSocketImpl(base::BindRepeating(
- [](network::mojom::NetworkContext* network_context) {
- return network_context;
- },
- network_context),
- open_params,
- logger,
- AuthContext::Create()),
- verify_challenge_result_(true),
- verify_challenge_disallow_(false),
- mock_timer_(new base::MockOneShotTimer()) {
- SetPeerCertForTesting(
- net::ImportCertFromFile(GetTestCertsDirectory(), "self_signed.pem"));
- }
- TestCastSocketBase(const TestCastSocketBase&) = delete;
- TestCastSocketBase& operator=(const TestCastSocketBase&) = delete;
- ~TestCastSocketBase() override {}
- void SetVerifyChallengeResult(bool value) {
- verify_challenge_result_ = value;
- }
- void TriggerTimeout() { mock_timer_->Fire(); }
- bool TestVerifyChannelPolicyNone() {
- AuthResult authResult;
- return VerifyChannelPolicy(authResult);
- }
- void DisallowVerifyChallengeResult() { verify_challenge_disallow_ = true; }
- protected:
- bool VerifyChallengeReply() override {
- EXPECT_FALSE(verify_challenge_disallow_);
- return verify_challenge_result_;
- }
- base::OneShotTimer* GetTimer() override { return mock_timer_.get(); }
- // Simulated result of verifying challenge reply.
- bool verify_challenge_result_;
- bool verify_challenge_disallow_;
- std::unique_ptr<base::MockOneShotTimer> mock_timer_;
- };
- class MockTestCastSocket : public TestCastSocketBase {
- public:
- static std::unique_ptr<MockTestCastSocket> CreateSecure(
- network::mojom::NetworkContext* network_context,
- const CastSocketOpenParams& open_params,
- Logger* logger) {
- return std::make_unique<MockTestCastSocket>(network_context, open_params,
- logger);
- }
- using TestCastSocketBase::TestCastSocketBase;
- MockTestCastSocket(network::mojom::NetworkContext* network_context,
- const CastSocketOpenParams& open_params,
- Logger* logger)
- : TestCastSocketBase(network_context, open_params, logger) {}
- MockTestCastSocket(const MockTestCastSocket&) = delete;
- MockTestCastSocket& operator=(const MockTestCastSocket&) = delete;
- ~MockTestCastSocket() override {}
- void SetupMockTransport() {
- mock_transport_ = new MockCastTransport;
- SetTransportForTesting(base::WrapUnique(mock_transport_.get()));
- }
- bool TestVerifyChannelPolicyAudioOnly() {
- AuthResult authResult;
- authResult.channel_policies |= AuthResult::POLICY_AUDIO_ONLY;
- return VerifyChannelPolicy(authResult);
- }
- MockCastTransport* GetMockTransport() {
- CHECK(mock_transport_);
- return mock_transport_;
- }
- private:
- raw_ptr<MockCastTransport> mock_transport_ = nullptr;
- };
- // TODO(https://crbug.com/928467): Remove this class.
- class TestSocketFactory : public net::ClientSocketFactory {
- public:
- explicit TestSocketFactory(net::IPEndPoint ip) : ip_(ip) {}
- TestSocketFactory(const TestSocketFactory&) = delete;
- TestSocketFactory& operator=(const TestSocketFactory&) = delete;
- ~TestSocketFactory() override = default;
- // Socket connection helpers.
- void SetupTcpConnect(net::IoMode mode, int result) {
- tcp_connect_data_ = std::make_unique<net::MockConnect>(mode, result, ip_);
- }
- void SetupSslConnect(net::IoMode mode, int result) {
- ssl_connect_data_ = std::make_unique<net::MockConnect>(mode, result, ip_);
- }
- // Socket I/O helpers.
- void AddWriteResult(const net::MockWrite& write) { writes_.push_back(write); }
- void AddWriteResult(net::IoMode mode, int result) {
- AddWriteResult(net::MockWrite(mode, result));
- }
- void AddWriteResultForData(net::IoMode mode, const std::string& msg) {
- AddWriteResult(mode, msg.size());
- }
- void AddReadResult(const net::MockRead& read) { reads_.push_back(read); }
- void AddReadResult(net::IoMode mode, int result) {
- AddReadResult(net::MockRead(mode, result));
- }
- void AddReadResultForData(net::IoMode mode, const std::string& data) {
- AddReadResult(net::MockRead(mode, data.c_str(), data.size()));
- }
- // Helpers for modifying other connection-related behaviors.
- void SetupTcpConnectUnresponsive() { tcp_unresponsive_ = true; }
- void SetTcpSocket(
- std::unique_ptr<net::TransportClientSocket> tcp_client_socket) {
- tcp_client_socket_ = std::move(tcp_client_socket);
- }
- void SetTLSSocketCreatedClosure(base::OnceClosure closure) {
- tls_socket_created_ = std::move(closure);
- }
- void Pause() {
- if (socket_data_provider_)
- socket_data_provider_->Pause();
- else
- socket_data_provider_paused_ = true;
- }
- void Resume() { socket_data_provider_->Resume(); }
- private:
- std::unique_ptr<net::DatagramClientSocket> CreateDatagramClientSocket(
- net::DatagramSocket::BindType,
- net::NetLog*,
- const net::NetLogSource&) override {
- NOTIMPLEMENTED();
- return nullptr;
- }
- std::unique_ptr<net::TransportClientSocket> CreateTransportClientSocket(
- const net::AddressList&,
- std::unique_ptr<net::SocketPerformanceWatcher>,
- net::NetworkQualityEstimator*,
- net::NetLog*,
- const net::NetLogSource&) override {
- if (tcp_client_socket_)
- return std::move(tcp_client_socket_);
- if (tcp_unresponsive_) {
- socket_data_provider_ = std::make_unique<net::StaticSocketDataProvider>();
- return std::unique_ptr<net::TransportClientSocket>(
- new MockTCPSocket(true, socket_data_provider_.get()));
- } else {
- socket_data_provider_ =
- std::make_unique<net::StaticSocketDataProvider>(reads_, writes_);
- socket_data_provider_->set_connect_data(*tcp_connect_data_);
- if (socket_data_provider_paused_)
- socket_data_provider_->Pause();
- return std::unique_ptr<net::TransportClientSocket>(
- new MockTCPSocket(false, socket_data_provider_.get()));
- }
- }
- std::unique_ptr<net::SSLClientSocket> CreateSSLClientSocket(
- net::SSLClientContext* context,
- std::unique_ptr<net::StreamSocket> nested_socket,
- const net::HostPortPair& host_and_port,
- const net::SSLConfig& ssl_config) override {
- if (!ssl_connect_data_) {
- // Test isn't overriding SSL socket creation.
- return net::ClientSocketFactory::GetDefaultFactory()
- ->CreateSSLClientSocket(context, std::move(nested_socket),
- host_and_port, ssl_config);
- }
- ssl_socket_data_provider_ = std::make_unique<net::SSLSocketDataProvider>(
- ssl_connect_data_->mode, ssl_connect_data_->result);
- if (tls_socket_created_)
- std::move(tls_socket_created_).Run();
- return std::make_unique<net::MockSSLClientSocket>(
- std::move(nested_socket), net::HostPortPair(), net::SSLConfig(),
- ssl_socket_data_provider_.get());
- }
- net::IPEndPoint ip_;
- // Simulated connect data
- std::unique_ptr<net::MockConnect> tcp_connect_data_;
- std::unique_ptr<net::MockConnect> ssl_connect_data_;
- // Simulated read / write data
- std::vector<net::MockWrite> writes_;
- std::vector<net::MockRead> reads_;
- std::unique_ptr<net::StaticSocketDataProvider> socket_data_provider_;
- std::unique_ptr<net::SSLSocketDataProvider> ssl_socket_data_provider_;
- bool socket_data_provider_paused_ = false;
- // If true, makes TCP connection process stall. For timeout testing.
- bool tcp_unresponsive_ = false;
- std::unique_ptr<net::TransportClientSocket> tcp_client_socket_;
- base::OnceClosure tls_socket_created_;
- };
- class CastSocketTestBase : public testing::Test {
- protected:
- CastSocketTestBase()
- : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
- logger_(new Logger()),
- observer_(new MockCastSocketObserver()),
- socket_open_params_(CreateIPEndPointForTest(),
- base::Milliseconds(kDistantTimeoutMillis)),
- client_socket_factory_(socket_open_params_.ip_endpoint) {}
- CastSocketTestBase(const CastSocketTestBase&) = delete;
- CastSocketTestBase& operator=(const CastSocketTestBase&) = delete;
- ~CastSocketTestBase() override {}
- void SetUp() override {
- EXPECT_CALL(*observer_, OnMessage(_, _)).Times(0);
- auto context_builder = net::CreateTestURLRequestContextBuilder();
- context_builder->set_client_socket_factory_for_testing(
- &client_socket_factory_);
- url_request_context_ = context_builder->Build();
- network_context_ = std::make_unique<network::NetworkContext>(
- nullptr, network_context_remote_.BindNewPipeAndPassReceiver(),
- url_request_context_.get(),
- /*cors_exempt_header_list=*/std::vector<std::string>());
- }
- // Runs all pending tasks in the message loop.
- void RunPendingTasks() {
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
- }
- TestSocketFactory* client_socket_factory() { return &client_socket_factory_; }
- content::BrowserTaskEnvironment task_environment_;
- std::unique_ptr<net::URLRequestContext> url_request_context_;
- std::unique_ptr<network::NetworkContext> network_context_;
- mojo::Remote<network::mojom::NetworkContext> network_context_remote_;
- raw_ptr<Logger> logger_;
- CompleteHandler handler_;
- std::unique_ptr<MockCastSocketObserver> observer_;
- CastSocketOpenParams socket_open_params_;
- TestSocketFactory client_socket_factory_;
- };
- class MockCastSocketTest : public CastSocketTestBase {
- public:
- MockCastSocketTest(const MockCastSocketTest&) = delete;
- MockCastSocketTest& operator=(const MockCastSocketTest&) = delete;
- protected:
- MockCastSocketTest() {}
- void TearDown() override {
- if (socket_) {
- EXPECT_CALL(handler_, OnCloseComplete(net::OK));
- socket_->Close(base::BindOnce(&CompleteHandler::OnCloseComplete,
- base::Unretained(&handler_)));
- }
- }
- void CreateCastSocketSecure() {
- socket_ = MockTestCastSocket::CreateSecure(network_context_.get(),
- socket_open_params_, logger_);
- }
- void HandleAuthHandshake() {
- socket_->SetupMockTransport();
- CastMessage challenge_proto = CreateAuthChallenge();
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(challenge_proto), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::OK));
- EXPECT_CALL(*socket_->GetMockTransport(), Start());
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- socket_->GetMockTransport()->current_delegate()->OnMessage(
- CreateAuthReply());
- RunPendingTasks();
- }
- std::unique_ptr<MockTestCastSocket> socket_;
- };
- class SslCastSocketTest : public CastSocketTestBase {
- public:
- SslCastSocketTest(const SslCastSocketTest&) = delete;
- SslCastSocketTest& operator=(const SslCastSocketTest&) = delete;
- protected:
- SslCastSocketTest() {}
- void TearDown() override {
- if (socket_) {
- EXPECT_CALL(handler_, OnCloseComplete(net::OK));
- socket_->Close(base::BindOnce(&CompleteHandler::OnCloseComplete,
- base::Unretained(&handler_)));
- }
- }
- void CreateSockets() {
- socket_ = std::make_unique<TestCastSocketBase>(
- network_context_.get(), socket_open_params_, logger_);
- server_cert_ =
- net::ImportCertFromFile(GetTestCertsDirectory(), "self_signed.pem");
- ASSERT_TRUE(server_cert_);
- server_private_key_ = ReadTestKeyFromPEM("self_signed.pem");
- ASSERT_TRUE(server_private_key_);
- server_context_ = CreateSSLServerContext(
- server_cert_.get(), *server_private_key_, server_ssl_config_);
- tcp_server_socket_ =
- std::make_unique<net::TCPServerSocket>(nullptr, net::NetLogSource());
- ASSERT_EQ(net::OK,
- tcp_server_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 1));
- net::IPEndPoint server_address;
- ASSERT_EQ(net::OK, tcp_server_socket_->GetLocalAddress(&server_address));
- tcp_client_socket_ = std::make_unique<net::TCPClientSocket>(
- net::AddressList(server_address), nullptr, nullptr, nullptr,
- net::NetLogSource());
- std::unique_ptr<net::StreamSocket> accepted_socket;
- accept_result_ = tcp_server_socket_->Accept(
- &accepted_socket, base::BindOnce(&SslCastSocketTest::TcpAcceptCallback,
- base::Unretained(this)));
- connect_result_ = tcp_client_socket_->Connect(base::BindOnce(
- &SslCastSocketTest::TcpConnectCallback, base::Unretained(this)));
- while (accept_result_ == net::ERR_IO_PENDING ||
- connect_result_ == net::ERR_IO_PENDING) {
- RunPendingTasks();
- }
- ASSERT_EQ(net::OK, accept_result_);
- ASSERT_EQ(net::OK, connect_result_);
- ASSERT_TRUE(accepted_socket);
- ASSERT_TRUE(tcp_client_socket_->IsConnected());
- server_socket_ =
- server_context_->CreateSSLServerSocket(std::move(accepted_socket));
- ASSERT_TRUE(server_socket_);
- client_socket_factory()->SetTcpSocket(std::move(tcp_client_socket_));
- }
- void ConnectSockets() {
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- net::TestCompletionCallback handshake_callback;
- int server_ret = handshake_callback.GetResult(
- server_socket_->Handshake(handshake_callback.callback()));
- ASSERT_EQ(net::OK, server_ret);
- }
- void TcpAcceptCallback(int result) { accept_result_ = result; }
- void TcpConnectCallback(int result) { connect_result_ = result; }
- std::unique_ptr<crypto::RSAPrivateKey> ReadTestKeyFromPEM(
- const base::StringPiece& name) {
- base::FilePath key_path = GetTestCertsDirectory().AppendASCII(name);
- std::string pem_data;
- if (!base::ReadFileToString(key_path, &pem_data)) {
- return nullptr;
- }
- const std::vector<std::string> headers({"PRIVATE KEY"});
- net::PEMTokenizer pem_tokenizer(pem_data, headers);
- if (!pem_tokenizer.GetNext()) {
- return nullptr;
- }
- std::vector<uint8_t> key_vector(pem_tokenizer.data().begin(),
- pem_tokenizer.data().end());
- std::unique_ptr<crypto::RSAPrivateKey> key(
- crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
- return key;
- }
- int ReadExactLength(net::IOBuffer* buffer,
- int buffer_length,
- net::Socket* socket) {
- scoped_refptr<net::DrainableIOBuffer> draining_buffer =
- base::MakeRefCounted<net::DrainableIOBuffer>(buffer, buffer_length);
- while (draining_buffer->BytesRemaining() > 0) {
- net::TestCompletionCallback read_callback;
- int read_result = read_callback.GetResult(server_socket_->Read(
- draining_buffer.get(), draining_buffer->BytesRemaining(),
- read_callback.callback()));
- EXPECT_GT(read_result, 0);
- draining_buffer->DidConsume(read_result);
- }
- return buffer_length;
- }
- int WriteExactLength(net::IOBuffer* buffer,
- int buffer_length,
- net::Socket* socket) {
- scoped_refptr<net::DrainableIOBuffer> draining_buffer =
- base::MakeRefCounted<net::DrainableIOBuffer>(buffer, buffer_length);
- while (draining_buffer->BytesRemaining() > 0) {
- net::TestCompletionCallback write_callback;
- int write_result = write_callback.GetResult(server_socket_->Write(
- draining_buffer.get(), draining_buffer->BytesRemaining(),
- write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
- EXPECT_GT(write_result, 0);
- draining_buffer->DidConsume(write_result);
- }
- return buffer_length;
- }
- // Result values used for TCP socket setup. These should contain values from
- // net::Error.
- int accept_result_;
- int connect_result_;
- // Underlying TCP sockets for |socket_| to communicate with |server_socket_|
- // when testing with the real SSL implementation.
- std::unique_ptr<net::TransportClientSocket> tcp_client_socket_;
- std::unique_ptr<net::TCPServerSocket> tcp_server_socket_;
- std::unique_ptr<TestCastSocketBase> socket_;
- // |server_socket_| is used for the *RealSSL tests in order to test the
- // CastSocket over a real SSL socket. The other members below are used to
- // initialize |server_socket_|.
- std::unique_ptr<net::SSLServerSocket> server_socket_;
- std::unique_ptr<net::SSLServerContext> server_context_;
- std::unique_ptr<crypto::RSAPrivateKey> server_private_key_;
- scoped_refptr<net::X509Certificate> server_cert_;
- net::SSLServerConfig server_ssl_config_;
- };
- } // namespace
- // Tests that the following connection flow works:
- // - TCP connection succeeds (async)
- // - SSL connection succeeds (async)
- // - Cert is extracted successfully
- // - Challenge request is sent (async)
- // - Challenge response is received (async)
- // - Credentials are verified successfuly
- TEST_F(MockCastSocketTest, TestConnectFullSecureFlowAsync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
- HandleAuthHandshake();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- // Tests that the following connection flow works:
- // - TCP connection succeeds (sync)
- // - SSL connection succeeds (sync)
- // - Cert is extracted successfully
- // - Challenge request is sent (sync)
- // - Challenge response is received (sync)
- // - Credentials are verified successfuly
- TEST_F(MockCastSocketTest, TestConnectFullSecureFlowSync) {
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
- CreateCastSocketSecure();
- HandleAuthHandshake();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- // Test that an AuthMessage with a mangled namespace triggers cancelation
- // of the connection event loop.
- TEST_F(MockCastSocketTest, TestConnectAuthMessageCorrupted) {
- CreateCastSocketSecure();
- socket_->SetupMockTransport();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
- CastMessage challenge_proto = CreateAuthChallenge();
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(challenge_proto), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::OK));
- EXPECT_CALL(*socket_->GetMockTransport(), Start());
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- CastMessage mangled_auth_reply = CreateAuthReply();
- mangled_auth_reply.set_namespace_("BOGUS_NAMESPACE");
- socket_->GetMockTransport()->current_delegate()->OnMessage(
- mangled_auth_reply);
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::TRANSPORT_ERROR, socket_->error_state());
- // Verifies that the CastSocket's resources were torn down during channel
- // close. (see http://crbug.com/504078)
- EXPECT_EQ(nullptr, socket_->transport());
- }
- // Test connection error - TCP connect fails (async)
- TEST_F(MockCastSocketTest, TestConnectTcpConnectErrorAsync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
- }
- // Test connection error - TCP connect fails (sync)
- TEST_F(MockCastSocketTest, TestConnectTcpConnectErrorSync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_FAILED);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
- }
- // Test connection error - timeout
- TEST_F(MockCastSocketTest, TestConnectTcpTimeoutError) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnectUnresponsive();
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT));
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CONNECTING, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- socket_->TriggerTimeout();
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
- }
- // Test connection error - TCP socket returns timeout
- TEST_F(MockCastSocketTest, TestConnectTcpSocketTimeoutError) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS,
- net::ERR_CONNECTION_TIMED_OUT);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT));
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
- EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
- logger_->GetLastError(socket_->id()).net_return_value);
- }
- // Test connection error - SSL connect fails (async)
- TEST_F(MockCastSocketTest, TestConnectSslConnectErrorAsync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
- }
- // Test connection error - SSL connect fails (sync)
- TEST_F(MockCastSocketTest, TestConnectSslConnectErrorSync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
- EXPECT_EQ(net::ERR_FAILED,
- logger_->GetLastError(socket_->id()).net_return_value);
- }
- // Test connection error - SSL connect times out (sync)
- TEST_F(MockCastSocketTest, TestConnectSslConnectTimeoutSync) {
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS,
- net::ERR_CONNECTION_TIMED_OUT);
- CreateCastSocketSecure();
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
- EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
- logger_->GetLastError(socket_->id()).net_return_value);
- }
- // Test connection error - SSL connect times out (async)
- TEST_F(MockCastSocketTest, TestConnectSslConnectTimeoutAsync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC,
- net::ERR_CONNECTION_TIMED_OUT);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
- }
- // Test connection error - challenge send fails
- TEST_F(MockCastSocketTest, TestConnectChallengeSendError) {
- CreateCastSocketSecure();
- socket_->SetupMockTransport();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(CreateAuthChallenge()), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
- }
- // Test connection error - connection is destroyed after the challenge is
- // sent, with the async result still lurking in the task queue.
- TEST_F(MockCastSocketTest, TestConnectDestroyedAfterChallengeSent) {
- CreateCastSocketSecure();
- socket_->SetupMockTransport();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(CreateAuthChallenge()), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- socket_.reset();
- RunPendingTasks();
- }
- // Test connection error - challenge reply receive fails
- TEST_F(MockCastSocketTest, TestConnectChallengeReplyReceiveError) {
- CreateCastSocketSecure();
- socket_->SetupMockTransport();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(CreateAuthChallenge()), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::OK));
- client_socket_factory()->AddReadResult(net::SYNCHRONOUS, net::ERR_FAILED);
- EXPECT_CALL(*observer_, OnError(_, ChannelError::CAST_SOCKET_ERROR));
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- EXPECT_CALL(*socket_->GetMockTransport(), Start());
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- socket_->GetMockTransport()->current_delegate()->OnError(
- ChannelError::CAST_SOCKET_ERROR);
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
- }
- TEST_F(MockCastSocketTest, TestConnectChallengeVerificationFails) {
- CreateCastSocketSecure();
- socket_->SetupMockTransport();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
- socket_->SetVerifyChallengeResult(false);
- EXPECT_CALL(*observer_, OnError(_, ChannelError::AUTHENTICATION_ERROR));
- CastMessage challenge_proto = CreateAuthChallenge();
- EXPECT_CALL(*socket_->GetMockTransport(),
- SendMessage_(EqualsProto(challenge_proto), _))
- .WillOnce(PostCompletionCallbackTask<1>(net::OK));
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- EXPECT_CALL(*socket_->GetMockTransport(), Start());
- socket_->AddObserver(observer_.get());
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- socket_->GetMockTransport()->current_delegate()->OnMessage(CreateAuthReply());
- RunPendingTasks();
- EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
- EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
- }
- // Sends message data through an actual non-mocked CastTransport object,
- // testing the two components in integration.
- TEST_F(MockCastSocketTest, TestConnectEndToEndWithRealTransportAsync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
- // Set low-level auth challenge expectations.
- CastMessage challenge = CreateAuthChallenge();
- std::string challenge_str;
- EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
- client_socket_factory()->AddWriteResultForData(net::ASYNC, challenge_str);
- // Set low-level auth reply expectations.
- CastMessage reply = CreateAuthReply();
- std::string reply_str;
- EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
- client_socket_factory()->AddReadResultForData(net::ASYNC, reply_str);
- client_socket_factory()->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
- // Make sure the data is ready by the TLS socket and not the TCP socket.
- client_socket_factory()->Pause();
- client_socket_factory()->SetTLSSocketCreatedClosure(
- base::BindLambdaForTesting([&] { client_socket_factory()->Resume(); }));
- CastMessage test_message = CreateTestMessage();
- std::string test_message_str;
- EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
- client_socket_factory()->AddWriteResultForData(net::ASYNC, test_message_str);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- // Send the test message through a real transport object.
- EXPECT_CALL(handler_, OnWriteComplete(net::OK));
- socket_->transport()->SendMessage(
- test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- // Same as TestConnectEndToEndWithRealTransportAsync, except synchronous.
- TEST_F(MockCastSocketTest, TestConnectEndToEndWithRealTransportSync) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
- client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
- // Set low-level auth challenge expectations.
- CastMessage challenge = CreateAuthChallenge();
- std::string challenge_str;
- EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
- client_socket_factory()->AddWriteResultForData(net::SYNCHRONOUS,
- challenge_str);
- // Set low-level auth reply expectations.
- CastMessage reply = CreateAuthReply();
- std::string reply_str;
- EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
- client_socket_factory()->AddReadResultForData(net::SYNCHRONOUS, reply_str);
- client_socket_factory()->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
- // Make sure the data is ready by the TLS socket and not the TCP socket.
- client_socket_factory()->Pause();
- client_socket_factory()->SetTLSSocketCreatedClosure(
- base::BindLambdaForTesting([&] { client_socket_factory()->Resume(); }));
- CastMessage test_message = CreateTestMessage();
- std::string test_message_str;
- EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
- client_socket_factory()->AddWriteResultForData(net::SYNCHRONOUS,
- test_message_str);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- // Send the test message through a real transport object.
- EXPECT_CALL(handler_, OnWriteComplete(net::OK));
- socket_->transport()->SendMessage(
- test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- TEST_F(MockCastSocketTest, TestObservers) {
- CreateCastSocketSecure();
- // Test AddObserever
- MockCastSocketObserver observer1;
- MockCastSocketObserver observer2;
- socket_->AddObserver(&observer1);
- socket_->AddObserver(&observer1);
- socket_->AddObserver(&observer2);
- socket_->AddObserver(&observer2);
- // Test notify observers
- EXPECT_CALL(observer1, OnError(_, cast_channel::ChannelError::CONNECT_ERROR));
- EXPECT_CALL(observer2, OnError(_, cast_channel::ChannelError::CONNECT_ERROR));
- CastSocketImpl::CastSocketMessageDelegate delegate(socket_.get());
- delegate.OnError(cast_channel::ChannelError::CONNECT_ERROR);
- }
- TEST_F(MockCastSocketTest, TestOpenChannelConnectingSocket) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnectUnresponsive();
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get())).Times(2);
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- socket_->TriggerTimeout();
- RunPendingTasks();
- }
- TEST_F(MockCastSocketTest, TestOpenChannelConnectedSocket) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
- client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
- HandleAuthHandshake();
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- }
- TEST_F(MockCastSocketTest, TestOpenChannelClosedSocket) {
- CreateCastSocketSecure();
- client_socket_factory()->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
- base::Unretained(&handler_)));
- }
- // https://crbug.com/874491, flaky on Win and Mac
- #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_FUCHSIA)
- #define MAYBE_TestConnectEndToEndWithRealSSL \
- DISABLED_TestConnectEndToEndWithRealSSL
- #else
- #define MAYBE_TestConnectEndToEndWithRealSSL TestConnectEndToEndWithRealSSL
- #endif
- // Tests connecting through an actual non-mocked CastTransport object and
- // non-mocked SSLClientSocket, testing the components in integration.
- TEST_F(SslCastSocketTest, MAYBE_TestConnectEndToEndWithRealSSL) {
- CreateSockets();
- ConnectSockets();
- // Set low-level auth challenge expectations.
- CastMessage challenge = CreateAuthChallenge();
- std::string challenge_str;
- EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
- int challenge_buffer_length = challenge_str.size();
- scoped_refptr<net::IOBuffer> challenge_buffer =
- base::MakeRefCounted<net::IOBuffer>(challenge_buffer_length);
- int read = ReadExactLength(challenge_buffer.get(), challenge_buffer_length,
- server_socket_.get());
- EXPECT_EQ(challenge_buffer_length, read);
- EXPECT_EQ(challenge_str,
- std::string(challenge_buffer->data(), challenge_buffer_length));
- // Set low-level auth reply expectations.
- CastMessage reply = CreateAuthReply();
- std::string reply_str;
- EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
- scoped_refptr<net::StringIOBuffer> reply_buffer =
- base::MakeRefCounted<net::StringIOBuffer>(reply_str);
- int written = WriteExactLength(reply_buffer.get(), reply_buffer->size(),
- server_socket_.get());
- EXPECT_EQ(reply_buffer->size(), written);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- // Sends message data through an actual non-mocked CastTransport object and
- // non-mocked SSLClientSocket, testing the components in integration.
- TEST_F(SslCastSocketTest, DISABLED_TestMessageEndToEndWithRealSSL) {
- CreateSockets();
- ConnectSockets();
- // Set low-level auth challenge expectations.
- CastMessage challenge = CreateAuthChallenge();
- std::string challenge_str;
- EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
- int challenge_buffer_length = challenge_str.size();
- scoped_refptr<net::IOBuffer> challenge_buffer =
- base::MakeRefCounted<net::IOBuffer>(challenge_buffer_length);
- int read = ReadExactLength(challenge_buffer.get(), challenge_buffer_length,
- server_socket_.get());
- EXPECT_EQ(challenge_buffer_length, read);
- EXPECT_EQ(challenge_str,
- std::string(challenge_buffer->data(), challenge_buffer_length));
- // Set low-level auth reply expectations.
- CastMessage reply = CreateAuthReply();
- std::string reply_str;
- EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
- scoped_refptr<net::StringIOBuffer> reply_buffer =
- base::MakeRefCounted<net::StringIOBuffer>(reply_str);
- int written = WriteExactLength(reply_buffer.get(), reply_buffer->size(),
- server_socket_.get());
- EXPECT_EQ(reply_buffer->size(), written);
- EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
- RunPendingTasks();
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- // Send a test message through the ssl socket.
- CastMessage test_message = CreateTestMessage();
- std::string test_message_str;
- EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
- int test_message_length = test_message_str.size();
- scoped_refptr<net::IOBuffer> test_message_buffer =
- base::MakeRefCounted<net::IOBuffer>(test_message_length);
- EXPECT_CALL(handler_, OnWriteComplete(net::OK));
- socket_->transport()->SendMessage(
- test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
- base::Unretained(&handler_)));
- RunPendingTasks();
- read = ReadExactLength(test_message_buffer.get(), test_message_length,
- server_socket_.get());
- EXPECT_EQ(test_message_length, read);
- EXPECT_EQ(test_message_str,
- std::string(test_message_buffer->data(), test_message_length));
- EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
- EXPECT_EQ(ChannelError::NONE, socket_->error_state());
- }
- } // namespace cast_channel
|