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