QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // 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 | #ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_ |
| 6 | #define QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_ |
| 7 | |
| 8 | #include <cstdint> |
| 9 | #include <memory> |
| 10 | #include <string> |
| 11 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 12 | #include "net/third_party/quiche/src/quic/core/proto/cached_network_parameters.pb.h" |
| 13 | #include "net/third_party/quiche/src/quic/core/quic_framer.h" |
| 14 | #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h" |
| 15 | #include "net/third_party/quiche/src/quic/core/quic_packets.h" |
| 16 | #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" |
| 17 | #include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h" |
| 18 | #include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h" |
| 19 | #include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h" |
dschinazi | 580d30b | 2019-04-26 15:05:20 -0700 | [diff] [blame] | 20 | #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 21 | #include "net/third_party/quiche/src/quic/tools/quic_client.h" |
| 22 | |
| 23 | namespace quic { |
| 24 | |
| 25 | class ProofVerifier; |
| 26 | class QuicPacketWriterWrapper; |
| 27 | |
| 28 | namespace test { |
| 29 | |
| 30 | class MockableQuicClientEpollNetworkHelper; |
| 31 | |
| 32 | // A quic client which allows mocking out reads and writes. |
| 33 | class MockableQuicClient : public QuicClient { |
| 34 | public: |
| 35 | MockableQuicClient(QuicSocketAddress server_address, |
| 36 | const QuicServerId& server_id, |
| 37 | const ParsedQuicVersionVector& supported_versions, |
| 38 | QuicEpollServer* epoll_server); |
| 39 | |
| 40 | MockableQuicClient(QuicSocketAddress server_address, |
| 41 | const QuicServerId& server_id, |
| 42 | const QuicConfig& config, |
| 43 | const ParsedQuicVersionVector& supported_versions, |
| 44 | QuicEpollServer* epoll_server); |
| 45 | |
| 46 | MockableQuicClient(QuicSocketAddress server_address, |
| 47 | const QuicServerId& server_id, |
| 48 | const QuicConfig& config, |
| 49 | const ParsedQuicVersionVector& supported_versions, |
| 50 | QuicEpollServer* epoll_server, |
| 51 | std::unique_ptr<ProofVerifier> proof_verifier); |
| 52 | MockableQuicClient(const MockableQuicClient&) = delete; |
| 53 | MockableQuicClient& operator=(const MockableQuicClient&) = delete; |
| 54 | |
| 55 | ~MockableQuicClient() override; |
| 56 | |
| 57 | QuicConnectionId GenerateNewConnectionId() override; |
dschinazi | 8ff7482 | 2019-05-28 16:37:20 -0700 | [diff] [blame] | 58 | void UseConnectionId(QuicConnectionId server_connection_id); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 59 | |
| 60 | void UseWriter(QuicPacketWriterWrapper* writer); |
| 61 | void set_peer_address(const QuicSocketAddress& address); |
| 62 | // The last incoming packet, iff |track_last_incoming_packet| is true. |
| 63 | const QuicReceivedPacket* last_incoming_packet(); |
| 64 | // If true, copy each packet from ProcessPacket into |last_incoming_packet| |
| 65 | void set_track_last_incoming_packet(bool track); |
| 66 | |
| 67 | // Casts the network helper to a MockableQuicClientEpollNetworkHelper. |
| 68 | MockableQuicClientEpollNetworkHelper* mockable_network_helper(); |
| 69 | const MockableQuicClientEpollNetworkHelper* mockable_network_helper() const; |
| 70 | |
| 71 | private: |
dschinazi | 8ff7482 | 2019-05-28 16:37:20 -0700 | [diff] [blame] | 72 | // Server connection ID to use, if server_connection_id_overridden_ |
| 73 | QuicConnectionId override_server_connection_id_; |
| 74 | bool server_connection_id_overridden_; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 75 | CachedNetworkParameters cached_network_paramaters_; |
| 76 | }; |
| 77 | |
| 78 | // A toy QUIC client used for testing. |
| 79 | class QuicTestClient : public QuicSpdyStream::Visitor, |
| 80 | public QuicClientPushPromiseIndex::Delegate { |
| 81 | public: |
| 82 | QuicTestClient(QuicSocketAddress server_address, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 83 | const std::string& server_hostname, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 84 | const ParsedQuicVersionVector& supported_versions); |
| 85 | QuicTestClient(QuicSocketAddress server_address, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 86 | const std::string& server_hostname, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 87 | const QuicConfig& config, |
| 88 | const ParsedQuicVersionVector& supported_versions); |
| 89 | QuicTestClient(QuicSocketAddress server_address, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 90 | const std::string& server_hostname, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 91 | const QuicConfig& config, |
| 92 | const ParsedQuicVersionVector& supported_versions, |
| 93 | std::unique_ptr<ProofVerifier> proof_verifier); |
| 94 | |
| 95 | ~QuicTestClient() override; |
| 96 | |
| 97 | // Sets the |user_agent_id| of the |client_|. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 98 | void SetUserAgentID(const std::string& user_agent_id); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 99 | |
| 100 | // Wraps data in a quic packet and sends it. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 101 | ssize_t SendData(const std::string& data, bool last_data); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 102 | // As above, but |delegate| will be notified when |data| is ACKed. |
| 103 | ssize_t SendData( |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 104 | const std::string& data, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 105 | bool last_data, |
| 106 | QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
| 107 | |
| 108 | // Clears any outstanding state and sends a simple GET of 'uri' to the |
| 109 | // server. Returns 0 if the request failed and no bytes were written. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 110 | ssize_t SendRequest(const std::string& uri); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 111 | // Send a request R and a RST_FRAME which resets R, in the same packet. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 112 | ssize_t SendRequestAndRstTogether(const std::string& uri); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 113 | // Sends requests for all the urls and waits for the responses. To process |
| 114 | // the individual responses as they are returned, the caller should use the |
| 115 | // set the response_listener on the client(). |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 116 | void SendRequestsAndWaitForResponses( |
| 117 | const std::vector<std::string>& url_list); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 118 | // Sends a request containing |headers| and |body| and returns the number of |
| 119 | // bytes sent (the size of the serialized request headers and body). |
| 120 | ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, |
| 121 | QuicStringPiece body); |
| 122 | // Sends a request containing |headers| and |body| with the fin bit set to |
| 123 | // |fin| and returns the number of bytes sent (the size of the serialized |
| 124 | // request headers and body). |
| 125 | ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, |
| 126 | QuicStringPiece body, |
| 127 | bool fin); |
| 128 | // Sends a request containing |headers| and |body| with the fin bit set to |
| 129 | // |fin| and returns the number of bytes sent (the size of the serialized |
| 130 | // request headers and body). If |flush| is true, will wait for the message to |
| 131 | // be flushed before returning. |
| 132 | ssize_t SendMessage(const spdy::SpdyHeaderBlock& headers, |
| 133 | QuicStringPiece body, |
| 134 | bool fin, |
| 135 | bool flush); |
| 136 | // Sends a request containing |headers| and |body|, waits for the response, |
| 137 | // and returns the response body. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 138 | std::string SendCustomSynchronousRequest(const spdy::SpdyHeaderBlock& headers, |
| 139 | const std::string& body); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 140 | // Sends a GET request for |uri|, waits for the response, and returns the |
| 141 | // response body. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 142 | std::string SendSynchronousRequest(const std::string& uri); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 143 | void SendConnectivityProbing(); |
| 144 | void Connect(); |
| 145 | void ResetConnection(); |
| 146 | void Disconnect(); |
| 147 | QuicSocketAddress local_address() const; |
| 148 | void ClearPerRequestState(); |
| 149 | bool WaitUntil(int timeout_ms, std::function<bool()> trigger); |
| 150 | ssize_t Send(const void* buffer, size_t size); |
| 151 | bool connected() const; |
| 152 | bool buffer_body() const; |
| 153 | void set_buffer_body(bool buffer_body); |
| 154 | |
| 155 | // Getters for stream state. Please note, these getters are divided into two |
| 156 | // groups. 1) returns state which only get updated once a complete response |
| 157 | // is received. 2) returns state of the oldest active stream which have |
| 158 | // received partial response (if any). |
| 159 | // Group 1. |
| 160 | const spdy::SpdyHeaderBlock& response_trailers() const; |
| 161 | bool response_complete() const; |
| 162 | int64_t response_body_size() const; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 163 | const std::string& response_body() const; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 164 | // Group 2. |
| 165 | bool response_headers_complete() const; |
| 166 | const spdy::SpdyHeaderBlock* response_headers() const; |
| 167 | const spdy::SpdyHeaderBlock* preliminary_headers() const; |
| 168 | int64_t response_size() const; |
| 169 | size_t bytes_read() const; |
| 170 | size_t bytes_written() const; |
| 171 | |
| 172 | // Returns once at least one complete response or a connection close has been |
| 173 | // received from the server. If responses are received for multiple (say 2) |
| 174 | // streams, next WaitForResponse will return immediately. |
| 175 | void WaitForResponse() { WaitForResponseForMs(-1); } |
| 176 | |
| 177 | // Returns once some data is received on any open streams or at least one |
| 178 | // complete response is received from the server. |
| 179 | void WaitForInitialResponse() { WaitForInitialResponseForMs(-1); } |
| 180 | |
| 181 | // Returns once at least one complete response or a connection close has been |
| 182 | // received from the server, or once the timeout expires. -1 means no timeout. |
| 183 | // If responses are received for multiple (say 2) streams, next |
| 184 | // WaitForResponseForMs will return immediately. |
| 185 | void WaitForResponseForMs(int timeout_ms) { |
| 186 | WaitUntil(timeout_ms, [this]() { return !closed_stream_states_.empty(); }); |
| 187 | if (response_complete()) { |
dschinazi | 4620e9a | 2019-04-26 16:07:11 -0700 | [diff] [blame] | 188 | QUIC_VLOG(1) << "Client received response:" |
| 189 | << response_headers()->DebugString() << response_body(); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 190 | } |
| 191 | } |
| 192 | |
| 193 | // Returns once some data is received on any open streams or at least one |
| 194 | // complete response is received from the server, or once the timeout |
| 195 | // expires. -1 means no timeout. |
| 196 | void WaitForInitialResponseForMs(int timeout_ms) { |
| 197 | WaitUntil(timeout_ms, [this]() { return response_size() != 0; }); |
| 198 | } |
| 199 | |
| 200 | // Migrate local address to <|new_host|, a random port>. |
| 201 | // Return whether the migration succeeded. |
| 202 | bool MigrateSocket(const QuicIpAddress& new_host); |
| 203 | // Migrate local address to <|new_host|, |port|>. |
| 204 | // Return whether the migration succeeded. |
| 205 | bool MigrateSocketWithSpecifiedPort(const QuicIpAddress& new_host, int port); |
| 206 | QuicIpAddress bind_to_address() const; |
| 207 | void set_bind_to_address(QuicIpAddress address); |
| 208 | const QuicSocketAddress& address() const; |
| 209 | |
| 210 | // From QuicSpdyStream::Visitor |
| 211 | void OnClose(QuicSpdyStream* stream) override; |
| 212 | |
| 213 | // From QuicClientPushPromiseIndex::Delegate |
| 214 | bool CheckVary(const spdy::SpdyHeaderBlock& client_request, |
| 215 | const spdy::SpdyHeaderBlock& promise_request, |
| 216 | const spdy::SpdyHeaderBlock& promise_response) override; |
| 217 | void OnRendezvousResult(QuicSpdyStream*) override; |
| 218 | |
| 219 | // Configures client_ to take ownership of and use the writer. |
| 220 | // Must be called before initial connect. |
| 221 | void UseWriter(QuicPacketWriterWrapper* writer); |
dschinazi | 8ff7482 | 2019-05-28 16:37:20 -0700 | [diff] [blame] | 222 | // Configures client_ to use a specific server connection ID instead of a |
| 223 | // random one. |
| 224 | void UseConnectionId(QuicConnectionId server_connection_id); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 225 | |
| 226 | // Returns nullptr if the maximum number of streams have already been created. |
| 227 | QuicSpdyClientStream* GetOrCreateStream(); |
| 228 | |
| 229 | // Calls GetOrCreateStream(), sends the request on the stream, and |
| 230 | // stores the request in case it needs to be resent. If |headers| is |
| 231 | // null, only the body will be sent on the stream. |
| 232 | ssize_t GetOrCreateStreamAndSendRequest( |
| 233 | const spdy::SpdyHeaderBlock* headers, |
| 234 | QuicStringPiece body, |
| 235 | bool fin, |
| 236 | QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
| 237 | |
| 238 | QuicRstStreamErrorCode stream_error() { return stream_error_; } |
| 239 | QuicErrorCode connection_error(); |
| 240 | |
| 241 | MockableQuicClient* client(); |
| 242 | |
| 243 | // cert_common_name returns the common name value of the server's certificate, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 244 | // or the empty std::string if no certificate was presented. |
| 245 | const std::string& cert_common_name() const; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 246 | |
| 247 | // cert_sct returns the signed timestamp of the server's certificate, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 248 | // or the empty std::string if no signed timestamp was presented. |
| 249 | const std::string& cert_sct() const; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 250 | |
| 251 | // Get the server config map. |
| 252 | QuicTagValueMap GetServerConfig() const; |
| 253 | |
| 254 | void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; } |
| 255 | |
| 256 | void set_priority(spdy::SpdyPriority priority) { priority_ = priority; } |
| 257 | |
| 258 | void WaitForWriteToFlush(); |
| 259 | |
| 260 | QuicEpollServer* epoll_server() { return &epoll_server_; } |
| 261 | |
| 262 | size_t num_requests() const { return num_requests_; } |
| 263 | |
| 264 | size_t num_responses() const { return num_responses_; } |
| 265 | |
| 266 | void set_server_address(const QuicSocketAddress& server_address) { |
| 267 | client_->set_server_address(server_address); |
| 268 | } |
| 269 | |
| 270 | void set_peer_address(const QuicSocketAddress& address) { |
| 271 | client_->set_peer_address(address); |
| 272 | } |
| 273 | |
| 274 | // Explicitly set the SNI value for this client, overriding the default |
| 275 | // behavior which extracts the SNI value from the request URL. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 276 | void OverrideSni(const std::string& sni) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 277 | override_sni_set_ = true; |
| 278 | override_sni_ = sni; |
| 279 | } |
| 280 | |
| 281 | void Initialize(); |
| 282 | |
| 283 | void set_client(MockableQuicClient* client) { client_.reset(client); } |
| 284 | |
| 285 | // Given |uri|, populates the fields in |headers| for a simple GET |
| 286 | // request. If |uri| is a relative URL, the QuicServerId will be |
| 287 | // use to specify the authority. |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 288 | bool PopulateHeaderBlockFromUrl(const std::string& uri, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 289 | spdy::SpdyHeaderBlock* headers); |
| 290 | |
| 291 | // Waits for a period of time that is long enough to receive all delayed acks |
| 292 | // sent by peer. |
| 293 | void WaitForDelayedAcks(); |
| 294 | |
| 295 | QuicSpdyClientStream* latest_created_stream() { |
| 296 | return latest_created_stream_; |
| 297 | } |
| 298 | |
| 299 | protected: |
| 300 | QuicTestClient(); |
| 301 | QuicTestClient(const QuicTestClient&) = delete; |
| 302 | QuicTestClient& operator=(const QuicTestClient&) = delete; |
| 303 | |
| 304 | private: |
| 305 | class TestClientDataToResend : public QuicClient::QuicDataToResend { |
| 306 | public: |
| 307 | TestClientDataToResend( |
| 308 | std::unique_ptr<spdy::SpdyHeaderBlock> headers, |
| 309 | QuicStringPiece body, |
| 310 | bool fin, |
| 311 | QuicTestClient* test_client, |
| 312 | QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
| 313 | |
| 314 | ~TestClientDataToResend() override; |
| 315 | |
| 316 | void Resend() override; |
| 317 | |
| 318 | protected: |
| 319 | QuicTestClient* test_client_; |
| 320 | QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener_; |
| 321 | }; |
| 322 | |
| 323 | // PerStreamState of a stream is updated when it is closed. |
| 324 | struct PerStreamState { |
| 325 | PerStreamState(const PerStreamState& other); |
| 326 | PerStreamState(QuicRstStreamErrorCode stream_error, |
| 327 | bool response_complete, |
| 328 | bool response_headers_complete, |
| 329 | const spdy::SpdyHeaderBlock& response_headers, |
| 330 | const spdy::SpdyHeaderBlock& preliminary_headers, |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 331 | const std::string& response, |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 332 | const spdy::SpdyHeaderBlock& response_trailers, |
| 333 | uint64_t bytes_read, |
| 334 | uint64_t bytes_written, |
| 335 | int64_t response_body_size); |
| 336 | ~PerStreamState(); |
| 337 | |
| 338 | QuicRstStreamErrorCode stream_error; |
| 339 | bool response_complete; |
| 340 | bool response_headers_complete; |
| 341 | spdy::SpdyHeaderBlock response_headers; |
| 342 | spdy::SpdyHeaderBlock preliminary_headers; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 343 | std::string response; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 344 | spdy::SpdyHeaderBlock response_trailers; |
| 345 | uint64_t bytes_read; |
| 346 | uint64_t bytes_written; |
| 347 | int64_t response_body_size; |
| 348 | }; |
| 349 | |
| 350 | bool HaveActiveStream(); |
| 351 | |
| 352 | // Read oldest received response and remove it from closed_stream_states_. |
| 353 | void ReadNextResponse(); |
| 354 | |
| 355 | // Clear open_streams_, closed_stream_states_ and reset |
| 356 | // latest_created_stream_. |
| 357 | void ClearPerConnectionState(); |
| 358 | |
| 359 | // Update latest_created_stream_, add |stream| to open_streams_ and starts |
| 360 | // tracking its state. |
| 361 | void SetLatestCreatedStream(QuicSpdyClientStream* stream); |
| 362 | |
| 363 | QuicEpollServer epoll_server_; |
| 364 | std::unique_ptr<MockableQuicClient> client_; // The actual client |
| 365 | QuicSpdyClientStream* latest_created_stream_; |
| 366 | std::map<QuicStreamId, QuicSpdyClientStream*> open_streams_; |
| 367 | // Received responses of closed streams. |
| 368 | QuicLinkedHashMap<QuicStreamId, PerStreamState> closed_stream_states_; |
| 369 | |
| 370 | QuicRstStreamErrorCode stream_error_; |
| 371 | |
| 372 | bool response_complete_; |
| 373 | bool response_headers_complete_; |
| 374 | mutable spdy::SpdyHeaderBlock preliminary_headers_; |
| 375 | mutable spdy::SpdyHeaderBlock response_headers_; |
| 376 | |
| 377 | // Parsed response trailers (if present), copied from the stream in OnClose. |
| 378 | spdy::SpdyHeaderBlock response_trailers_; |
| 379 | |
| 380 | spdy::SpdyPriority priority_; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 381 | std::string response_; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 382 | // bytes_read_ and bytes_written_ are updated only when stream_ is released; |
| 383 | // prefer bytes_read() and bytes_written() member functions. |
| 384 | uint64_t bytes_read_; |
| 385 | uint64_t bytes_written_; |
| 386 | // The number of HTTP body bytes received. |
| 387 | int64_t response_body_size_; |
| 388 | // True if we tried to connect already since the last call to Disconnect(). |
| 389 | bool connect_attempted_; |
| 390 | // The client will auto-connect exactly once before sending data. If |
| 391 | // something causes a connection reset, it will not automatically reconnect |
| 392 | // unless auto_reconnect_ is true. |
| 393 | bool auto_reconnect_; |
| 394 | // Should we buffer the response body? Defaults to true. |
| 395 | bool buffer_body_; |
| 396 | // For async push promise rendezvous, validation may fail in which |
| 397 | // case the request should be retried. |
| 398 | std::unique_ptr<TestClientDataToResend> push_promise_data_to_resend_; |
| 399 | // Number of requests/responses this client has sent/received. |
| 400 | size_t num_requests_; |
| 401 | size_t num_responses_; |
| 402 | |
| 403 | // If set, this value is used for the connection SNI, overriding the usual |
| 404 | // logic which extracts the SNI from the request URL. |
| 405 | bool override_sni_set_ = false; |
vasilvv | c48c871 | 2019-03-11 13:38:16 -0700 | [diff] [blame] | 406 | std::string override_sni_; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 407 | }; |
| 408 | |
| 409 | } // namespace test |
| 410 | |
| 411 | } // namespace quic |
| 412 | |
| 413 | #endif // QUICHE_QUIC_TEST_TOOLS_QUIC_TEST_CLIENT_H_ |