Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: net/tools/quic/test_tools/quic_test_client.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "net/tools/quic/test_tools/quic_test_client.h"
6
7 #include "base/time/time.h"
8 #include "net/base/completion_callback.h"
9 #include "net/base/net_errors.h"
10 #include "net/cert/cert_verify_result.h"
11 #include "net/cert/x509_certificate.h"
12 #include "net/quic/crypto/proof_verifier.h"
13 #include "net/quic/quic_server_id.h"
14 #include "net/quic/test_tools/quic_connection_peer.h"
15 #include "net/quic/test_tools/quic_session_peer.h"
16 #include "net/quic/test_tools/quic_test_utils.h"
17 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
18 #include "net/tools/balsa/balsa_headers.h"
19 #include "net/tools/quic/quic_epoll_connection_helper.h"
20 #include "net/tools/quic/quic_packet_writer_wrapper.h"
21 #include "net/tools/quic/quic_spdy_client_stream.h"
22 #include "net/tools/quic/test_tools/http_message.h"
23 #include "net/tools/quic/test_tools/quic_client_peer.h"
24 #include "url/gurl.h"
25
26 using base::StringPiece;
27 using net::QuicServerId;
28 using net::test::QuicConnectionPeer;
29 using net::test::QuicSessionPeer;
30 using net::test::ReliableQuicStreamPeer;
31 using std::string;
32 using std::vector;
33
34 namespace net {
35 namespace tools {
36 namespace test {
37 namespace {
38
39 // RecordingProofVerifier accepts any certificate chain and records the common
40 // name of the leaf.
41 class RecordingProofVerifier : public ProofVerifier {
42 public:
43 // ProofVerifier interface.
44 QuicAsyncStatus VerifyProof(const string& hostname,
45 const string& server_config,
46 const vector<string>& certs,
47 const string& signature,
48 const ProofVerifyContext* context,
49 string* error_details,
50 scoped_ptr<ProofVerifyDetails>* details,
51 ProofVerifierCallback* callback) override {
52 common_name_.clear();
53 if (certs.empty()) {
54 return QUIC_FAILURE;
55 }
56
57 // Convert certs to X509Certificate.
58 vector<StringPiece> cert_pieces(certs.size());
59 for (unsigned i = 0; i < certs.size(); i++) {
60 cert_pieces[i] = StringPiece(certs[i]);
61 }
62 scoped_refptr<net::X509Certificate> cert =
63 net::X509Certificate::CreateFromDERCertChain(cert_pieces);
64 if (!cert.get()) {
65 return QUIC_FAILURE;
66 }
67
68 common_name_ = cert->subject().GetDisplayName();
69 return QUIC_SUCCESS;
70 }
71
72 const string& common_name() const { return common_name_; }
73
74 private:
75 string common_name_;
76 };
77
78 } // anonymous namespace
79
80 BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers,
81 bool secure) {
82 StringPiece uri = const_headers->request_uri();
83 if (uri.empty()) {
84 return nullptr;
85 }
86 if (const_headers->request_method() == "CONNECT") {
87 return nullptr;
88 }
89 BalsaHeaders* headers = new BalsaHeaders;
90 headers->CopyFrom(*const_headers);
91 if (!uri.starts_with("https://") &&
92 !uri.starts_with("http://")) {
93 // If we have a relative URL, set some defaults.
94 string full_uri = secure ? "https://www.google.com" :
95 "http://www.google.com";
96 full_uri.append(uri.as_string());
97 headers->SetRequestUri(full_uri);
98 }
99 return headers;
100 }
101
102 MockableQuicClient::MockableQuicClient(
103 IPEndPoint server_address,
104 const QuicServerId& server_id,
105 const QuicVersionVector& supported_versions,
106 EpollServer* epoll_server)
107 : QuicClient(server_address,
108 server_id,
109 supported_versions,
110 epoll_server),
111 override_connection_id_(0),
112 test_writer_(nullptr) {}
113
114 MockableQuicClient::MockableQuicClient(
115 IPEndPoint server_address,
116 const QuicServerId& server_id,
117 const QuicConfig& config,
118 const QuicVersionVector& supported_versions,
119 EpollServer* epoll_server)
120 : QuicClient(server_address,
121 server_id,
122 supported_versions,
123 config,
124 epoll_server),
125 override_connection_id_(0),
126 test_writer_(nullptr) {}
127
128 MockableQuicClient::~MockableQuicClient() {
129 if (connected()) {
130 Disconnect();
131 }
132 }
133
134 QuicPacketWriter* MockableQuicClient::CreateQuicPacketWriter() {
135 QuicPacketWriter* writer = QuicClient::CreateQuicPacketWriter();
136 if (!test_writer_) {
137 return writer;
138 }
139 test_writer_->set_writer(writer);
140 return test_writer_;
141 }
142
143 QuicConnectionId MockableQuicClient::GenerateConnectionId() {
144 return override_connection_id_ ? override_connection_id_
145 : QuicClient::GenerateConnectionId();
146 }
147
148 // Takes ownership of writer.
149 void MockableQuicClient::UseWriter(QuicPacketWriterWrapper* writer) {
150 CHECK(test_writer_ == nullptr);
151 test_writer_ = writer;
152 }
153
154 void MockableQuicClient::UseConnectionId(QuicConnectionId connection_id) {
155 override_connection_id_ = connection_id;
156 }
157
158 QuicTestClient::QuicTestClient(IPEndPoint server_address,
159 const string& server_hostname,
160 bool secure,
161 const QuicVersionVector& supported_versions)
162 : client_(new MockableQuicClient(server_address,
163 QuicServerId(server_hostname,
164 server_address.port(),
165 secure,
166 PRIVACY_MODE_DISABLED),
167 supported_versions,
168 &epoll_server_)) {
169 Initialize(secure);
170 }
171
172 QuicTestClient::QuicTestClient(
173 IPEndPoint server_address,
174 const string& server_hostname,
175 bool secure,
176 const QuicConfig& config,
177 const QuicVersionVector& supported_versions)
178 : client_(
179 new MockableQuicClient(server_address,
180 QuicServerId(server_hostname,
181 server_address.port(),
182 secure,
183 PRIVACY_MODE_DISABLED),
184 config,
185 supported_versions,
186 &epoll_server_)) {
187 Initialize(secure);
188 }
189
190 QuicTestClient::QuicTestClient() {
191 }
192
193 QuicTestClient::~QuicTestClient() {
194 if (stream_) {
195 stream_->set_visitor(nullptr);
196 }
197 }
198
199 void QuicTestClient::Initialize(bool secure) {
200 priority_ = 3;
201 connect_attempted_ = false;
202 secure_ = secure;
203 auto_reconnect_ = false;
204 buffer_body_ = true;
205 fec_policy_ = FEC_PROTECT_OPTIONAL;
206 proof_verifier_ = nullptr;
207 ClearPerRequestState();
208 ExpectCertificates(secure_);
209 // As chrome will generally do this, we want it to be the default when it's
210 // not overridden.
211 if (!client_->config()->HasSetBytesForConnectionIdToSend()) {
212 client_->config()->SetBytesForConnectionIdToSend(0);
213 }
214 }
215
216 void QuicTestClient::ExpectCertificates(bool on) {
217 if (on) {
218 proof_verifier_ = new RecordingProofVerifier;
219 client_->SetProofVerifier(proof_verifier_);
220 } else {
221 proof_verifier_ = nullptr;
222 client_->SetProofVerifier(nullptr);
223 }
224 }
225
226 void QuicTestClient::SetUserAgentID(const string& user_agent_id) {
227 client_->SetUserAgentID(user_agent_id);
228 }
229
230 ssize_t QuicTestClient::SendRequest(const string& uri) {
231 HTTPMessage message(HttpConstants::HTTP_1_1,
232 HttpConstants::GET,
233 uri);
234 return SendMessage(message);
235 }
236
237 ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) {
238 stream_ = nullptr; // Always force creation of a stream for SendMessage.
239
240 // If we're not connected, try to find an sni hostname.
241 if (!connected()) {
242 GURL url(message.headers()->request_uri().as_string());
243 if (!url.host().empty()) {
244 client_->set_server_id(
245 QuicServerId(url.host(),
246 url.EffectiveIntPort(),
247 url.SchemeIs("https"),
248 PRIVACY_MODE_DISABLED));
249 }
250 }
251
252 QuicSpdyClientStream* stream = GetOrCreateStream();
253 if (!stream) { return 0; }
254
255 scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(),
256 secure_));
257 ssize_t ret = GetOrCreateStream()->SendRequest(
258 munged_headers.get() ? *munged_headers : *message.headers(),
259 message.body(), message.has_complete_message());
260 WaitForWriteToFlush();
261 return ret;
262 }
263
264 ssize_t QuicTestClient::SendData(string data, bool last_data) {
265 return SendData(data, last_data, nullptr);
266 }
267
268 ssize_t QuicTestClient::SendData(string data,
269 bool last_data,
270 QuicAckNotifier::DelegateInterface* delegate) {
271 QuicSpdyClientStream* stream = GetOrCreateStream();
272 if (!stream) { return 0; }
273 GetOrCreateStream()->SendBody(data, last_data, delegate);
274 WaitForWriteToFlush();
275 return data.length();
276 }
277
278 bool QuicTestClient::response_complete() const {
279 return response_complete_;
280 }
281
282 int QuicTestClient::response_header_size() const {
283 return response_header_size_;
284 }
285
286 int64 QuicTestClient::response_body_size() const {
287 return response_body_size_;
288 }
289
290 bool QuicTestClient::buffer_body() const {
291 return buffer_body_;
292 }
293
294 void QuicTestClient::set_buffer_body(bool buffer_body) {
295 buffer_body_ = buffer_body;
296 }
297
298 bool QuicTestClient::ServerInLameDuckMode() const {
299 return false;
300 }
301
302 const string& QuicTestClient::response_body() {
303 return response_;
304 }
305
306 string QuicTestClient::SendCustomSynchronousRequest(
307 const HTTPMessage& message) {
308 SendMessage(message);
309 WaitForResponse();
310 return response_;
311 }
312
313 string QuicTestClient::SendSynchronousRequest(const string& uri) {
314 if (SendRequest(uri) == 0) {
315 DLOG(ERROR) << "Failed the request for uri:" << uri;
316 return "";
317 }
318 WaitForResponse();
319 return response_;
320 }
321
322 QuicSpdyClientStream* QuicTestClient::GetOrCreateStream() {
323 if (!connect_attempted_ || auto_reconnect_) {
324 if (!connected()) {
325 Connect();
326 }
327 if (!connected()) {
328 return nullptr;
329 }
330 }
331 if (!stream_) {
332 stream_ = client_->CreateReliableClientStream();
333 if (stream_ == nullptr) {
334 return nullptr;
335 }
336 stream_->set_visitor(this);
337 reinterpret_cast<QuicSpdyClientStream*>(stream_)->set_priority(priority_);
338 // Set FEC policy on stream.
339 ReliableQuicStreamPeer::SetFecPolicy(stream_, fec_policy_);
340 }
341
342 return stream_;
343 }
344
345 QuicErrorCode QuicTestClient::connection_error() {
346 return client()->session()->error();
347 }
348
349 MockableQuicClient* QuicTestClient::client() { return client_.get(); }
350
351 const string& QuicTestClient::cert_common_name() const {
352 return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_)
353 ->common_name();
354 }
355
356 QuicTagValueMap QuicTestClient::GetServerConfig() const {
357 QuicCryptoClientConfig* config =
358 QuicClientPeer::GetCryptoConfig(client_.get());
359 QuicCryptoClientConfig::CachedState* state =
360 config->LookupOrCreate(client_->server_id());
361 const CryptoHandshakeMessage* handshake_msg = state->GetServerConfig();
362 if (handshake_msg != nullptr) {
363 return handshake_msg->tag_value_map();
364 } else {
365 return QuicTagValueMap();
366 }
367 }
368
369 bool QuicTestClient::connected() const {
370 return client_->connected();
371 }
372
373 void QuicTestClient::Connect() {
374 DCHECK(!connected());
375 if (!connect_attempted_) {
376 client_->Initialize();
377 }
378 client_->Connect();
379 connect_attempted_ = true;
380 }
381
382 void QuicTestClient::ResetConnection() {
383 Disconnect();
384 Connect();
385 }
386
387 void QuicTestClient::Disconnect() {
388 client_->Disconnect();
389 connect_attempted_ = false;
390 }
391
392 IPEndPoint QuicTestClient::LocalSocketAddress() const {
393 return client_->client_address();
394 }
395
396 void QuicTestClient::ClearPerRequestState() {
397 stream_error_ = QUIC_STREAM_NO_ERROR;
398 stream_ = nullptr;
399 response_ = "";
400 response_complete_ = false;
401 response_headers_complete_ = false;
402 headers_.Clear();
403 bytes_read_ = 0;
404 bytes_written_ = 0;
405 response_header_size_ = 0;
406 response_body_size_ = 0;
407 }
408
409 void QuicTestClient::WaitForResponseForMs(int timeout_ms) {
410 int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
411 int64 old_timeout_us = epoll_server()->timeout_in_us();
412 if (timeout_us > 0) {
413 epoll_server()->set_timeout_in_us(timeout_us);
414 }
415 const QuicClock* clock =
416 QuicConnectionPeer::GetHelper(client()->session()->connection())->
417 GetClock();
418 QuicTime end_waiting_time = clock->Now().Add(
419 QuicTime::Delta::FromMicroseconds(timeout_us));
420 while (stream_ != nullptr &&
421 !client_->session()->IsClosedStream(stream_->id()) &&
422 (timeout_us < 0 || clock->Now() < end_waiting_time)) {
423 client_->WaitForEvents();
424 }
425 if (timeout_us > 0) {
426 epoll_server()->set_timeout_in_us(old_timeout_us);
427 }
428 }
429
430 void QuicTestClient::WaitForInitialResponseForMs(int timeout_ms) {
431 int64 timeout_us = timeout_ms * base::Time::kMicrosecondsPerMillisecond;
432 int64 old_timeout_us = epoll_server()->timeout_in_us();
433 if (timeout_us > 0) {
434 epoll_server()->set_timeout_in_us(timeout_us);
435 }
436 const QuicClock* clock =
437 QuicConnectionPeer::GetHelper(client()->session()->connection())->
438 GetClock();
439 QuicTime end_waiting_time = clock->Now().Add(
440 QuicTime::Delta::FromMicroseconds(timeout_us));
441 while (stream_ != nullptr &&
442 !client_->session()->IsClosedStream(stream_->id()) &&
443 stream_->stream_bytes_read() == 0 &&
444 (timeout_us < 0 || clock->Now() < end_waiting_time)) {
445 client_->WaitForEvents();
446 }
447 if (timeout_us > 0) {
448 epoll_server()->set_timeout_in_us(old_timeout_us);
449 }
450 }
451
452 ssize_t QuicTestClient::Send(const void *buffer, size_t size) {
453 return SendData(string(static_cast<const char*>(buffer), size), false);
454 }
455
456 bool QuicTestClient::response_headers_complete() const {
457 if (stream_ != nullptr) {
458 return stream_->headers_decompressed();
459 } else {
460 return response_headers_complete_;
461 }
462 }
463
464 const BalsaHeaders* QuicTestClient::response_headers() const {
465 if (stream_ != nullptr) {
466 return &stream_->headers();
467 } else {
468 return &headers_;
469 }
470 }
471
472 int64 QuicTestClient::response_size() const {
473 return bytes_read_;
474 }
475
476 size_t QuicTestClient::bytes_read() const {
477 return bytes_read_;
478 }
479
480 size_t QuicTestClient::bytes_written() const {
481 return bytes_written_;
482 }
483
484 void QuicTestClient::OnClose(QuicDataStream* stream) {
485 if (stream_ != stream) {
486 return;
487 }
488 if (buffer_body()) {
489 // TODO(fnk): The stream still buffers the whole thing. Fix that.
490 response_ = stream_->data();
491 }
492 response_complete_ = true;
493 response_headers_complete_ = stream_->headers_decompressed();
494 headers_.CopyFrom(stream_->headers());
495 stream_error_ = stream_->stream_error();
496 bytes_read_ = stream_->stream_bytes_read() + stream_->header_bytes_read();
497 bytes_written_ =
498 stream_->stream_bytes_written() + stream_->header_bytes_written();
499 response_header_size_ = headers_.GetSizeForWriteBuffer();
500 response_body_size_ = stream_->data().size();
501 stream_ = nullptr;
502 }
503
504 void QuicTestClient::UseWriter(QuicPacketWriterWrapper* writer) {
505 client_->UseWriter(writer);
506 }
507
508 void QuicTestClient::UseConnectionId(QuicConnectionId connection_id) {
509 DCHECK(!connected());
510 client_->UseConnectionId(connection_id);
511 }
512
513 ssize_t QuicTestClient::SendAndWaitForResponse(const void *buffer,
514 size_t size) {
515 LOG(DFATAL) << "Not implemented";
516 return 0;
517 }
518
519 void QuicTestClient::Bind(IPEndPoint* local_address) {
520 DLOG(WARNING) << "Bind will be done during connect";
521 }
522
523 string QuicTestClient::SerializeMessage(const HTTPMessage& message) {
524 LOG(DFATAL) << "Not implemented";
525 return "";
526 }
527
528 IPAddressNumber QuicTestClient::bind_to_address() const {
529 return client_->bind_to_address();
530 }
531
532 void QuicTestClient::set_bind_to_address(IPAddressNumber address) {
533 client_->set_bind_to_address(address);
534 }
535
536 const IPEndPoint& QuicTestClient::address() const {
537 LOG(DFATAL) << "Not implemented";
538 return client_->server_address();
539 }
540
541 size_t QuicTestClient::requests_sent() const {
542 LOG(DFATAL) << "Not implemented";
543 return 0;
544 }
545
546 void QuicTestClient::WaitForWriteToFlush() {
547 while (connected() && client()->session()->HasDataToWrite()) {
548 client_->WaitForEvents();
549 }
550 }
551
552 void QuicTestClient::SetFecPolicy(FecPolicy fec_policy) {
553 fec_policy_ = fec_policy;
554 // Set policy for headers and crypto streams.
555 ReliableQuicStreamPeer::SetFecPolicy(
556 QuicSessionPeer::GetHeadersStream(client()->session()), fec_policy);
557 ReliableQuicStreamPeer::SetFecPolicy(client()->session()->GetCryptoStream(),
558 fec_policy);
559 }
560
561 } // namespace test
562 } // namespace tools
563 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/test_tools/quic_test_client.h ('k') | net/tools/quic/test_tools/quic_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698