blob: ba65ce29881521f7522c1757c1654b6b923f9432 [file] [log] [blame]
vasilvve6472f62019-10-02 06:50:56 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
6
7#include <memory>
bnc463f2352019-10-10 04:49:34 -07008#include <utility>
vasilvve6472f62019-10-02 06:50:56 -07009
10#include "url/gurl.h"
vasilvvddf52472019-10-04 15:14:02 -070011#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
vasilvve6472f62019-10-02 06:50:56 -070012#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
vasilvvddf52472019-10-04 15:14:02 -070013#include "net/third_party/quiche/src/quic/core/quic_types.h"
vasilvve6472f62019-10-02 06:50:56 -070014#include "net/third_party/quiche/src/quic/core/quic_utils.h"
vasilvvddf52472019-10-04 15:14:02 -070015#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
vasilvve6472f62019-10-02 06:50:56 -070016#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
17#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
vasilvvddf52472019-10-04 15:14:02 -070018#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
19#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
vasilvve6472f62019-10-02 06:50:56 -070020#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
vasilvvdfbd3df2019-11-01 11:58:43 -070021#include "net/third_party/quiche/src/quic/test_tools/quic_transport_test_tools.h"
bnc4e9283d2019-12-17 07:08:57 -080022#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
vasilvve6472f62019-10-02 06:50:56 -070023
24namespace quic {
25namespace test {
26namespace {
27
28using testing::_;
29using testing::ElementsAre;
vasilvvda373d42020-01-16 12:36:27 -080030using testing::Eq;
vasilvve6472f62019-10-02 06:50:56 -070031
32const char* kTestOrigin = "https://test-origin.test";
vasilvve6472f62019-10-02 06:50:56 -070033url::Origin GetTestOrigin() {
34 GURL origin_url(kTestOrigin);
35 return url::Origin::Create(origin_url);
36}
37
38ParsedQuicVersionVector GetVersions() {
vasilvv7e5e6092020-03-02 15:52:33 -080039 return {DefaultVersionForQuicTransport()};
vasilvve6472f62019-10-02 06:50:56 -070040}
41
vasilvvddf52472019-10-04 15:14:02 -070042std::string DataInStream(QuicStream* stream) {
43 QuicStreamSendBuffer& send_buffer = QuicStreamPeer::SendBuffer(stream);
44 std::string result;
45 result.resize(send_buffer.stream_offset());
46 QuicDataWriter writer(result.size(), &result[0]);
47 EXPECT_TRUE(
48 send_buffer.WriteStreamData(0, send_buffer.stream_offset(), &writer));
49 return result;
50}
51
vasilvve6472f62019-10-02 06:50:56 -070052class QuicTransportClientSessionTest : public QuicTest {
53 protected:
54 QuicTransportClientSessionTest()
55 : connection_(&helper_,
56 &alarm_factory_,
57 Perspective::IS_CLIENT,
58 GetVersions()),
vasilvve6472f62019-10-02 06:50:56 -070059 crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
vasilvv7e5e6092020-03-02 15:52:33 -080060 QuicEnableVersion(DefaultVersionForQuicTransport());
vasilvve58d0f12019-12-04 14:35:25 -080061 CreateSession(GetTestOrigin(), "");
vasilvvddf52472019-10-04 15:14:02 -070062 }
63
vasilvve58d0f12019-12-04 14:35:25 -080064 void CreateSession(url::Origin origin, std::string url_suffix) {
vasilvvdfbd3df2019-11-01 11:58:43 -070065 session_ = std::make_unique<QuicTransportClientSession>(
vasilvve58d0f12019-12-04 14:35:25 -080066 &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
67 GURL("quic-transport://test.example.com:50000" + url_suffix),
vasilvvdfbd3df2019-11-01 11:58:43 -070068 &crypto_config_, origin, &visitor_);
vasilvve6472f62019-10-02 06:50:56 -070069 session_->Initialize();
70 crypto_stream_ = static_cast<QuicCryptoClientStream*>(
71 session_->GetMutableCryptoStream());
72 }
73
vasilvvddf52472019-10-04 15:14:02 -070074 void Connect() {
vasilvve6472f62019-10-02 06:50:56 -070075 session_->CryptoConnect();
76 QuicConfig server_config = DefaultQuicConfig();
rch83f29bd2019-11-13 11:47:34 -080077 std::unique_ptr<QuicCryptoServerConfig> crypto_config(
78 crypto_test_utils::CryptoServerConfigForTesting());
vasilvve6472f62019-10-02 06:50:56 -070079 crypto_test_utils::HandshakeWithFakeServer(
rch83f29bd2019-11-13 11:47:34 -080080 &server_config, crypto_config.get(), &helper_, &alarm_factory_,
81 &connection_, crypto_stream_, QuicTransportAlpn());
vasilvve6472f62019-10-02 06:50:56 -070082 }
83
84 MockAlarmFactory alarm_factory_;
85 MockQuicConnectionHelper helper_;
86
87 PacketSavingConnection connection_;
vasilvve6472f62019-10-02 06:50:56 -070088 QuicCryptoClientConfig crypto_config_;
vasilvvdfbd3df2019-11-01 11:58:43 -070089 MockClientVisitor visitor_;
90 std::unique_ptr<QuicTransportClientSession> session_;
vasilvve6472f62019-10-02 06:50:56 -070091 QuicCryptoClientStream* crypto_stream_;
92};
93
94TEST_F(QuicTransportClientSessionTest, HasValidAlpn) {
vasilvveba61c42019-10-08 14:23:14 -070095 EXPECT_THAT(session_->GetAlpnsToOffer(), ElementsAre(QuicTransportAlpn()));
vasilvve6472f62019-10-02 06:50:56 -070096}
97
98TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
vasilvve58d0f12019-12-04 14:35:25 -080099 constexpr char kTestOriginClientIndication[] =
100 "\0\0" // key (0x0000, origin)
101 "\0\x18" // length
102 "https://test-origin.test" // value
103 "\0\x01" // key (0x0001, path)
104 "\0\x01" // length
105 "/"; // value
106
vasilvv467b4222019-12-09 16:22:11 -0800107 EXPECT_CALL(visitor_, OnSessionReady());
vasilvve58d0f12019-12-04 14:35:25 -0800108 Connect();
109 EXPECT_TRUE(session_->IsSessionReady());
110
111 QuicStream* client_indication_stream =
112 QuicSessionPeer::zombie_streams(session_.get())[ClientIndicationStream()]
113 .get();
114 ASSERT_TRUE(client_indication_stream != nullptr);
115 const std::string client_indication = DataInStream(client_indication_stream);
116 const std::string expected_client_indication{
117 kTestOriginClientIndication,
bnc4e9283d2019-12-17 07:08:57 -0800118 QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1};
vasilvve58d0f12019-12-04 14:35:25 -0800119 EXPECT_EQ(client_indication, expected_client_indication);
120}
121
122TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
123 constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
124 constexpr char kTestOriginClientIndication[] =
125 "\0\0" // key (0x0000, origin)
126 "\0\x18" // length
127 "https://test-origin.test" // value
128 "\0\x01" // key (0x0001, path)
129 "\0\x14" // length
130 "/foo/bar?hello=world"; // value
131
132 CreateSession(GetTestOrigin(), kSuffix);
vasilvvddf52472019-10-04 15:14:02 -0700133 Connect();
vasilvve6472f62019-10-02 06:50:56 -0700134 EXPECT_TRUE(session_->IsSessionReady());
vasilvvddf52472019-10-04 15:14:02 -0700135
136 QuicStream* client_indication_stream =
vasilvveba61c42019-10-08 14:23:14 -0700137 QuicSessionPeer::zombie_streams(session_.get())[ClientIndicationStream()]
vasilvvddf52472019-10-04 15:14:02 -0700138 .get();
139 ASSERT_TRUE(client_indication_stream != nullptr);
140 const std::string client_indication = DataInStream(client_indication_stream);
141 const std::string expected_client_indication{
142 kTestOriginClientIndication,
bnc4e9283d2019-12-17 07:08:57 -0800143 QUICHE_ARRAYSIZE(kTestOriginClientIndication) - 1};
vasilvvddf52472019-10-04 15:14:02 -0700144 EXPECT_EQ(client_indication, expected_client_indication);
vasilvve6472f62019-10-02 06:50:56 -0700145}
146
vasilvvddf52472019-10-04 15:14:02 -0700147TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
148 std::string long_string(68000, 'a');
149 GURL bad_origin_url{"https://" + long_string + ".example/"};
150 EXPECT_TRUE(bad_origin_url.is_valid());
vasilvve58d0f12019-12-04 14:35:25 -0800151 CreateSession(url::Origin::Create(bad_origin_url), "");
vasilvve6472f62019-10-02 06:50:56 -0700152
vasilvvddf52472019-10-04 15:14:02 -0700153 EXPECT_QUIC_BUG(Connect(), "Client origin too long");
vasilvve6472f62019-10-02 06:50:56 -0700154}
155
vasilvvdfbd3df2019-11-01 11:58:43 -0700156TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
157 Connect();
158 ASSERT_TRUE(session_->IsSessionReady());
159 ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);
160
161 const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
162 session_->transport_version(), 0);
163 QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
164 EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
165 session_->OnStreamFrame(frame);
166
167 QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
168 ASSERT_TRUE(stream != nullptr);
169 EXPECT_EQ(stream->ReadableBytes(), 4u);
170 EXPECT_EQ(stream->id(), id);
171}
172
vasilvv2b0ab242020-01-07 07:32:09 -0800173TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
vasilvvda373d42020-01-16 12:36:27 -0800174 EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
vasilvv2b0ab242020-01-07 07:32:09 -0800175 session_->OnMessageReceived("test");
vasilvv2b0ab242020-01-07 07:32:09 -0800176}
177
vasilvve6472f62019-10-02 06:50:56 -0700178} // namespace
179} // namespace test
180} // namespace quic