blob: 8e6a0e27882a8bbe49f6f131c3d075cc7978b8b0 [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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/quic_transport/quic_transport_client_session.h"
vasilvve6472f62019-10-02 06:50:56 -07006
7#include <memory>
bnc463f2352019-10-10 04:49:34 -07008#include <utility>
vasilvve6472f62019-10-02 06:50:56 -07009
vasilvv035fe3d2020-10-20 08:38:37 -070010#include "absl/base/macros.h"
vasilvve6472f62019-10-02 06:50:56 -070011#include "url/gurl.h"
QUICHE team5be974e2020-12-29 18:35:24 -050012#include "quic/core/quic_data_writer.h"
13#include "quic/core/quic_server_id.h"
14#include "quic/core/quic_types.h"
15#include "quic/core/quic_utils.h"
16#include "quic/platform/api/quic_expect_bug.h"
17#include "quic/platform/api/quic_test.h"
18#include "quic/test_tools/crypto_test_utils.h"
19#include "quic/test_tools/quic_session_peer.h"
20#include "quic/test_tools/quic_stream_peer.h"
21#include "quic/test_tools/quic_test_utils.h"
22#include "quic/test_tools/quic_transport_test_tools.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),
QUICHE team20456ed2020-11-18 22:24:42 -080068 &crypto_config_, origin, &visitor_, /*datagram_observer=*/nullptr);
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
renjietang647b3cf2020-08-04 13:23:12 -0700111 QuicStream* client_indication_stream;
renjietang4c334822020-09-28 15:44:55 -0700112 client_indication_stream =
113 QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
114 .get();
vasilvve58d0f12019-12-04 14:35:25 -0800115 ASSERT_TRUE(client_indication_stream != nullptr);
116 const std::string client_indication = DataInStream(client_indication_stream);
117 const std::string expected_client_indication{
118 kTestOriginClientIndication,
vasilvv035fe3d2020-10-20 08:38:37 -0700119 ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
vasilvve58d0f12019-12-04 14:35:25 -0800120 EXPECT_EQ(client_indication, expected_client_indication);
121}
122
123TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
124 constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
125 constexpr char kTestOriginClientIndication[] =
126 "\0\0" // key (0x0000, origin)
127 "\0\x18" // length
128 "https://test-origin.test" // value
129 "\0\x01" // key (0x0001, path)
130 "\0\x14" // length
131 "/foo/bar?hello=world"; // value
132
133 CreateSession(GetTestOrigin(), kSuffix);
vasilvvddf52472019-10-04 15:14:02 -0700134 Connect();
vasilvve6472f62019-10-02 06:50:56 -0700135 EXPECT_TRUE(session_->IsSessionReady());
vasilvvddf52472019-10-04 15:14:02 -0700136
renjietang647b3cf2020-08-04 13:23:12 -0700137 QuicStream* client_indication_stream;
renjietang4c334822020-09-28 15:44:55 -0700138 client_indication_stream =
139 QuicSessionPeer::stream_map(session_.get())[ClientIndicationStream()]
140 .get();
vasilvvddf52472019-10-04 15:14:02 -0700141 ASSERT_TRUE(client_indication_stream != nullptr);
142 const std::string client_indication = DataInStream(client_indication_stream);
143 const std::string expected_client_indication{
144 kTestOriginClientIndication,
vasilvv035fe3d2020-10-20 08:38:37 -0700145 ABSL_ARRAYSIZE(kTestOriginClientIndication) - 1};
vasilvvddf52472019-10-04 15:14:02 -0700146 EXPECT_EQ(client_indication, expected_client_indication);
vasilvve6472f62019-10-02 06:50:56 -0700147}
148
vasilvvddf52472019-10-04 15:14:02 -0700149TEST_F(QuicTransportClientSessionTest, OriginTooLong) {
150 std::string long_string(68000, 'a');
151 GURL bad_origin_url{"https://" + long_string + ".example/"};
152 EXPECT_TRUE(bad_origin_url.is_valid());
vasilvve58d0f12019-12-04 14:35:25 -0800153 CreateSession(url::Origin::Create(bad_origin_url), "");
vasilvve6472f62019-10-02 06:50:56 -0700154
vasilvvddf52472019-10-04 15:14:02 -0700155 EXPECT_QUIC_BUG(Connect(), "Client origin too long");
vasilvve6472f62019-10-02 06:50:56 -0700156}
157
vasilvvdfbd3df2019-11-01 11:58:43 -0700158TEST_F(QuicTransportClientSessionTest, ReceiveNewStreams) {
159 Connect();
160 ASSERT_TRUE(session_->IsSessionReady());
161 ASSERT_TRUE(session_->AcceptIncomingUnidirectionalStream() == nullptr);
162
163 const QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(
164 session_->transport_version(), 0);
165 QuicStreamFrame frame(id, /*fin=*/false, /*offset=*/0, "test");
166 EXPECT_CALL(visitor_, OnIncomingUnidirectionalStreamAvailable()).Times(1);
167 session_->OnStreamFrame(frame);
168
169 QuicTransportStream* stream = session_->AcceptIncomingUnidirectionalStream();
170 ASSERT_TRUE(stream != nullptr);
171 EXPECT_EQ(stream->ReadableBytes(), 4u);
172 EXPECT_EQ(stream->id(), id);
173}
174
vasilvv2b0ab242020-01-07 07:32:09 -0800175TEST_F(QuicTransportClientSessionTest, ReceiveDatagram) {
vasilvvda373d42020-01-16 12:36:27 -0800176 EXPECT_CALL(visitor_, OnDatagramReceived(Eq("test")));
vasilvv2b0ab242020-01-07 07:32:09 -0800177 session_->OnMessageReceived("test");
vasilvv2b0ab242020-01-07 07:32:09 -0800178}
179
vasilvve6472f62019-10-02 06:50:56 -0700180} // namespace
181} // namespace test
182} // namespace quic