| 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 |