|  | // Copyright (c) 2018 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 "quiche/quic/tools/quic_simple_client_session.h" | 
|  |  | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | #include "quiche/quic/core/quic_path_validator.h" | 
|  | #include "quiche/quic/core/quic_types.h" | 
|  | #include "quiche/common/http/http_header_block.h" | 
|  |  | 
|  | namespace quic { | 
|  |  | 
|  | QuicSimpleClientSession::QuicSimpleClientSession( | 
|  | const QuicConfig& config, const ParsedQuicVersionVector& supported_versions, | 
|  | QuicConnection* connection, QuicClientBase::NetworkHelper* network_helper, | 
|  | const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config, | 
|  | bool drop_response_body, bool enable_web_transport) | 
|  | : QuicSimpleClientSession(config, supported_versions, connection, | 
|  | /*visitor=*/nullptr, network_helper, server_id, | 
|  | crypto_config, drop_response_body, | 
|  | enable_web_transport) {} | 
|  |  | 
|  | QuicSimpleClientSession::QuicSimpleClientSession( | 
|  | const QuicConfig& config, const ParsedQuicVersionVector& supported_versions, | 
|  | QuicConnection* connection, QuicSession::Visitor* visitor, | 
|  | QuicClientBase::NetworkHelper* network_helper, | 
|  | const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config, | 
|  | bool drop_response_body, bool enable_web_transport) | 
|  | : QuicSpdyClientSession(config, supported_versions, connection, visitor, | 
|  | server_id, crypto_config, | 
|  | enable_web_transport | 
|  | ? QuicPriorityType::kWebTransport | 
|  | : QuicPriorityType::kHttp), | 
|  | network_helper_(network_helper), | 
|  | drop_response_body_(drop_response_body), | 
|  | enable_web_transport_(enable_web_transport) {} | 
|  |  | 
|  | std::unique_ptr<QuicSpdyClientStream> | 
|  | QuicSimpleClientSession::CreateClientStream() { | 
|  | auto stream = std::make_unique<QuicSimpleClientStream>( | 
|  | GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL, | 
|  | drop_response_body_); | 
|  | stream->set_on_interim_headers( | 
|  | [this](const quiche::HttpHeaderBlock& headers) { | 
|  | on_interim_headers_(headers); | 
|  | }); | 
|  | return stream; | 
|  | } | 
|  |  | 
|  | WebTransportHttp3VersionSet | 
|  | QuicSimpleClientSession::LocallySupportedWebTransportVersions() const { | 
|  | return enable_web_transport_ ? kDefaultSupportedWebTransportVersions | 
|  | : WebTransportHttp3VersionSet(); | 
|  | } | 
|  |  | 
|  | HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() { | 
|  | return enable_web_transport_ ? HttpDatagramSupport::kRfcAndDraft04 | 
|  | : HttpDatagramSupport::kNone; | 
|  | } | 
|  |  | 
|  | void QuicSimpleClientSession::CreateContextForMultiPortPath( | 
|  | std::unique_ptr<MultiPortPathContextObserver> context_observer) { | 
|  | if (!network_helper_ || connection()->multi_port_stats() == nullptr) { | 
|  | return; | 
|  | } | 
|  | auto self_address = connection()->self_address(); | 
|  | auto server_address = connection()->peer_address(); | 
|  | if (!network_helper_->CreateUDPSocketAndBind( | 
|  | server_address, self_address.host(), self_address.port() + 1)) { | 
|  | return; | 
|  | } | 
|  | QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter(); | 
|  | if (writer == nullptr) { | 
|  | return; | 
|  | } | 
|  | context_observer->OnMultiPortPathContextAvailable( | 
|  | std::make_unique<PathMigrationContext>( | 
|  | std::unique_ptr<QuicPacketWriter>(writer), | 
|  | network_helper_->GetLatestClientAddress(), peer_address())); | 
|  | } | 
|  |  | 
|  | void QuicSimpleClientSession::MigrateToMultiPortPath( | 
|  | std::unique_ptr<QuicPathValidationContext> context) { | 
|  | auto* path_migration_context = | 
|  | static_cast<PathMigrationContext*>(context.get()); | 
|  | MigratePath(path_migration_context->self_address(), | 
|  | path_migration_context->peer_address(), | 
|  | path_migration_context->ReleaseWriter(), /*owns_writer=*/true); | 
|  | } | 
|  |  | 
|  | }  // namespace quic |