1 // Copyright (c) 2015 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 // A base class for the toy client, which connects to a specified port and sends 6 // QUIC request to that endpoint. 7 8 #ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_ 9 #define QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_ 10 11 #include <string> 12 13 #include "absl/strings/string_view.h" 14 #include "quiche/quic/core/crypto/crypto_handshake.h" 15 #include "quiche/quic/core/http/quic_spdy_client_session.h" 16 #include "quiche/quic/core/http/quic_spdy_client_stream.h" 17 #include "quiche/quic/core/quic_config.h" 18 #include "quiche/quic/platform/api/quic_socket_address.h" 19 #include "quiche/quic/tools/quic_client_base.h" 20 #include "quiche/spdy/core/http2_header_block.h" 21 22 namespace quic { 23 24 class ProofVerifier; 25 class QuicServerId; 26 class SessionCache; 27 28 class QuicSpdyClientBase : public QuicClientBase, 29 public QuicSpdyStream::Visitor { 30 public: 31 // A ResponseListener is notified when a complete response is received. 32 class ResponseListener { 33 public: ResponseListener()34 ResponseListener() {} ~ResponseListener()35 virtual ~ResponseListener() {} 36 virtual void OnCompleteResponse( 37 QuicStreamId id, const spdy::Http2HeaderBlock& response_headers, 38 absl::string_view response_body) = 0; 39 }; 40 41 QuicSpdyClientBase(const QuicServerId& server_id, 42 const ParsedQuicVersionVector& supported_versions, 43 const QuicConfig& config, 44 QuicConnectionHelperInterface* helper, 45 QuicAlarmFactory* alarm_factory, 46 std::unique_ptr<NetworkHelper> network_helper, 47 std::unique_ptr<ProofVerifier> proof_verifier, 48 std::unique_ptr<SessionCache> session_cache); 49 QuicSpdyClientBase(const QuicSpdyClientBase&) = delete; 50 QuicSpdyClientBase& operator=(const QuicSpdyClientBase&) = delete; 51 52 ~QuicSpdyClientBase() override; 53 54 // QuicSpdyStream::Visitor 55 void OnClose(QuicSpdyStream* stream) override; 56 57 // A spdy session has to call CryptoConnect on top of the regular 58 // initialization. 59 void InitializeSession() override; 60 61 // Sends an HTTP request and does not wait for response before returning. 62 void SendRequest(const spdy::Http2HeaderBlock& headers, 63 absl::string_view body, bool fin); 64 65 // Sends an HTTP request and waits for response before returning. 66 void SendRequestAndWaitForResponse(const spdy::Http2HeaderBlock& headers, 67 absl::string_view body, bool fin); 68 69 // Sends a request simple GET for each URL in |url_list|, and then waits for 70 // each to complete. 71 void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list); 72 73 // Returns a newly created QuicSpdyClientStream. 74 virtual QuicSpdyClientStream* CreateClientStream(); 75 76 // Returns a the session used for this client downcasted to a 77 // QuicSpdyClientSession. 78 QuicSpdyClientSession* client_session(); 79 const QuicSpdyClientSession* client_session() const; 80 set_store_response(bool val)81 void set_store_response(bool val) { store_response_ = val; } 82 83 int latest_response_code() const; 84 const std::string& latest_response_headers() const; 85 const std::string& preliminary_response_headers() const; 86 const spdy::Http2HeaderBlock& latest_response_header_block() const; 87 const std::string& latest_response_body() const; 88 const std::string& latest_response_trailers() const; 89 latest_ttlb()90 QuicTime::Delta latest_ttlb() const { return latest_ttlb_; } latest_ttfb()91 QuicTime::Delta latest_ttfb() const { return latest_ttfb_; } 92 set_response_listener(std::unique_ptr<ResponseListener> listener)93 void set_response_listener(std::unique_ptr<ResponseListener> listener) { 94 response_listener_ = std::move(listener); 95 } 96 set_drop_response_body(bool drop_response_body)97 void set_drop_response_body(bool drop_response_body) { 98 drop_response_body_ = drop_response_body; 99 } drop_response_body()100 bool drop_response_body() const { return drop_response_body_; } 101 set_enable_web_transport(bool enable_web_transport)102 void set_enable_web_transport(bool enable_web_transport) { 103 enable_web_transport_ = enable_web_transport; 104 } enable_web_transport()105 bool enable_web_transport() const { return enable_web_transport_; } 106 set_use_datagram_contexts(bool use_datagram_contexts)107 void set_use_datagram_contexts(bool use_datagram_contexts) { 108 use_datagram_contexts_ = use_datagram_contexts; 109 } use_datagram_contexts()110 bool use_datagram_contexts() const { return use_datagram_contexts_; } 111 112 // QuicClientBase methods. 113 bool goaway_received() const override; 114 bool EarlyDataAccepted() override; 115 bool ReceivedInchoateReject() override; 116 117 std::optional<uint64_t> last_received_http3_goaway_id(); 118 set_max_inbound_header_list_size(size_t size)119 void set_max_inbound_header_list_size(size_t size) { 120 max_inbound_header_list_size_ = size; 121 } 122 123 protected: 124 int GetNumSentClientHellosFromSession() override; 125 int GetNumReceivedServerConfigUpdatesFromSession() override; 126 127 // Takes ownership of |connection|. 128 std::unique_ptr<QuicSession> CreateQuicClientSession( 129 const quic::ParsedQuicVersionVector& supported_versions, 130 QuicConnection* connection) override; 131 ClearDataToResend()132 void ClearDataToResend() override {} 133 ResendSavedData()134 void ResendSavedData() override {} 135 136 bool HasActiveRequests() override; 137 138 private: 139 void SendRequestInternal(spdy::Http2HeaderBlock sanitized_headers, 140 absl::string_view body, bool fin); 141 142 // If true, store the latest response code, headers, and body. 143 bool store_response_; 144 // HTTP response code from most recent response. 145 int latest_response_code_; 146 // HTTP/2 headers from most recent response. 147 std::string latest_response_headers_; 148 // preliminary 100 Continue HTTP/2 headers from most recent response, if any. 149 std::string preliminary_response_headers_; 150 // HTTP/2 headers from most recent response. 151 spdy::Http2HeaderBlock latest_response_header_block_; 152 // Body of most recent response. 153 std::string latest_response_body_; 154 // HTTP/2 trailers from most recent response. 155 std::string latest_response_trailers_; 156 157 QuicTime::Delta latest_ttfb_ = QuicTime::Delta::Infinite(); 158 QuicTime::Delta latest_ttlb_ = QuicTime::Delta::Infinite(); 159 160 // Listens for full responses. 161 std::unique_ptr<ResponseListener> response_listener_; 162 163 bool drop_response_body_ = false; 164 bool enable_web_transport_ = false; 165 bool use_datagram_contexts_ = false; 166 // If not zero, used to set client's max inbound header size before session 167 // initialize. 168 size_t max_inbound_header_list_size_ = 0; 169 }; 170 171 } // namespace quic 172 173 #endif // QUICHE_QUIC_TOOLS_QUIC_SPDY_CLIENT_BASE_H_ 174