OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/test_tools/quic_test_client.h" | 5 #include "net/tools/quic/test_tools/quic_test_client.h" |
6 | 6 |
7 #include "base/time/time.h" | 7 #include "base/time/time.h" |
8 #include "net/base/completion_callback.h" | 8 #include "net/base/completion_callback.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/cert/cert_verify_result.h" | 10 #include "net/cert/cert_verify_result.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 // RecordingProofVerifier accepts any certificate chain and records the common | 36 // RecordingProofVerifier accepts any certificate chain and records the common |
37 // name of the leaf. | 37 // name of the leaf. |
38 class RecordingProofVerifier : public ProofVerifier { | 38 class RecordingProofVerifier : public ProofVerifier { |
39 public: | 39 public: |
40 // ProofVerifier interface. | 40 // ProofVerifier interface. |
41 virtual Status VerifyProof(const string& hostname, | 41 virtual Status VerifyProof(const string& hostname, |
42 const string& server_config, | 42 const string& server_config, |
43 const vector<string>& certs, | 43 const vector<string>& certs, |
44 const string& signature, | 44 const string& signature, |
45 const net::ProofVerifyContext* context, | 45 const ProofVerifyContext* context, |
46 string* error_details, | 46 string* error_details, |
47 scoped_ptr<ProofVerifyDetails>* details, | 47 scoped_ptr<ProofVerifyDetails>* details, |
48 ProofVerifierCallback* callback) OVERRIDE { | 48 ProofVerifierCallback* callback) OVERRIDE { |
49 common_name_.clear(); | 49 common_name_.clear(); |
50 if (certs.empty()) { | 50 if (certs.empty()) { |
51 return FAILURE; | 51 return FAILURE; |
52 } | 52 } |
53 | 53 |
54 // Convert certs to X509Certificate. | 54 // Convert certs to X509Certificate. |
55 vector<StringPiece> cert_pieces(certs.size()); | 55 vector<StringPiece> cert_pieces(certs.size()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 !uri.starts_with("http://")) { | 89 !uri.starts_with("http://")) { |
90 // If we have a relative URL, set some defaults. | 90 // If we have a relative URL, set some defaults. |
91 string full_uri = secure ? "https://www.google.com" : | 91 string full_uri = secure ? "https://www.google.com" : |
92 "http://www.google.com"; | 92 "http://www.google.com"; |
93 full_uri.append(uri.as_string()); | 93 full_uri.append(uri.as_string()); |
94 headers->SetRequestUri(full_uri); | 94 headers->SetRequestUri(full_uri); |
95 } | 95 } |
96 return headers; | 96 return headers; |
97 } | 97 } |
98 | 98 |
99 // A quic client which allows mocking out writes. | 99 MockableQuicClient::MockableQuicClient( |
100 class MockableQuicClient : public QuicClient { | 100 IPEndPoint server_address, |
101 public: | 101 const QuicServerId& server_id, |
102 MockableQuicClient(IPEndPoint server_address, | 102 const QuicVersionVector& supported_versions, |
103 const QuicServerId& server_id, | 103 uint32 initial_flow_control_window) |
104 const QuicVersionVector& supported_versions, | 104 : QuicClient(server_address, |
105 uint32 initial_flow_control_window) | 105 server_id, |
106 : QuicClient(server_address, | 106 supported_versions, |
107 server_id, | 107 false, |
108 supported_versions, | 108 initial_flow_control_window), |
109 false, | 109 override_connection_id_(0), |
110 initial_flow_control_window), | 110 test_writer_(NULL) {} |
111 override_connection_id_(0), | |
112 test_writer_(NULL) {} | |
113 | 111 |
114 MockableQuicClient(IPEndPoint server_address, | 112 MockableQuicClient::MockableQuicClient( |
115 const QuicServerId& server_id, | 113 IPEndPoint server_address, |
116 const QuicConfig& config, | 114 const QuicServerId& server_id, |
117 const QuicVersionVector& supported_versions, | 115 const QuicConfig& config, |
118 uint32 initial_flow_control_window) | 116 const QuicVersionVector& supported_versions, |
119 : QuicClient(server_address, | 117 uint32 initial_flow_control_window) |
120 server_id, | 118 : QuicClient(server_address, |
121 config, | 119 server_id, |
122 supported_versions, | 120 config, |
123 initial_flow_control_window), | 121 supported_versions, |
124 override_connection_id_(0), | 122 initial_flow_control_window), |
125 test_writer_(NULL) {} | 123 override_connection_id_(0), |
| 124 test_writer_(NULL) {} |
126 | 125 |
127 virtual ~MockableQuicClient() { | 126 MockableQuicClient::~MockableQuicClient() { |
128 if (connected()) { | 127 if (connected()) { |
129 Disconnect(); | 128 Disconnect(); |
130 } | |
131 } | 129 } |
| 130 } |
132 | 131 |
133 virtual QuicPacketWriter* CreateQuicPacketWriter() OVERRIDE { | 132 QuicPacketWriter* MockableQuicClient::CreateQuicPacketWriter() { |
134 QuicPacketWriter* writer = QuicClient::CreateQuicPacketWriter(); | 133 QuicPacketWriter* writer = QuicClient::CreateQuicPacketWriter(); |
135 if (!test_writer_) { | 134 if (!test_writer_) { |
136 return writer; | 135 return writer; |
137 } | |
138 test_writer_->set_writer(writer); | |
139 return test_writer_; | |
140 } | 136 } |
| 137 test_writer_->set_writer(writer); |
| 138 return test_writer_; |
| 139 } |
141 | 140 |
142 virtual QuicConnectionId GenerateConnectionId() OVERRIDE { | 141 QuicConnectionId MockableQuicClient::GenerateConnectionId() { |
143 return override_connection_id_ ? override_connection_id_ | 142 return override_connection_id_ ? override_connection_id_ |
144 : QuicClient::GenerateConnectionId(); | 143 : QuicClient::GenerateConnectionId(); |
145 } | 144 } |
146 | 145 |
147 // Takes ownership of writer. | 146 // Takes ownership of writer. |
148 void UseWriter(QuicPacketWriterWrapper* writer) { | 147 void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) { |
149 CHECK(test_writer_ == NULL); | 148 CHECK(test_writer_ == NULL); |
150 test_writer_ = writer; | 149 test_writer_ = writer; |
151 } | 150 } |
152 | 151 |
153 void UseConnectionId(QuicConnectionId connection_id) { | 152 void MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) { |
154 override_connection_id_ = connection_id; | 153 override_connection_id_ = connection_id; |
155 } | 154 } |
156 | |
157 virtual int ReadPacket(char* buffer, | |
158 int buffer_len, | |
159 IPEndPoint* server_address, | |
160 IPAddressNumber* client_ip) OVERRIDE { | |
161 return QuicClient::ReadPacket( | |
162 buffer, buffer_len, server_address, client_ip); | |
163 } | |
164 | |
165 private: | |
166 QuicConnectionId override_connection_id_; // ConnectionId to use, if nonzero | |
167 QuicPacketWriterWrapper* test_writer_; | |
168 }; | |
169 | 155 |
170 QuicTestClient::QuicTestClient(IPEndPoint server_address, | 156 QuicTestClient::QuicTestClient(IPEndPoint server_address, |
171 const string& server_hostname, | 157 const string& server_hostname, |
172 const QuicVersionVector& supported_versions) | 158 const QuicVersionVector& supported_versions) |
173 : client_(new MockableQuicClient(server_address, | 159 : client_(new MockableQuicClient(server_address, |
174 QuicServerId(server_hostname, | 160 QuicServerId(server_hostname, |
175 server_address.port(), | 161 server_address.port(), |
176 false, | 162 false, |
177 PRIVACY_MODE_DISABLED), | 163 PRIVACY_MODE_DISABLED), |
178 supported_versions, | 164 supported_versions, |
179 kInitialFlowControlWindowForTest)) { | 165 kInitialFlowControlWindowForTest)) { |
180 Initialize(server_address, server_hostname, true); | 166 Initialize(true); |
181 } | 167 } |
182 | 168 |
183 QuicTestClient::QuicTestClient(IPEndPoint server_address, | 169 QuicTestClient::QuicTestClient(IPEndPoint server_address, |
184 const string& server_hostname, | 170 const string& server_hostname, |
185 bool secure, | 171 bool secure, |
186 const QuicVersionVector& supported_versions) | 172 const QuicVersionVector& supported_versions) |
187 : client_(new MockableQuicClient(server_address, | 173 : client_(new MockableQuicClient(server_address, |
188 QuicServerId(server_hostname, | 174 QuicServerId(server_hostname, |
189 server_address.port(), | 175 server_address.port(), |
190 secure, | 176 secure, |
191 PRIVACY_MODE_DISABLED), | 177 PRIVACY_MODE_DISABLED), |
192 supported_versions, | 178 supported_versions, |
193 kInitialFlowControlWindowForTest)) { | 179 kInitialFlowControlWindowForTest)) { |
194 Initialize(server_address, server_hostname, secure); | 180 Initialize(secure); |
195 } | 181 } |
196 | 182 |
197 QuicTestClient::QuicTestClient( | 183 QuicTestClient::QuicTestClient( |
198 IPEndPoint server_address, | 184 IPEndPoint server_address, |
199 const string& server_hostname, | 185 const string& server_hostname, |
200 bool secure, | 186 bool secure, |
201 const QuicConfig& config, | 187 const QuicConfig& config, |
202 const QuicVersionVector& supported_versions, | 188 const QuicVersionVector& supported_versions, |
203 uint32 client_initial_flow_control_receive_window) | 189 uint32 client_initial_flow_control_receive_window) |
204 : client_( | 190 : client_( |
205 new MockableQuicClient(server_address, | 191 new MockableQuicClient(server_address, |
206 QuicServerId(server_hostname, | 192 QuicServerId(server_hostname, |
207 server_address.port(), | 193 server_address.port(), |
208 secure, | 194 secure, |
209 PRIVACY_MODE_DISABLED), | 195 PRIVACY_MODE_DISABLED), |
210 config, | 196 config, |
211 supported_versions, | 197 supported_versions, |
212 client_initial_flow_control_receive_window)) { | 198 client_initial_flow_control_receive_window)) { |
213 Initialize(server_address, server_hostname, secure); | 199 Initialize(secure); |
214 } | 200 } |
215 | 201 |
216 void QuicTestClient::Initialize(IPEndPoint address, | 202 QuicTestClient::QuicTestClient() { |
217 const string& hostname, | 203 } |
218 bool secure) { | 204 |
219 server_address_ = address; | 205 void QuicTestClient::Initialize(bool secure) { |
220 priority_ = 3; | 206 priority_ = 3; |
221 connect_attempted_ = false; | 207 connect_attempted_ = false; |
222 secure_ = secure; | 208 secure_ = secure; |
223 auto_reconnect_ = false; | 209 auto_reconnect_ = false; |
224 buffer_body_ = true; | 210 buffer_body_ = true; |
225 proof_verifier_ = NULL; | 211 proof_verifier_ = NULL; |
226 ClearPerRequestState(); | 212 ClearPerRequestState(); |
227 ExpectCertificates(secure_); | 213 ExpectCertificates(secure_); |
228 } | 214 } |
229 | 215 |
230 QuicTestClient::~QuicTestClient() { | 216 QuicTestClient::~QuicTestClient() { |
231 if (stream_) { | 217 if (stream_) { |
232 stream_->set_visitor(NULL); | 218 stream_->set_visitor(NULL); |
233 } | 219 } |
234 } | 220 } |
235 | 221 |
236 void QuicTestClient::ExpectCertificates(bool on) { | 222 void QuicTestClient::ExpectCertificates(bool on) { |
237 if (on) { | 223 if (on) { |
238 proof_verifier_ = new RecordingProofVerifier; | 224 proof_verifier_ = new RecordingProofVerifier; |
239 client_->SetProofVerifier(proof_verifier_); | 225 client_->SetProofVerifier(proof_verifier_); |
240 } else { | 226 } else { |
241 proof_verifier_ = NULL; | 227 proof_verifier_ = NULL; |
242 client_->SetProofVerifier(NULL); | 228 client_->SetProofVerifier(NULL); |
243 } | 229 } |
244 } | 230 } |
245 | 231 |
246 ssize_t QuicTestClient::SendRequest(const string& uri) { | 232 ssize_t QuicTestClient::SendRequest(const string& uri) { |
247 HTTPMessage message(HttpConstants::HTTP_1_1, HttpConstants::GET, uri); | 233 HTTPMessage message(HttpConstants::HTTP_1_1, |
| 234 HttpConstants::GET, |
| 235 uri); |
248 return SendMessage(message); | 236 return SendMessage(message); |
249 } | 237 } |
250 | 238 |
251 ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) { | 239 ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) { |
252 stream_ = NULL; // Always force creation of a stream for SendMessage. | 240 stream_ = NULL; // Always force creation of a stream for SendMessage. |
253 | 241 |
254 // If we're not connected, try to find an sni hostname. | 242 // If we're not connected, try to find an sni hostname. |
255 if (!connected()) { | 243 if (!connected()) { |
256 GURL url(message.headers()->request_uri().as_string()); | 244 GURL url(message.headers()->request_uri().as_string()); |
257 if (!url.host().empty()) { | 245 if (!url.host().empty()) { |
258 client_->set_server_id( | 246 client_->set_server_id( |
259 QuicServerId(url.host(), url.EffectiveIntPort(), | 247 QuicServerId(url.host(), |
260 url.SchemeIs("https"), PRIVACY_MODE_DISABLED)); | 248 url.EffectiveIntPort(), |
| 249 url.SchemeIs("https"), |
| 250 PRIVACY_MODE_DISABLED)); |
261 } | 251 } |
262 } | 252 } |
263 | 253 |
264 QuicSpdyClientStream* stream = GetOrCreateStream(); | 254 QuicSpdyClientStream* stream = GetOrCreateStream(); |
265 if (!stream) { return 0; } | 255 if (!stream) { return 0; } |
266 | 256 |
267 scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(), | 257 scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(), |
268 secure_)); | 258 secure_)); |
269 ssize_t ret = GetOrCreateStream()->SendRequest( | 259 ssize_t ret = GetOrCreateStream()->SendRequest( |
270 munged_headers.get() ? *munged_headers.get() : *message.headers(), | 260 munged_headers.get() ? *munged_headers.get() : *message.headers(), |
271 message.body(), | 261 message.body(), |
272 message.has_complete_message()); | 262 message.has_complete_message()); |
273 WaitForWriteToFlush(); | 263 WaitForWriteToFlush(); |
274 return ret; | 264 return ret; |
275 } | 265 } |
276 | 266 |
277 ssize_t QuicTestClient::SendData(string data, bool last_data) { | 267 ssize_t QuicTestClient::SendData(string data, bool last_data) { |
278 QuicSpdyClientStream* stream = GetOrCreateStream(); | 268 QuicSpdyClientStream* stream = GetOrCreateStream(); |
279 if (!stream) { return 0; } | 269 if (!stream) { return 0; } |
280 GetOrCreateStream()->SendBody(data, last_data); | 270 GetOrCreateStream()->SendBody(data, last_data); |
281 WaitForWriteToFlush(); | 271 WaitForWriteToFlush(); |
282 return data.length(); | 272 return data.length(); |
283 } | 273 } |
284 | 274 |
285 QuicPacketCreator::Options* QuicTestClient::options() { | 275 QuicPacketCreator::Options* QuicTestClient::options() { |
286 return client_->options(); | 276 return client_->options(); |
287 } | 277 } |
288 | 278 |
| 279 bool QuicTestClient::response_complete() const { |
| 280 return response_complete_; |
| 281 } |
| 282 |
| 283 int QuicTestClient::response_header_size() const { |
| 284 return response_header_size_; |
| 285 } |
| 286 |
| 287 int QuicTestClient::response_body_size() const { |
| 288 return response_body_size_; |
| 289 } |
| 290 |
| 291 bool QuicTestClient::buffer_body() const { |
| 292 return buffer_body_; |
| 293 } |
| 294 |
| 295 void QuicTestClient::set_buffer_body(bool buffer_body) { |
| 296 buffer_body_ = buffer_body; |
| 297 } |
| 298 |
| 299 bool QuicTestClient::ServerInLameDuckMode() const { |
| 300 return false; |
| 301 } |
| 302 |
| 303 const string& QuicTestClient::response_body() { |
| 304 return response_; |
| 305 } |
| 306 |
289 string QuicTestClient::SendCustomSynchronousRequest( | 307 string QuicTestClient::SendCustomSynchronousRequest( |
290 const HTTPMessage& message) { | 308 const HTTPMessage& message) { |
291 SendMessage(message); | 309 SendMessage(message); |
292 WaitForResponse(); | 310 WaitForResponse(); |
293 return response_; | 311 return response_; |
294 } | 312 } |
295 | 313 |
296 string QuicTestClient::SendSynchronousRequest(const string& uri) { | 314 string QuicTestClient::SendSynchronousRequest(const string& uri) { |
297 if (SendRequest(uri) == 0) { | 315 if (SendRequest(uri) == 0) { |
298 DLOG(ERROR) << "Failed the request for uri:" << uri; | 316 DLOG(ERROR) << "Failed the request for uri:" << uri; |
(...skipping 29 matching lines...) Expand all Loading... |
328 } | 346 } |
329 | 347 |
330 QuicClient* QuicTestClient::client() { return client_.get(); } | 348 QuicClient* QuicTestClient::client() { return client_.get(); } |
331 | 349 |
332 const string& QuicTestClient::cert_common_name() const { | 350 const string& QuicTestClient::cert_common_name() const { |
333 return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_) | 351 return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_) |
334 ->common_name(); | 352 ->common_name(); |
335 } | 353 } |
336 | 354 |
337 QuicTagValueMap QuicTestClient::GetServerConfig() const { | 355 QuicTagValueMap QuicTestClient::GetServerConfig() const { |
338 net::QuicCryptoClientConfig* config = | 356 QuicCryptoClientConfig* config = |
339 QuicClientPeer::GetCryptoConfig(client_.get()); | 357 QuicClientPeer::GetCryptoConfig(client_.get()); |
340 net::QuicCryptoClientConfig::CachedState* state = | 358 QuicCryptoClientConfig::CachedState* state = |
341 config->LookupOrCreate(client_->server_id()); | 359 config->LookupOrCreate(client_->server_id()); |
342 const net::CryptoHandshakeMessage* handshake_msg = state->GetServerConfig(); | 360 const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig(); |
343 if (handshake_msg != NULL) { | 361 if (handshake_msg != NULL) { |
344 return handshake_msg->tag_value_map(); | 362 return handshake_msg->tag_value_map(); |
345 } else { | 363 } else { |
346 return QuicTagValueMap(); | 364 return QuicTagValueMap(); |
347 } | 365 } |
348 } | 366 } |
349 | 367 |
350 bool QuicTestClient::connected() const { | 368 bool QuicTestClient::connected() const { |
351 return client_->connected(); | 369 return client_->connected(); |
352 } | 370 } |
353 | 371 |
354 void QuicTestClient::WaitForResponse() { | |
355 if (stream_ == NULL) { | |
356 // The client has likely disconnected. | |
357 return; | |
358 } | |
359 client_->WaitForStreamToClose(stream_->id()); | |
360 } | |
361 | |
362 void QuicTestClient::Connect() { | 372 void QuicTestClient::Connect() { |
363 DCHECK(!connected()); | 373 DCHECK(!connected()); |
364 if (!connect_attempted_) { | 374 if (!connect_attempted_) { |
365 client_->Initialize(); | 375 client_->Initialize(); |
366 } | 376 } |
367 client_->Connect(); | 377 client_->Connect(); |
368 connect_attempted_ = true; | 378 connect_attempted_ = true; |
369 } | 379 } |
370 | 380 |
371 void QuicTestClient::ResetConnection() { | 381 void QuicTestClient::ResetConnection() { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 502 |
493 void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) { | 503 void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) { |
494 client_->UseWriter(writer); | 504 client_->UseWriter(writer); |
495 } | 505 } |
496 | 506 |
497 void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) { | 507 void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) { |
498 DCHECK(!connected()); | 508 DCHECK(!connected()); |
499 client_->UseConnectionId(connection_id); | 509 client_->UseConnectionId(connection_id); |
500 } | 510 } |
501 | 511 |
| 512 ssize_t QuicTestClient::SendAndWaitForResponse(const void *buffer, |
| 513 size_t size) { |
| 514 LOG(DFATAL) << "Not implemented"; |
| 515 return 0; |
| 516 } |
| 517 void QuicTestClient::Bind(IPEndPoint* local_address) { |
| 518 DLOG(WARNING) << "Bind will be done during connect"; |
| 519 } |
| 520 string QuicTestClient::SerializeMessage(const HTTPMessage& message) { |
| 521 LOG(DFATAL) << "Not implemented"; |
| 522 return ""; |
| 523 } |
| 524 IPAddressNumber QuicTestClient::bind_to_address() const { |
| 525 return client_->bind_to_address(); |
| 526 } |
| 527 void QuicTestClient::set_bind_to_address(IPAddressNumber address) { |
| 528 client_->set_bind_to_address(address); |
| 529 } |
| 530 const IPEndPoint& QuicTestClient::address() const { |
| 531 LOG(DFATAL) << "Not implemented"; |
| 532 return client_->server_address(); |
| 533 } |
| 534 size_t QuicTestClient::requests_sent() const { |
| 535 LOG(DFATAL) << "Not implemented"; |
| 536 return 0; |
| 537 } |
| 538 |
502 void QuicTestClient::WaitForWriteToFlush() { | 539 void QuicTestClient::WaitForWriteToFlush() { |
503 while (connected() && client()->session()->HasDataToWrite()) { | 540 while (connected() && client()->session()->HasDataToWrite()) { |
504 client_->WaitForEvents(); | 541 client_->WaitForEvents(); |
505 } | 542 } |
506 } | 543 } |
507 | 544 |
508 } // namespace test | 545 } // namespace test |
509 } // namespace tools | 546 } // namespace tools |
510 } // namespace net | 547 } // namespace net |
OLD | NEW |