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.
5 // A toy client, which connects to a specified port and sends QUIC
6 // request to that endpoint.
8 #ifndef NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
9 #define NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_
13 #include "base/basictypes.h"
14 #include "base/command_line.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/strings/string_piece.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/http/http_response_headers.h"
19 #include "net/log/net_log.h"
20 #include "net/quic/quic_config.h"
21 #include "net/quic/quic_data_stream.h"
22 #include "net/quic/quic_packet_reader.h"
23 #include "net/tools/quic/quic_client_base.h"
27 struct HttpRequestInfo
;
28 class QuicConnectionHelper
;
29 class UDPClientSocket
;
37 class QuicSimpleClient
: public QuicClientBase
,
38 public QuicDataStream::Visitor
,
39 public QuicPacketReader::Visitor
{
41 class ResponseListener
{
44 virtual ~ResponseListener() {}
45 virtual void OnCompleteResponse(QuicStreamId id
,
46 const HttpResponseHeaders
& response_headers
,
47 const std::string
& response_body
) = 0;
50 // The client uses these objects to keep track of any data to resend upon
51 // receipt of a stateless reject. Recall that the client API allows callers
52 // to optimistically send data to the server prior to handshake-confirmation.
53 // If the client subsequently receives a stateless reject, it must tear down
54 // its existing session, create a new session, and resend all previously sent
55 // data. It uses these objects to keep track of all the sent data, and to
56 // resend the data upon a subsequent connection.
57 class QuicDataToResend
{
59 // Takes ownership of |headers|. |headers| may be null, since it's possible
60 // to send data without headers.
61 QuicDataToResend(HttpRequestInfo
* headers
,
62 base::StringPiece body
,
65 virtual ~QuicDataToResend();
67 // Must be overridden by specific classes with the actual method for
69 virtual void Resend() = 0;
72 HttpRequestInfo
* headers_
;
73 base::StringPiece body_
;
77 DISALLOW_COPY_AND_ASSIGN(QuicDataToResend
);
80 // Create a quic client, which will have events managed by an externally owned
82 QuicSimpleClient(IPEndPoint server_address
,
83 const QuicServerId
& server_id
,
84 const QuicVersionVector
& supported_versions
);
85 QuicSimpleClient(IPEndPoint server_address
,
86 const QuicServerId
& server_id
,
87 const QuicVersionVector
& supported_versions
,
88 const QuicConfig
& config
);
90 ~QuicSimpleClient() override
;
92 // From QuicClientBase
93 bool Initialize() override
;
94 bool WaitForEvents() override
;
95 QuicConnectionId
GenerateNewConnectionId() override
;
97 // "Connect" to the QUIC server, including performing synchronous crypto
101 // Start the crypto handshake. This can be done in place of the synchronous
102 // Connect(), but callers are responsible for making sure the crypto handshake
106 // Disconnects from the QUIC server.
109 // Sends an HTTP request and does not wait for response before returning.
110 void SendRequest(const HttpRequestInfo
& headers
,
111 base::StringPiece body
,
114 // Sends an HTTP request and waits for response before returning.
115 void SendRequestAndWaitForResponse(const HttpRequestInfo
& headers
,
116 base::StringPiece body
,
119 // Sends a request simple GET for each URL in |args|, and then waits for
121 void SendRequestsAndWaitForResponse(
122 const base::CommandLine::StringVector
& url_list
);
124 // Migrate to a new socket during an active connection.
125 bool MigrateSocket(const IPAddressNumber
& new_host
);
127 // QuicPacketReader::Visitor
128 void OnReadError(int result
) override
;
129 bool OnPacket(const QuicEncryptedPacket
& packet
,
130 IPEndPoint local_address
,
131 IPEndPoint peer_address
) override
;
133 // QuicDataStream::Visitor
134 void OnClose(QuicDataStream
* stream
) override
;
136 // If the crypto handshake has not yet been confirmed, adds the data to the
137 // queue of data to resend if the client receives a stateless reject.
138 // Otherwise, deletes the data. Takes ownerership of |data_to_resend|.
139 void MaybeAddQuicDataToResend(QuicDataToResend
* data_to_resend
);
141 void set_bind_to_address(IPAddressNumber address
) {
142 bind_to_address_
= address
;
145 IPAddressNumber
bind_to_address() const { return bind_to_address_
; }
147 void set_local_port(int local_port
) { local_port_
= local_port
; }
149 const IPEndPoint
& server_address() const { return server_address_
; }
151 const IPEndPoint
& client_address() const { return client_address_
; }
153 // Takes ownership of the listener.
154 void set_response_listener(ResponseListener
* listener
) {
155 response_listener_
.reset(listener
);
158 void set_store_response(bool val
) { store_response_
= val
; }
160 size_t latest_response_code() const;
161 const std::string
& latest_response_headers() const;
162 const std::string
& latest_response_body() const;
165 virtual QuicConnectionHelper
* CreateQuicConnectionHelper();
166 virtual QuicPacketWriter
* CreateQuicPacketWriter();
169 friend class net::tools::test::QuicClientPeer
;
171 // Specific QuicClient class for storing data to resend.
172 class ClientQuicDataToResend
: public QuicDataToResend
{
174 // Takes ownership of |headers|.
175 ClientQuicDataToResend(HttpRequestInfo
* headers
,
176 base::StringPiece body
,
178 QuicSimpleClient
* client
)
179 : QuicDataToResend(headers
, body
, fin
), client_(client
) {
184 ~ClientQuicDataToResend() override
{}
186 void Resend() override
;
189 QuicSimpleClient
* client_
;
191 DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend
);
194 // Used during initialization: creates the UDP socket FD, sets socket options,
195 // and binds the socket to our address.
196 bool CreateUDPSocket();
198 // Read a UDP packet and hand it to the framer.
199 bool ReadAndProcessPacket();
201 void StartPacketReaderIfNotStarted();
203 // Used by |helper_| to time alarms.
206 // Address of the server.
207 const IPEndPoint server_address_
;
209 // Address of the client if the client is connected to the server.
210 IPEndPoint client_address_
;
212 // If initialized, the address to bind to.
213 IPAddressNumber bind_to_address_
;
214 // Local port to bind to. Initialize to 0.
217 // UDP socket connected to the server.
218 scoped_ptr
<UDPClientSocket
> socket_
;
220 // Helper to be used by created connections.
221 scoped_ptr
<QuicConnectionHelper
> helper_
;
223 // Listens for full responses.
224 scoped_ptr
<ResponseListener
> response_listener_
;
226 // Tracks if the client is initialized to connect.
229 // If overflow_supported_ is true, this will be the number of packets dropped
230 // during the lifetime of the server.
231 QuicPacketCount packets_dropped_
;
233 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
234 // because the socket would otherwise overflow.
235 bool overflow_supported_
;
237 // If true, store the latest response code, headers, and body.
238 bool store_response_
;
239 // HTTP response code from most recent response.
240 size_t latest_response_code_
;
241 // HTTP headers from most recent response.
242 std::string latest_response_headers_
;
243 // Body of most recent response.
244 std::string latest_response_body_
;
246 // Keeps track of any data sent before the handshake.
247 std::vector
<QuicDataToResend
*> data_sent_before_handshake_
;
249 // Once the client receives a stateless reject, keeps track of any data that
250 // must be resent upon a subsequent successful connection.
251 std::vector
<QuicDataToResend
*> data_to_resend_on_connect_
;
253 // The log used for the sockets.
256 scoped_ptr
<QuicPacketReader
> packet_reader_
;
258 bool packet_reader_started_
;
260 base::WeakPtrFactory
<QuicSimpleClient
> weak_factory_
;
262 DISALLOW_COPY_AND_ASSIGN(QuicSimpleClient
);
268 #endif // NET_TOOLS_QUIC_QUIC_SIMPLE_CLIENT_H_