blob: f82670f5478af0e50d7b9592908cd98609af2d90 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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/core/http/quic_spdy_client_session.h"
6
vasilvv872e7a32019-03-12 16:42:44 -07007#include <string>
bnc463f2352019-10-10 04:49:34 -07008#include <utility>
vasilvv872e7a32019-03-12 16:42:44 -07009
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
11#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
12#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
13#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
14#include "net/third_party/quiche/src/quic/core/quic_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020
21namespace quic {
22
23QuicSpdyClientSession::QuicSpdyClientSession(
24 const QuicConfig& config,
25 const ParsedQuicVersionVector& supported_versions,
26 QuicConnection* connection,
27 const QuicServerId& server_id,
28 QuicCryptoClientConfig* crypto_config,
29 QuicClientPushPromiseIndex* push_promise_index)
30 : QuicSpdyClientSessionBase(connection,
31 push_promise_index,
32 config,
33 supported_versions),
34 server_id_(server_id),
35 crypto_config_(crypto_config),
36 respect_goaway_(true) {}
37
38QuicSpdyClientSession::~QuicSpdyClientSession() = default;
39
40void QuicSpdyClientSession::Initialize() {
41 crypto_stream_ = CreateQuicCryptoStream();
42 QuicSpdyClientSessionBase::Initialize();
43}
44
45void QuicSpdyClientSession::OnProofValid(
46 const QuicCryptoClientConfig::CachedState& /*cached*/) {}
47
48void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
49 const ProofVerifyDetails& /*verify_details*/) {}
50
51bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
52 if (!crypto_stream_->encryption_established()) {
53 QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
54 return false;
55 }
renjietang686ce582019-10-17 14:28:16 -070056 bool goaway_received = VersionUsesHttp3(transport_version())
57 ? http3_goaway_received()
58 : QuicSession::goaway_received();
renjietang686ce582019-10-17 14:28:16 -070059 if (goaway_received && respect_goaway_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050060 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
61 << "Already received goaway.";
62 return false;
63 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050064 return CanOpenNextOutgoingBidirectionalStream();
65}
66
67bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
68 QUIC_BUG << "Try to create outgoing unidirectional client data streams";
69 return false;
70}
71
72QuicSpdyClientStream*
73QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
74 if (!ShouldCreateOutgoingBidirectionalStream()) {
75 return nullptr;
76 }
77 std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
78 QuicSpdyClientStream* stream_ptr = stream.get();
79 ActivateStream(std::move(stream));
80 return stream_ptr;
81}
82
83QuicSpdyClientStream*
84QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
85 QUIC_BUG << "Try to create outgoing unidirectional client data streams";
86 return nullptr;
87}
88
89std::unique_ptr<QuicSpdyClientStream>
90QuicSpdyClientSession::CreateClientStream() {
vasilvv0fc587f2019-09-06 13:33:08 -070091 return std::make_unique<QuicSpdyClientStream>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
93}
94
95QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
96 return crypto_stream_.get();
97}
98
99const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
100 const {
101 return crypto_stream_.get();
102}
103
104void QuicSpdyClientSession::CryptoConnect() {
105 DCHECK(flow_controller());
106 crypto_stream_->CryptoConnect();
107}
108
109int QuicSpdyClientSession::GetNumSentClientHellos() const {
110 return crypto_stream_->num_sent_client_hellos();
111}
112
113int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
114 return crypto_stream_->num_scup_messages_received();
115}
116
117bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
118 if (!connection()->connected()) {
119 QUIC_BUG << "ShouldCreateIncomingStream called when disconnected";
120 return false;
121 }
renjietang686ce582019-10-17 14:28:16 -0700122 bool goaway_received = quic::VersionUsesHttp3(transport_version())
123 ? http3_goaway_received()
124 : QuicSession::goaway_received();
125 if (goaway_received && respect_goaway_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500126 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
127 << "Already received goaway.";
128 return false;
129 }
renjietangd1d00852019-09-06 10:43:12 -0700130 if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id) ||
131 (VersionHasIetfQuicFrames(transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 QuicUtils::IsBidirectionalStreamId(id))) {
133 QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
134 connection()->CloseConnection(
135 QUIC_INVALID_STREAM_ID,
136 "Server created non write unidirectional stream",
137 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
138 return false;
139 }
140 return true;
141}
142
143QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
renjietangbaea59c2019-05-29 15:08:14 -0700144 PendingStream* pending) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145 QuicSpdyStream* stream =
renjietangbaea59c2019-05-29 15:08:14 -0700146 new QuicSpdyClientStream(pending, this, READ_UNIDIRECTIONAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 ActivateStream(QuicWrapUnique(stream));
148 return stream;
149}
150
151QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
152 if (!ShouldCreateIncomingStream(id)) {
153 return nullptr;
154 }
155 QuicSpdyStream* stream =
156 new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
157 ActivateStream(QuicWrapUnique(stream));
158 return stream;
159}
160
161std::unique_ptr<QuicCryptoClientStreamBase>
162QuicSpdyClientSession::CreateQuicCryptoStream() {
vasilvv0fc587f2019-09-06 13:33:08 -0700163 return std::make_unique<QuicCryptoClientStream>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500164 server_id_, this,
165 crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
166 this);
167}
168
dschinazi17d42422019-06-18 16:35:07 -0700169bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170 return true;
171}
172
173} // namespace quic