| // 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 "absl/base/nullability.h" | |
| #include "quiche/quic/core/crypto/quic_crypto_client_config.h" | |
| #include "quiche/quic/core/http/quic_connection_migration_manager.h" | |
| #include "quiche/quic/core/http/quic_spdy_client_session.h" | |
| #include "quiche/quic/core/http/quic_spdy_client_stream.h" | |
| #include "quiche/quic/core/http/quic_spdy_session.h" | |
| #include "quiche/quic/core/quic_config.h" | |
| #include "quiche/quic/core/quic_connection.h" | |
| #include "quiche/quic/core/quic_force_blockable_packet_writer.h" | |
| #include "quiche/quic/core/quic_packet_writer.h" | |
| #include "quiche/quic/core/quic_path_validator.h" | |
| #include "quiche/quic/core/quic_server_id.h" | |
| #include "quiche/quic/core/quic_session.h" | |
| #include "quiche/quic/core/quic_types.h" | |
| #include "quiche/quic/core/quic_versions.h" | |
| #include "quiche/quic/tools/quic_client_base.h" | |
| #include "quiche/quic/tools/quic_simple_client_stream.h" | |
| #include "quiche/common/http/http_header_block.h" | |
| #include "quiche/common/quiche_callbacks.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) | |
| : QuicSimpleClientSession(config, supported_versions, connection, visitor, | |
| /*writer=*/nullptr, | |
| /*migration_helper=*/nullptr, | |
| QuicConnectionMigrationConfig{ | |
| .allow_server_preferred_address = false}, | |
| 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, | |
| QuicForceBlockablePacketWriter* absl_nullable writer, | |
| QuicMigrationHelper* absl_nullable migration_helper, | |
| const QuicConnectionMigrationConfig& migration_config, | |
| 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, writer, | |
| migration_helper, migration_config, 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) { | |
| if (on_interim_headers_ != nullptr) { | |
| 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 |