| OLD | NEW |
| (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/socket/socket_test_util.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/bind.h" | |
| 12 #include "base/bind_helpers.h" | |
| 13 #include "base/callback_helpers.h" | |
| 14 #include "base/compiler_specific.h" | |
| 15 #include "base/message_loop/message_loop.h" | |
| 16 #include "base/run_loop.h" | |
| 17 #include "base/time/time.h" | |
| 18 #include "net/base/address_family.h" | |
| 19 #include "net/base/address_list.h" | |
| 20 #include "net/base/auth.h" | |
| 21 #include "net/base/load_timing_info.h" | |
| 22 #include "net/http/http_network_session.h" | |
| 23 #include "net/http/http_request_headers.h" | |
| 24 #include "net/http/http_response_headers.h" | |
| 25 #include "net/socket/client_socket_pool_histograms.h" | |
| 26 #include "net/socket/socket.h" | |
| 27 #include "net/socket/websocket_endpoint_lock_manager.h" | |
| 28 #include "net/ssl/ssl_cert_request_info.h" | |
| 29 #include "net/ssl/ssl_connection_status_flags.h" | |
| 30 #include "net/ssl/ssl_info.h" | |
| 31 #include "testing/gtest/include/gtest/gtest.h" | |
| 32 | |
| 33 // Socket events are easier to debug if you log individual reads and writes. | |
| 34 // Enable these if locally debugging, but they are too noisy for the waterfall. | |
| 35 #if 0 | |
| 36 #define NET_TRACE(level, s) DLOG(level) << s << __FUNCTION__ << "() " | |
| 37 #else | |
| 38 #define NET_TRACE(level, s) EAT_STREAM_PARAMETERS | |
| 39 #endif | |
| 40 | |
| 41 namespace net { | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 inline char AsciifyHigh(char x) { | |
| 46 char nybble = static_cast<char>((x >> 4) & 0x0F); | |
| 47 return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10); | |
| 48 } | |
| 49 | |
| 50 inline char AsciifyLow(char x) { | |
| 51 char nybble = static_cast<char>((x >> 0) & 0x0F); | |
| 52 return nybble + ((nybble < 0x0A) ? '0' : 'A' - 10); | |
| 53 } | |
| 54 | |
| 55 inline char Asciify(char x) { | |
| 56 if ((x < 0) || !isprint(x)) | |
| 57 return '.'; | |
| 58 return x; | |
| 59 } | |
| 60 | |
| 61 void DumpData(const char* data, int data_len) { | |
| 62 if (logging::LOG_INFO < logging::GetMinLogLevel()) | |
| 63 return; | |
| 64 DVLOG(1) << "Length: " << data_len; | |
| 65 const char* pfx = "Data: "; | |
| 66 if (!data || (data_len <= 0)) { | |
| 67 DVLOG(1) << pfx << "<None>"; | |
| 68 } else { | |
| 69 int i; | |
| 70 for (i = 0; i <= (data_len - 4); i += 4) { | |
| 71 DVLOG(1) << pfx | |
| 72 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
| 73 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
| 74 << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2]) | |
| 75 << AsciifyHigh(data[i + 3]) << AsciifyLow(data[i + 3]) | |
| 76 << " '" | |
| 77 << Asciify(data[i + 0]) | |
| 78 << Asciify(data[i + 1]) | |
| 79 << Asciify(data[i + 2]) | |
| 80 << Asciify(data[i + 3]) | |
| 81 << "'"; | |
| 82 pfx = " "; | |
| 83 } | |
| 84 // Take care of any 'trailing' bytes, if data_len was not a multiple of 4. | |
| 85 switch (data_len - i) { | |
| 86 case 3: | |
| 87 DVLOG(1) << pfx | |
| 88 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
| 89 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
| 90 << AsciifyHigh(data[i + 2]) << AsciifyLow(data[i + 2]) | |
| 91 << " '" | |
| 92 << Asciify(data[i + 0]) | |
| 93 << Asciify(data[i + 1]) | |
| 94 << Asciify(data[i + 2]) | |
| 95 << " '"; | |
| 96 break; | |
| 97 case 2: | |
| 98 DVLOG(1) << pfx | |
| 99 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
| 100 << AsciifyHigh(data[i + 1]) << AsciifyLow(data[i + 1]) | |
| 101 << " '" | |
| 102 << Asciify(data[i + 0]) | |
| 103 << Asciify(data[i + 1]) | |
| 104 << " '"; | |
| 105 break; | |
| 106 case 1: | |
| 107 DVLOG(1) << pfx | |
| 108 << AsciifyHigh(data[i + 0]) << AsciifyLow(data[i + 0]) | |
| 109 << " '" | |
| 110 << Asciify(data[i + 0]) | |
| 111 << " '"; | |
| 112 break; | |
| 113 } | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 template <MockReadWriteType type> | |
| 118 void DumpMockReadWrite(const MockReadWrite<type>& r) { | |
| 119 if (logging::LOG_INFO < logging::GetMinLogLevel()) | |
| 120 return; | |
| 121 DVLOG(1) << "Async: " << (r.mode == ASYNC) | |
| 122 << "\nResult: " << r.result; | |
| 123 DumpData(r.data, r.data_len); | |
| 124 const char* stop = (r.sequence_number & MockRead::STOPLOOP) ? " (STOP)" : ""; | |
| 125 DVLOG(1) << "Stage: " << (r.sequence_number & ~MockRead::STOPLOOP) << stop | |
| 126 << "\nTime: " << r.time_stamp.ToInternalValue(); | |
| 127 } | |
| 128 | |
| 129 } // namespace | |
| 130 | |
| 131 MockConnect::MockConnect() : mode(ASYNC), result(OK) { | |
| 132 IPAddressNumber ip; | |
| 133 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
| 134 peer_addr = IPEndPoint(ip, 0); | |
| 135 } | |
| 136 | |
| 137 MockConnect::MockConnect(IoMode io_mode, int r) : mode(io_mode), result(r) { | |
| 138 IPAddressNumber ip; | |
| 139 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
| 140 peer_addr = IPEndPoint(ip, 0); | |
| 141 } | |
| 142 | |
| 143 MockConnect::MockConnect(IoMode io_mode, int r, IPEndPoint addr) : | |
| 144 mode(io_mode), | |
| 145 result(r), | |
| 146 peer_addr(addr) { | |
| 147 } | |
| 148 | |
| 149 MockConnect::~MockConnect() {} | |
| 150 | |
| 151 StaticSocketDataProvider::StaticSocketDataProvider() | |
| 152 : reads_(NULL), | |
| 153 read_index_(0), | |
| 154 read_count_(0), | |
| 155 writes_(NULL), | |
| 156 write_index_(0), | |
| 157 write_count_(0) { | |
| 158 } | |
| 159 | |
| 160 StaticSocketDataProvider::StaticSocketDataProvider(MockRead* reads, | |
| 161 size_t reads_count, | |
| 162 MockWrite* writes, | |
| 163 size_t writes_count) | |
| 164 : reads_(reads), | |
| 165 read_index_(0), | |
| 166 read_count_(reads_count), | |
| 167 writes_(writes), | |
| 168 write_index_(0), | |
| 169 write_count_(writes_count) { | |
| 170 } | |
| 171 | |
| 172 StaticSocketDataProvider::~StaticSocketDataProvider() {} | |
| 173 | |
| 174 const MockRead& StaticSocketDataProvider::PeekRead() const { | |
| 175 CHECK(!at_read_eof()); | |
| 176 return reads_[read_index_]; | |
| 177 } | |
| 178 | |
| 179 const MockWrite& StaticSocketDataProvider::PeekWrite() const { | |
| 180 CHECK(!at_write_eof()); | |
| 181 return writes_[write_index_]; | |
| 182 } | |
| 183 | |
| 184 const MockRead& StaticSocketDataProvider::PeekRead(size_t index) const { | |
| 185 CHECK_LT(index, read_count_); | |
| 186 return reads_[index]; | |
| 187 } | |
| 188 | |
| 189 const MockWrite& StaticSocketDataProvider::PeekWrite(size_t index) const { | |
| 190 CHECK_LT(index, write_count_); | |
| 191 return writes_[index]; | |
| 192 } | |
| 193 | |
| 194 MockRead StaticSocketDataProvider::GetNextRead() { | |
| 195 CHECK(!at_read_eof()); | |
| 196 reads_[read_index_].time_stamp = base::Time::Now(); | |
| 197 return reads_[read_index_++]; | |
| 198 } | |
| 199 | |
| 200 MockWriteResult StaticSocketDataProvider::OnWrite(const std::string& data) { | |
| 201 if (!writes_) { | |
| 202 // Not using mock writes; succeed synchronously. | |
| 203 return MockWriteResult(SYNCHRONOUS, data.length()); | |
| 204 } | |
| 205 EXPECT_FALSE(at_write_eof()); | |
| 206 if (at_write_eof()) { | |
| 207 // Show what the extra write actually consists of. | |
| 208 EXPECT_EQ("<unexpected write>", data); | |
| 209 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 210 } | |
| 211 | |
| 212 // Check that what we are writing matches the expectation. | |
| 213 // Then give the mocked return value. | |
| 214 MockWrite* w = &writes_[write_index_++]; | |
| 215 w->time_stamp = base::Time::Now(); | |
| 216 int result = w->result; | |
| 217 if (w->data) { | |
| 218 // Note - we can simulate a partial write here. If the expected data | |
| 219 // is a match, but shorter than the write actually written, that is legal. | |
| 220 // Example: | |
| 221 // Application writes "foobarbaz" (9 bytes) | |
| 222 // Expected write was "foo" (3 bytes) | |
| 223 // This is a success, and we return 3 to the application. | |
| 224 std::string expected_data(w->data, w->data_len); | |
| 225 EXPECT_GE(data.length(), expected_data.length()); | |
| 226 std::string actual_data(data.substr(0, w->data_len)); | |
| 227 EXPECT_EQ(expected_data, actual_data); | |
| 228 if (expected_data != actual_data) | |
| 229 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 230 if (result == OK) | |
| 231 result = w->data_len; | |
| 232 } | |
| 233 return MockWriteResult(w->mode, result); | |
| 234 } | |
| 235 | |
| 236 void StaticSocketDataProvider::Reset() { | |
| 237 read_index_ = 0; | |
| 238 write_index_ = 0; | |
| 239 } | |
| 240 | |
| 241 DynamicSocketDataProvider::DynamicSocketDataProvider() | |
| 242 : short_read_limit_(0), | |
| 243 allow_unconsumed_reads_(false) { | |
| 244 } | |
| 245 | |
| 246 DynamicSocketDataProvider::~DynamicSocketDataProvider() {} | |
| 247 | |
| 248 MockRead DynamicSocketDataProvider::GetNextRead() { | |
| 249 if (reads_.empty()) | |
| 250 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 251 MockRead result = reads_.front(); | |
| 252 if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) { | |
| 253 reads_.pop_front(); | |
| 254 } else { | |
| 255 result.data_len = short_read_limit_; | |
| 256 reads_.front().data += result.data_len; | |
| 257 reads_.front().data_len -= result.data_len; | |
| 258 } | |
| 259 return result; | |
| 260 } | |
| 261 | |
| 262 void DynamicSocketDataProvider::Reset() { | |
| 263 reads_.clear(); | |
| 264 } | |
| 265 | |
| 266 void DynamicSocketDataProvider::SimulateRead(const char* data, | |
| 267 const size_t length) { | |
| 268 if (!allow_unconsumed_reads_) { | |
| 269 EXPECT_TRUE(reads_.empty()) << "Unconsumed read: " << reads_.front().data; | |
| 270 } | |
| 271 reads_.push_back(MockRead(ASYNC, data, length)); | |
| 272 } | |
| 273 | |
| 274 SSLSocketDataProvider::SSLSocketDataProvider(IoMode mode, int result) | |
| 275 : connect(mode, result), | |
| 276 next_proto_status(SSLClientSocket::kNextProtoUnsupported), | |
| 277 was_npn_negotiated(false), | |
| 278 protocol_negotiated(kProtoUnknown), | |
| 279 client_cert_sent(false), | |
| 280 cert_request_info(NULL), | |
| 281 channel_id_sent(false), | |
| 282 connection_status(0), | |
| 283 should_pause_on_connect(false), | |
| 284 is_in_session_cache(false) { | |
| 285 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, | |
| 286 &connection_status); | |
| 287 // Set to TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 | |
| 288 SSLConnectionStatusSetCipherSuite(0xcc14, &connection_status); | |
| 289 } | |
| 290 | |
| 291 SSLSocketDataProvider::~SSLSocketDataProvider() { | |
| 292 } | |
| 293 | |
| 294 void SSLSocketDataProvider::SetNextProto(NextProto proto) { | |
| 295 was_npn_negotiated = true; | |
| 296 next_proto_status = SSLClientSocket::kNextProtoNegotiated; | |
| 297 protocol_negotiated = proto; | |
| 298 next_proto = SSLClientSocket::NextProtoToString(proto); | |
| 299 } | |
| 300 | |
| 301 DelayedSocketData::DelayedSocketData( | |
| 302 int write_delay, MockRead* reads, size_t reads_count, | |
| 303 MockWrite* writes, size_t writes_count) | |
| 304 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
| 305 write_delay_(write_delay), | |
| 306 read_in_progress_(false), | |
| 307 weak_factory_(this) { | |
| 308 DCHECK_GE(write_delay_, 0); | |
| 309 } | |
| 310 | |
| 311 DelayedSocketData::DelayedSocketData( | |
| 312 const MockConnect& connect, int write_delay, MockRead* reads, | |
| 313 size_t reads_count, MockWrite* writes, size_t writes_count) | |
| 314 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
| 315 write_delay_(write_delay), | |
| 316 read_in_progress_(false), | |
| 317 weak_factory_(this) { | |
| 318 DCHECK_GE(write_delay_, 0); | |
| 319 set_connect_data(connect); | |
| 320 } | |
| 321 | |
| 322 DelayedSocketData::~DelayedSocketData() { | |
| 323 } | |
| 324 | |
| 325 void DelayedSocketData::ForceNextRead() { | |
| 326 DCHECK(read_in_progress_); | |
| 327 write_delay_ = 0; | |
| 328 CompleteRead(); | |
| 329 } | |
| 330 | |
| 331 MockRead DelayedSocketData::GetNextRead() { | |
| 332 MockRead out = MockRead(ASYNC, ERR_IO_PENDING); | |
| 333 if (write_delay_ <= 0) | |
| 334 out = StaticSocketDataProvider::GetNextRead(); | |
| 335 read_in_progress_ = (out.result == ERR_IO_PENDING); | |
| 336 return out; | |
| 337 } | |
| 338 | |
| 339 MockWriteResult DelayedSocketData::OnWrite(const std::string& data) { | |
| 340 MockWriteResult rv = StaticSocketDataProvider::OnWrite(data); | |
| 341 // Now that our write has completed, we can allow reads to continue. | |
| 342 if (!--write_delay_ && read_in_progress_) | |
| 343 base::MessageLoop::current()->PostDelayedTask( | |
| 344 FROM_HERE, | |
| 345 base::Bind(&DelayedSocketData::CompleteRead, | |
| 346 weak_factory_.GetWeakPtr()), | |
| 347 base::TimeDelta::FromMilliseconds(100)); | |
| 348 return rv; | |
| 349 } | |
| 350 | |
| 351 void DelayedSocketData::Reset() { | |
| 352 set_socket(NULL); | |
| 353 read_in_progress_ = false; | |
| 354 weak_factory_.InvalidateWeakPtrs(); | |
| 355 StaticSocketDataProvider::Reset(); | |
| 356 } | |
| 357 | |
| 358 void DelayedSocketData::CompleteRead() { | |
| 359 if (socket() && read_in_progress_) | |
| 360 socket()->OnReadComplete(GetNextRead()); | |
| 361 } | |
| 362 | |
| 363 OrderedSocketData::OrderedSocketData( | |
| 364 MockRead* reads, size_t reads_count, MockWrite* writes, size_t writes_count) | |
| 365 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
| 366 sequence_number_(0), loop_stop_stage_(0), | |
| 367 blocked_(false), weak_factory_(this) { | |
| 368 } | |
| 369 | |
| 370 OrderedSocketData::OrderedSocketData( | |
| 371 const MockConnect& connect, | |
| 372 MockRead* reads, size_t reads_count, | |
| 373 MockWrite* writes, size_t writes_count) | |
| 374 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
| 375 sequence_number_(0), loop_stop_stage_(0), | |
| 376 blocked_(false), weak_factory_(this) { | |
| 377 set_connect_data(connect); | |
| 378 } | |
| 379 | |
| 380 void OrderedSocketData::EndLoop() { | |
| 381 // If we've already stopped the loop, don't do it again until we've advanced | |
| 382 // to the next sequence_number. | |
| 383 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ << ": EndLoop()"; | |
| 384 if (loop_stop_stage_ > 0) { | |
| 385 const MockRead& next_read = StaticSocketDataProvider::PeekRead(); | |
| 386 if ((next_read.sequence_number & ~MockRead::STOPLOOP) > | |
| 387 loop_stop_stage_) { | |
| 388 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 389 << ": Clearing stop index"; | |
| 390 loop_stop_stage_ = 0; | |
| 391 } else { | |
| 392 return; | |
| 393 } | |
| 394 } | |
| 395 // Record the sequence_number at which we stopped the loop. | |
| 396 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 397 << ": Posting Quit at read " << read_index(); | |
| 398 loop_stop_stage_ = sequence_number_; | |
| 399 } | |
| 400 | |
| 401 MockRead OrderedSocketData::GetNextRead() { | |
| 402 weak_factory_.InvalidateWeakPtrs(); | |
| 403 blocked_ = false; | |
| 404 const MockRead& next_read = StaticSocketDataProvider::PeekRead(); | |
| 405 if (next_read.sequence_number & MockRead::STOPLOOP) | |
| 406 EndLoop(); | |
| 407 if ((next_read.sequence_number & ~MockRead::STOPLOOP) <= | |
| 408 sequence_number_++) { | |
| 409 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1 | |
| 410 << ": Read " << read_index(); | |
| 411 DumpMockReadWrite(next_read); | |
| 412 blocked_ = (next_read.result == ERR_IO_PENDING); | |
| 413 return StaticSocketDataProvider::GetNextRead(); | |
| 414 } | |
| 415 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ - 1 | |
| 416 << ": I/O Pending"; | |
| 417 MockRead result = MockRead(ASYNC, ERR_IO_PENDING); | |
| 418 DumpMockReadWrite(result); | |
| 419 blocked_ = true; | |
| 420 return result; | |
| 421 } | |
| 422 | |
| 423 MockWriteResult OrderedSocketData::OnWrite(const std::string& data) { | |
| 424 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 425 << ": Write " << write_index(); | |
| 426 DumpMockReadWrite(PeekWrite()); | |
| 427 ++sequence_number_; | |
| 428 if (blocked_) { | |
| 429 // TODO(willchan): This 100ms delay seems to work around some weirdness. We | |
| 430 // should probably fix the weirdness. One example is in SpdyStream, | |
| 431 // DoSendRequest() will return ERR_IO_PENDING, and there's a race. If the | |
| 432 // SYN_REPLY causes OnResponseReceived() to get called before | |
| 433 // SpdyStream::ReadResponseHeaders() is called, we hit a NOTREACHED(). | |
| 434 base::MessageLoop::current()->PostDelayedTask( | |
| 435 FROM_HERE, | |
| 436 base::Bind(&OrderedSocketData::CompleteRead, | |
| 437 weak_factory_.GetWeakPtr()), | |
| 438 base::TimeDelta::FromMilliseconds(100)); | |
| 439 } | |
| 440 return StaticSocketDataProvider::OnWrite(data); | |
| 441 } | |
| 442 | |
| 443 void OrderedSocketData::Reset() { | |
| 444 NET_TRACE(INFO, " *** ") << "Stage " | |
| 445 << sequence_number_ << ": Reset()"; | |
| 446 sequence_number_ = 0; | |
| 447 loop_stop_stage_ = 0; | |
| 448 set_socket(NULL); | |
| 449 weak_factory_.InvalidateWeakPtrs(); | |
| 450 StaticSocketDataProvider::Reset(); | |
| 451 } | |
| 452 | |
| 453 void OrderedSocketData::CompleteRead() { | |
| 454 if (socket() && blocked_) { | |
| 455 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_; | |
| 456 socket()->OnReadComplete(GetNextRead()); | |
| 457 } | |
| 458 } | |
| 459 | |
| 460 OrderedSocketData::~OrderedSocketData() {} | |
| 461 | |
| 462 DeterministicSocketData::DeterministicSocketData(MockRead* reads, | |
| 463 size_t reads_count, MockWrite* writes, size_t writes_count) | |
| 464 : StaticSocketDataProvider(reads, reads_count, writes, writes_count), | |
| 465 sequence_number_(0), | |
| 466 current_read_(), | |
| 467 current_write_(), | |
| 468 stopping_sequence_number_(0), | |
| 469 stopped_(false), | |
| 470 print_debug_(false), | |
| 471 is_running_(false) { | |
| 472 VerifyCorrectSequenceNumbers(reads, reads_count, writes, writes_count); | |
| 473 } | |
| 474 | |
| 475 DeterministicSocketData::~DeterministicSocketData() {} | |
| 476 | |
| 477 void DeterministicSocketData::Run() { | |
| 478 DCHECK(!is_running_); | |
| 479 is_running_ = true; | |
| 480 | |
| 481 SetStopped(false); | |
| 482 int counter = 0; | |
| 483 // Continue to consume data until all data has run out, or the stopped_ flag | |
| 484 // has been set. Consuming data requires two separate operations -- running | |
| 485 // the tasks in the message loop, and explicitly invoking the read/write | |
| 486 // callbacks (simulating network I/O). We check our conditions between each, | |
| 487 // since they can change in either. | |
| 488 while ((!at_write_eof() || !at_read_eof()) && !stopped()) { | |
| 489 if (counter % 2 == 0) | |
| 490 base::RunLoop().RunUntilIdle(); | |
| 491 if (counter % 2 == 1) { | |
| 492 InvokeCallbacks(); | |
| 493 } | |
| 494 counter++; | |
| 495 } | |
| 496 // We're done consuming new data, but it is possible there are still some | |
| 497 // pending callbacks which we expect to complete before returning. | |
| 498 while (delegate_.get() && | |
| 499 (delegate_->WritePending() || delegate_->ReadPending()) && | |
| 500 !stopped()) { | |
| 501 InvokeCallbacks(); | |
| 502 base::RunLoop().RunUntilIdle(); | |
| 503 } | |
| 504 SetStopped(false); | |
| 505 is_running_ = false; | |
| 506 } | |
| 507 | |
| 508 void DeterministicSocketData::RunFor(int steps) { | |
| 509 StopAfter(steps); | |
| 510 Run(); | |
| 511 } | |
| 512 | |
| 513 void DeterministicSocketData::SetStop(int seq) { | |
| 514 DCHECK_LT(sequence_number_, seq); | |
| 515 stopping_sequence_number_ = seq; | |
| 516 stopped_ = false; | |
| 517 } | |
| 518 | |
| 519 void DeterministicSocketData::StopAfter(int seq) { | |
| 520 SetStop(sequence_number_ + seq); | |
| 521 } | |
| 522 | |
| 523 MockRead DeterministicSocketData::GetNextRead() { | |
| 524 current_read_ = StaticSocketDataProvider::PeekRead(); | |
| 525 | |
| 526 // Synchronous read while stopped is an error | |
| 527 if (stopped() && current_read_.mode == SYNCHRONOUS) { | |
| 528 LOG(ERROR) << "Unable to perform synchronous IO while stopped"; | |
| 529 return MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 530 } | |
| 531 | |
| 532 // Async read which will be called back in a future step. | |
| 533 if (sequence_number_ < current_read_.sequence_number) { | |
| 534 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 535 << ": I/O Pending"; | |
| 536 MockRead result = MockRead(SYNCHRONOUS, ERR_IO_PENDING); | |
| 537 if (current_read_.mode == SYNCHRONOUS) { | |
| 538 LOG(ERROR) << "Unable to perform synchronous read: " | |
| 539 << current_read_.sequence_number | |
| 540 << " at stage: " << sequence_number_; | |
| 541 result = MockRead(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 542 } | |
| 543 if (print_debug_) | |
| 544 DumpMockReadWrite(result); | |
| 545 return result; | |
| 546 } | |
| 547 | |
| 548 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 549 << ": Read " << read_index(); | |
| 550 if (print_debug_) | |
| 551 DumpMockReadWrite(current_read_); | |
| 552 | |
| 553 // Increment the sequence number if IO is complete | |
| 554 if (current_read_.mode == SYNCHRONOUS) | |
| 555 NextStep(); | |
| 556 | |
| 557 DCHECK_NE(ERR_IO_PENDING, current_read_.result); | |
| 558 StaticSocketDataProvider::GetNextRead(); | |
| 559 | |
| 560 return current_read_; | |
| 561 } | |
| 562 | |
| 563 MockWriteResult DeterministicSocketData::OnWrite(const std::string& data) { | |
| 564 const MockWrite& next_write = StaticSocketDataProvider::PeekWrite(); | |
| 565 current_write_ = next_write; | |
| 566 | |
| 567 // Synchronous write while stopped is an error | |
| 568 if (stopped() && next_write.mode == SYNCHRONOUS) { | |
| 569 LOG(ERROR) << "Unable to perform synchronous IO while stopped"; | |
| 570 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 571 } | |
| 572 | |
| 573 // Async write which will be called back in a future step. | |
| 574 if (sequence_number_ < next_write.sequence_number) { | |
| 575 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 576 << ": I/O Pending"; | |
| 577 if (next_write.mode == SYNCHRONOUS) { | |
| 578 LOG(ERROR) << "Unable to perform synchronous write: " | |
| 579 << next_write.sequence_number << " at stage: " << sequence_number_; | |
| 580 return MockWriteResult(SYNCHRONOUS, ERR_UNEXPECTED); | |
| 581 } | |
| 582 } else { | |
| 583 NET_TRACE(INFO, " *** ") << "Stage " << sequence_number_ | |
| 584 << ": Write " << write_index(); | |
| 585 } | |
| 586 | |
| 587 if (print_debug_) | |
| 588 DumpMockReadWrite(next_write); | |
| 589 | |
| 590 // Move to the next step if I/O is synchronous, since the operation will | |
| 591 // complete when this method returns. | |
| 592 if (next_write.mode == SYNCHRONOUS) | |
| 593 NextStep(); | |
| 594 | |
| 595 // This is either a sync write for this step, or an async write. | |
| 596 return StaticSocketDataProvider::OnWrite(data); | |
| 597 } | |
| 598 | |
| 599 void DeterministicSocketData::Reset() { | |
| 600 NET_TRACE(INFO, " *** ") << "Stage " | |
| 601 << sequence_number_ << ": Reset()"; | |
| 602 sequence_number_ = 0; | |
| 603 StaticSocketDataProvider::Reset(); | |
| 604 NOTREACHED(); | |
| 605 } | |
| 606 | |
| 607 void DeterministicSocketData::InvokeCallbacks() { | |
| 608 if (delegate_.get() && delegate_->WritePending() && | |
| 609 (current_write().sequence_number == sequence_number())) { | |
| 610 NextStep(); | |
| 611 delegate_->CompleteWrite(); | |
| 612 return; | |
| 613 } | |
| 614 if (delegate_.get() && delegate_->ReadPending() && | |
| 615 (current_read().sequence_number == sequence_number())) { | |
| 616 NextStep(); | |
| 617 delegate_->CompleteRead(); | |
| 618 return; | |
| 619 } | |
| 620 } | |
| 621 | |
| 622 void DeterministicSocketData::NextStep() { | |
| 623 // Invariant: Can never move *past* the stopping step. | |
| 624 DCHECK_LT(sequence_number_, stopping_sequence_number_); | |
| 625 sequence_number_++; | |
| 626 if (sequence_number_ == stopping_sequence_number_) | |
| 627 SetStopped(true); | |
| 628 } | |
| 629 | |
| 630 void DeterministicSocketData::VerifyCorrectSequenceNumbers( | |
| 631 MockRead* reads, size_t reads_count, | |
| 632 MockWrite* writes, size_t writes_count) { | |
| 633 size_t read = 0; | |
| 634 size_t write = 0; | |
| 635 int expected = 0; | |
| 636 while (read < reads_count || write < writes_count) { | |
| 637 // Check to see that we have a read or write at the expected | |
| 638 // state. | |
| 639 if (read < reads_count && reads[read].sequence_number == expected) { | |
| 640 ++read; | |
| 641 ++expected; | |
| 642 continue; | |
| 643 } | |
| 644 if (write < writes_count && writes[write].sequence_number == expected) { | |
| 645 ++write; | |
| 646 ++expected; | |
| 647 continue; | |
| 648 } | |
| 649 NOTREACHED() << "Missing sequence number: " << expected; | |
| 650 return; | |
| 651 } | |
| 652 DCHECK_EQ(read, reads_count); | |
| 653 DCHECK_EQ(write, writes_count); | |
| 654 } | |
| 655 | |
| 656 MockClientSocketFactory::MockClientSocketFactory() {} | |
| 657 | |
| 658 MockClientSocketFactory::~MockClientSocketFactory() {} | |
| 659 | |
| 660 void MockClientSocketFactory::AddSocketDataProvider( | |
| 661 SocketDataProvider* data) { | |
| 662 mock_data_.Add(data); | |
| 663 } | |
| 664 | |
| 665 void MockClientSocketFactory::AddSSLSocketDataProvider( | |
| 666 SSLSocketDataProvider* data) { | |
| 667 mock_ssl_data_.Add(data); | |
| 668 } | |
| 669 | |
| 670 void MockClientSocketFactory::ResetNextMockIndexes() { | |
| 671 mock_data_.ResetNextIndex(); | |
| 672 mock_ssl_data_.ResetNextIndex(); | |
| 673 } | |
| 674 | |
| 675 scoped_ptr<DatagramClientSocket> | |
| 676 MockClientSocketFactory::CreateDatagramClientSocket( | |
| 677 DatagramSocket::BindType bind_type, | |
| 678 const RandIntCallback& rand_int_cb, | |
| 679 net::NetLog* net_log, | |
| 680 const net::NetLog::Source& source) { | |
| 681 SocketDataProvider* data_provider = mock_data_.GetNext(); | |
| 682 scoped_ptr<MockUDPClientSocket> socket( | |
| 683 new MockUDPClientSocket(data_provider, net_log)); | |
| 684 data_provider->set_socket(socket.get()); | |
| 685 if (bind_type == DatagramSocket::RANDOM_BIND) | |
| 686 socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535))); | |
| 687 return socket.Pass(); | |
| 688 } | |
| 689 | |
| 690 scoped_ptr<StreamSocket> MockClientSocketFactory::CreateTransportClientSocket( | |
| 691 const AddressList& addresses, | |
| 692 net::NetLog* net_log, | |
| 693 const net::NetLog::Source& source) { | |
| 694 SocketDataProvider* data_provider = mock_data_.GetNext(); | |
| 695 scoped_ptr<MockTCPClientSocket> socket( | |
| 696 new MockTCPClientSocket(addresses, net_log, data_provider)); | |
| 697 data_provider->set_socket(socket.get()); | |
| 698 return socket.Pass(); | |
| 699 } | |
| 700 | |
| 701 scoped_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket( | |
| 702 scoped_ptr<ClientSocketHandle> transport_socket, | |
| 703 const HostPortPair& host_and_port, | |
| 704 const SSLConfig& ssl_config, | |
| 705 const SSLClientSocketContext& context) { | |
| 706 SSLSocketDataProvider* next_ssl_data = mock_ssl_data_.GetNext(); | |
| 707 if (!next_ssl_data->next_protos_expected_in_ssl_config.empty()) { | |
| 708 EXPECT_EQ(next_ssl_data->next_protos_expected_in_ssl_config.size(), | |
| 709 ssl_config.next_protos.size()); | |
| 710 EXPECT_TRUE( | |
| 711 std::equal(next_ssl_data->next_protos_expected_in_ssl_config.begin(), | |
| 712 next_ssl_data->next_protos_expected_in_ssl_config.end(), | |
| 713 ssl_config.next_protos.begin())); | |
| 714 } | |
| 715 scoped_ptr<MockSSLClientSocket> socket(new MockSSLClientSocket( | |
| 716 transport_socket.Pass(), host_and_port, ssl_config, next_ssl_data)); | |
| 717 ssl_client_sockets_.push_back(socket.get()); | |
| 718 return socket.Pass(); | |
| 719 } | |
| 720 | |
| 721 void MockClientSocketFactory::ClearSSLSessionCache() { | |
| 722 } | |
| 723 | |
| 724 const char MockClientSocket::kTlsUnique[] = "MOCK_TLSUNIQ"; | |
| 725 | |
| 726 MockClientSocket::MockClientSocket(const BoundNetLog& net_log) | |
| 727 : connected_(false), | |
| 728 net_log_(net_log), | |
| 729 weak_factory_(this) { | |
| 730 IPAddressNumber ip; | |
| 731 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | |
| 732 peer_addr_ = IPEndPoint(ip, 0); | |
| 733 } | |
| 734 | |
| 735 int MockClientSocket::SetReceiveBufferSize(int32 size) { | |
| 736 return OK; | |
| 737 } | |
| 738 | |
| 739 int MockClientSocket::SetSendBufferSize(int32 size) { | |
| 740 return OK; | |
| 741 } | |
| 742 | |
| 743 void MockClientSocket::Disconnect() { | |
| 744 connected_ = false; | |
| 745 } | |
| 746 | |
| 747 bool MockClientSocket::IsConnected() const { | |
| 748 return connected_; | |
| 749 } | |
| 750 | |
| 751 bool MockClientSocket::IsConnectedAndIdle() const { | |
| 752 return connected_; | |
| 753 } | |
| 754 | |
| 755 int MockClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
| 756 if (!IsConnected()) | |
| 757 return ERR_SOCKET_NOT_CONNECTED; | |
| 758 *address = peer_addr_; | |
| 759 return OK; | |
| 760 } | |
| 761 | |
| 762 int MockClientSocket::GetLocalAddress(IPEndPoint* address) const { | |
| 763 IPAddressNumber ip; | |
| 764 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
| 765 CHECK(rv); | |
| 766 *address = IPEndPoint(ip, 123); | |
| 767 return OK; | |
| 768 } | |
| 769 | |
| 770 const BoundNetLog& MockClientSocket::NetLog() const { | |
| 771 return net_log_; | |
| 772 } | |
| 773 | |
| 774 std::string MockClientSocket::GetSessionCacheKey() const { | |
| 775 NOTIMPLEMENTED(); | |
| 776 return std::string(); | |
| 777 } | |
| 778 | |
| 779 bool MockClientSocket::InSessionCache() const { | |
| 780 NOTIMPLEMENTED(); | |
| 781 return false; | |
| 782 } | |
| 783 | |
| 784 void MockClientSocket::SetHandshakeCompletionCallback(const base::Closure& cb) { | |
| 785 NOTIMPLEMENTED(); | |
| 786 } | |
| 787 | |
| 788 void MockClientSocket::GetSSLCertRequestInfo( | |
| 789 SSLCertRequestInfo* cert_request_info) { | |
| 790 } | |
| 791 | |
| 792 int MockClientSocket::ExportKeyingMaterial(const base::StringPiece& label, | |
| 793 bool has_context, | |
| 794 const base::StringPiece& context, | |
| 795 unsigned char* out, | |
| 796 unsigned int outlen) { | |
| 797 memset(out, 'A', outlen); | |
| 798 return OK; | |
| 799 } | |
| 800 | |
| 801 int MockClientSocket::GetTLSUniqueChannelBinding(std::string* out) { | |
| 802 out->assign(MockClientSocket::kTlsUnique); | |
| 803 return OK; | |
| 804 } | |
| 805 | |
| 806 ChannelIDService* MockClientSocket::GetChannelIDService() const { | |
| 807 NOTREACHED(); | |
| 808 return NULL; | |
| 809 } | |
| 810 | |
| 811 SSLClientSocket::NextProtoStatus | |
| 812 MockClientSocket::GetNextProto(std::string* proto) { | |
| 813 proto->clear(); | |
| 814 return SSLClientSocket::kNextProtoUnsupported; | |
| 815 } | |
| 816 | |
| 817 scoped_refptr<X509Certificate> | |
| 818 MockClientSocket::GetUnverifiedServerCertificateChain() const { | |
| 819 NOTREACHED(); | |
| 820 return NULL; | |
| 821 } | |
| 822 | |
| 823 MockClientSocket::~MockClientSocket() {} | |
| 824 | |
| 825 void MockClientSocket::RunCallbackAsync(const CompletionCallback& callback, | |
| 826 int result) { | |
| 827 base::MessageLoop::current()->PostTask( | |
| 828 FROM_HERE, | |
| 829 base::Bind(&MockClientSocket::RunCallback, | |
| 830 weak_factory_.GetWeakPtr(), | |
| 831 callback, | |
| 832 result)); | |
| 833 } | |
| 834 | |
| 835 void MockClientSocket::RunCallback(const net::CompletionCallback& callback, | |
| 836 int result) { | |
| 837 if (!callback.is_null()) | |
| 838 callback.Run(result); | |
| 839 } | |
| 840 | |
| 841 MockTCPClientSocket::MockTCPClientSocket(const AddressList& addresses, | |
| 842 net::NetLog* net_log, | |
| 843 SocketDataProvider* data) | |
| 844 : MockClientSocket(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
| 845 addresses_(addresses), | |
| 846 data_(data), | |
| 847 read_offset_(0), | |
| 848 read_data_(SYNCHRONOUS, ERR_UNEXPECTED), | |
| 849 need_read_data_(true), | |
| 850 peer_closed_connection_(false), | |
| 851 pending_buf_(NULL), | |
| 852 pending_buf_len_(0), | |
| 853 was_used_to_convey_data_(false) { | |
| 854 DCHECK(data_); | |
| 855 peer_addr_ = data->connect_data().peer_addr; | |
| 856 data_->Reset(); | |
| 857 } | |
| 858 | |
| 859 MockTCPClientSocket::~MockTCPClientSocket() {} | |
| 860 | |
| 861 int MockTCPClientSocket::Read(IOBuffer* buf, int buf_len, | |
| 862 const CompletionCallback& callback) { | |
| 863 if (!connected_) | |
| 864 return ERR_UNEXPECTED; | |
| 865 | |
| 866 // If the buffer is already in use, a read is already in progress! | |
| 867 DCHECK(pending_buf_.get() == NULL); | |
| 868 | |
| 869 // Store our async IO data. | |
| 870 pending_buf_ = buf; | |
| 871 pending_buf_len_ = buf_len; | |
| 872 pending_callback_ = callback; | |
| 873 | |
| 874 if (need_read_data_) { | |
| 875 read_data_ = data_->GetNextRead(); | |
| 876 if (read_data_.result == ERR_CONNECTION_CLOSED) { | |
| 877 // This MockRead is just a marker to instruct us to set | |
| 878 // peer_closed_connection_. | |
| 879 peer_closed_connection_ = true; | |
| 880 } | |
| 881 if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { | |
| 882 // This MockRead is just a marker to instruct us to set | |
| 883 // peer_closed_connection_. Skip it and get the next one. | |
| 884 read_data_ = data_->GetNextRead(); | |
| 885 peer_closed_connection_ = true; | |
| 886 } | |
| 887 // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility | |
| 888 // to complete the async IO manually later (via OnReadComplete). | |
| 889 if (read_data_.result == ERR_IO_PENDING) { | |
| 890 // We need to be using async IO in this case. | |
| 891 DCHECK(!callback.is_null()); | |
| 892 return ERR_IO_PENDING; | |
| 893 } | |
| 894 need_read_data_ = false; | |
| 895 } | |
| 896 | |
| 897 return CompleteRead(); | |
| 898 } | |
| 899 | |
| 900 int MockTCPClientSocket::Write(IOBuffer* buf, int buf_len, | |
| 901 const CompletionCallback& callback) { | |
| 902 DCHECK(buf); | |
| 903 DCHECK_GT(buf_len, 0); | |
| 904 | |
| 905 if (!connected_) | |
| 906 return ERR_UNEXPECTED; | |
| 907 | |
| 908 std::string data(buf->data(), buf_len); | |
| 909 MockWriteResult write_result = data_->OnWrite(data); | |
| 910 | |
| 911 was_used_to_convey_data_ = true; | |
| 912 | |
| 913 if (write_result.mode == ASYNC) { | |
| 914 RunCallbackAsync(callback, write_result.result); | |
| 915 return ERR_IO_PENDING; | |
| 916 } | |
| 917 | |
| 918 return write_result.result; | |
| 919 } | |
| 920 | |
| 921 int MockTCPClientSocket::Connect(const CompletionCallback& callback) { | |
| 922 if (connected_) | |
| 923 return OK; | |
| 924 connected_ = true; | |
| 925 peer_closed_connection_ = false; | |
| 926 if (data_->connect_data().mode == ASYNC) { | |
| 927 if (data_->connect_data().result == ERR_IO_PENDING) | |
| 928 pending_callback_ = callback; | |
| 929 else | |
| 930 RunCallbackAsync(callback, data_->connect_data().result); | |
| 931 return ERR_IO_PENDING; | |
| 932 } | |
| 933 return data_->connect_data().result; | |
| 934 } | |
| 935 | |
| 936 void MockTCPClientSocket::Disconnect() { | |
| 937 MockClientSocket::Disconnect(); | |
| 938 pending_callback_.Reset(); | |
| 939 } | |
| 940 | |
| 941 bool MockTCPClientSocket::IsConnected() const { | |
| 942 return connected_ && !peer_closed_connection_; | |
| 943 } | |
| 944 | |
| 945 bool MockTCPClientSocket::IsConnectedAndIdle() const { | |
| 946 return IsConnected(); | |
| 947 } | |
| 948 | |
| 949 int MockTCPClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
| 950 if (addresses_.empty()) | |
| 951 return MockClientSocket::GetPeerAddress(address); | |
| 952 | |
| 953 *address = addresses_[0]; | |
| 954 return OK; | |
| 955 } | |
| 956 | |
| 957 bool MockTCPClientSocket::WasEverUsed() const { | |
| 958 return was_used_to_convey_data_; | |
| 959 } | |
| 960 | |
| 961 bool MockTCPClientSocket::UsingTCPFastOpen() const { | |
| 962 return false; | |
| 963 } | |
| 964 | |
| 965 bool MockTCPClientSocket::WasNpnNegotiated() const { | |
| 966 return false; | |
| 967 } | |
| 968 | |
| 969 bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
| 970 return false; | |
| 971 } | |
| 972 | |
| 973 void MockTCPClientSocket::OnReadComplete(const MockRead& data) { | |
| 974 // There must be a read pending. | |
| 975 DCHECK(pending_buf_.get()); | |
| 976 // You can't complete a read with another ERR_IO_PENDING status code. | |
| 977 DCHECK_NE(ERR_IO_PENDING, data.result); | |
| 978 // Since we've been waiting for data, need_read_data_ should be true. | |
| 979 DCHECK(need_read_data_); | |
| 980 | |
| 981 read_data_ = data; | |
| 982 need_read_data_ = false; | |
| 983 | |
| 984 // The caller is simulating that this IO completes right now. Don't | |
| 985 // let CompleteRead() schedule a callback. | |
| 986 read_data_.mode = SYNCHRONOUS; | |
| 987 | |
| 988 CompletionCallback callback = pending_callback_; | |
| 989 int rv = CompleteRead(); | |
| 990 RunCallback(callback, rv); | |
| 991 } | |
| 992 | |
| 993 void MockTCPClientSocket::OnConnectComplete(const MockConnect& data) { | |
| 994 CompletionCallback callback = pending_callback_; | |
| 995 RunCallback(callback, data.result); | |
| 996 } | |
| 997 | |
| 998 int MockTCPClientSocket::CompleteRead() { | |
| 999 DCHECK(pending_buf_.get()); | |
| 1000 DCHECK(pending_buf_len_ > 0); | |
| 1001 | |
| 1002 was_used_to_convey_data_ = true; | |
| 1003 | |
| 1004 // Save the pending async IO data and reset our |pending_| state. | |
| 1005 scoped_refptr<IOBuffer> buf = pending_buf_; | |
| 1006 int buf_len = pending_buf_len_; | |
| 1007 CompletionCallback callback = pending_callback_; | |
| 1008 pending_buf_ = NULL; | |
| 1009 pending_buf_len_ = 0; | |
| 1010 pending_callback_.Reset(); | |
| 1011 | |
| 1012 int result = read_data_.result; | |
| 1013 DCHECK(result != ERR_IO_PENDING); | |
| 1014 | |
| 1015 if (read_data_.data) { | |
| 1016 if (read_data_.data_len - read_offset_ > 0) { | |
| 1017 result = std::min(buf_len, read_data_.data_len - read_offset_); | |
| 1018 memcpy(buf->data(), read_data_.data + read_offset_, result); | |
| 1019 read_offset_ += result; | |
| 1020 if (read_offset_ == read_data_.data_len) { | |
| 1021 need_read_data_ = true; | |
| 1022 read_offset_ = 0; | |
| 1023 } | |
| 1024 } else { | |
| 1025 result = 0; // EOF | |
| 1026 } | |
| 1027 } | |
| 1028 | |
| 1029 if (read_data_.mode == ASYNC) { | |
| 1030 DCHECK(!callback.is_null()); | |
| 1031 RunCallbackAsync(callback, result); | |
| 1032 return ERR_IO_PENDING; | |
| 1033 } | |
| 1034 return result; | |
| 1035 } | |
| 1036 | |
| 1037 DeterministicSocketHelper::DeterministicSocketHelper( | |
| 1038 net::NetLog* net_log, | |
| 1039 DeterministicSocketData* data) | |
| 1040 : write_pending_(false), | |
| 1041 write_result_(0), | |
| 1042 read_data_(), | |
| 1043 read_buf_(NULL), | |
| 1044 read_buf_len_(0), | |
| 1045 read_pending_(false), | |
| 1046 data_(data), | |
| 1047 was_used_to_convey_data_(false), | |
| 1048 peer_closed_connection_(false), | |
| 1049 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)) { | |
| 1050 } | |
| 1051 | |
| 1052 DeterministicSocketHelper::~DeterministicSocketHelper() {} | |
| 1053 | |
| 1054 void DeterministicSocketHelper::CompleteWrite() { | |
| 1055 was_used_to_convey_data_ = true; | |
| 1056 write_pending_ = false; | |
| 1057 write_callback_.Run(write_result_); | |
| 1058 } | |
| 1059 | |
| 1060 int DeterministicSocketHelper::CompleteRead() { | |
| 1061 DCHECK_GT(read_buf_len_, 0); | |
| 1062 DCHECK_LE(read_data_.data_len, read_buf_len_); | |
| 1063 DCHECK(read_buf_); | |
| 1064 | |
| 1065 was_used_to_convey_data_ = true; | |
| 1066 | |
| 1067 if (read_data_.result == ERR_IO_PENDING) | |
| 1068 read_data_ = data_->GetNextRead(); | |
| 1069 DCHECK_NE(ERR_IO_PENDING, read_data_.result); | |
| 1070 // If read_data_.mode is ASYNC, we do not need to wait, since this is already | |
| 1071 // the callback. Therefore we don't even bother to check it. | |
| 1072 int result = read_data_.result; | |
| 1073 | |
| 1074 if (read_data_.data_len > 0) { | |
| 1075 DCHECK(read_data_.data); | |
| 1076 result = std::min(read_buf_len_, read_data_.data_len); | |
| 1077 memcpy(read_buf_->data(), read_data_.data, result); | |
| 1078 } | |
| 1079 | |
| 1080 if (read_pending_) { | |
| 1081 read_pending_ = false; | |
| 1082 read_callback_.Run(result); | |
| 1083 } | |
| 1084 | |
| 1085 return result; | |
| 1086 } | |
| 1087 | |
| 1088 int DeterministicSocketHelper::Write( | |
| 1089 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | |
| 1090 DCHECK(buf); | |
| 1091 DCHECK_GT(buf_len, 0); | |
| 1092 | |
| 1093 std::string data(buf->data(), buf_len); | |
| 1094 MockWriteResult write_result = data_->OnWrite(data); | |
| 1095 | |
| 1096 if (write_result.mode == ASYNC) { | |
| 1097 write_callback_ = callback; | |
| 1098 write_result_ = write_result.result; | |
| 1099 DCHECK(!write_callback_.is_null()); | |
| 1100 write_pending_ = true; | |
| 1101 return ERR_IO_PENDING; | |
| 1102 } | |
| 1103 | |
| 1104 was_used_to_convey_data_ = true; | |
| 1105 write_pending_ = false; | |
| 1106 return write_result.result; | |
| 1107 } | |
| 1108 | |
| 1109 int DeterministicSocketHelper::Read( | |
| 1110 IOBuffer* buf, int buf_len, const CompletionCallback& callback) { | |
| 1111 | |
| 1112 read_data_ = data_->GetNextRead(); | |
| 1113 // The buffer should always be big enough to contain all the MockRead data. To | |
| 1114 // use small buffers, split the data into multiple MockReads. | |
| 1115 DCHECK_LE(read_data_.data_len, buf_len); | |
| 1116 | |
| 1117 if (read_data_.result == ERR_CONNECTION_CLOSED) { | |
| 1118 // This MockRead is just a marker to instruct us to set | |
| 1119 // peer_closed_connection_. | |
| 1120 peer_closed_connection_ = true; | |
| 1121 } | |
| 1122 if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { | |
| 1123 // This MockRead is just a marker to instruct us to set | |
| 1124 // peer_closed_connection_. Skip it and get the next one. | |
| 1125 read_data_ = data_->GetNextRead(); | |
| 1126 peer_closed_connection_ = true; | |
| 1127 } | |
| 1128 | |
| 1129 read_buf_ = buf; | |
| 1130 read_buf_len_ = buf_len; | |
| 1131 read_callback_ = callback; | |
| 1132 | |
| 1133 if (read_data_.mode == ASYNC || (read_data_.result == ERR_IO_PENDING)) { | |
| 1134 read_pending_ = true; | |
| 1135 DCHECK(!read_callback_.is_null()); | |
| 1136 return ERR_IO_PENDING; | |
| 1137 } | |
| 1138 | |
| 1139 was_used_to_convey_data_ = true; | |
| 1140 return CompleteRead(); | |
| 1141 } | |
| 1142 | |
| 1143 DeterministicMockUDPClientSocket::DeterministicMockUDPClientSocket( | |
| 1144 net::NetLog* net_log, | |
| 1145 DeterministicSocketData* data) | |
| 1146 : connected_(false), | |
| 1147 helper_(net_log, data), | |
| 1148 source_port_(123) { | |
| 1149 } | |
| 1150 | |
| 1151 DeterministicMockUDPClientSocket::~DeterministicMockUDPClientSocket() {} | |
| 1152 | |
| 1153 bool DeterministicMockUDPClientSocket::WritePending() const { | |
| 1154 return helper_.write_pending(); | |
| 1155 } | |
| 1156 | |
| 1157 bool DeterministicMockUDPClientSocket::ReadPending() const { | |
| 1158 return helper_.read_pending(); | |
| 1159 } | |
| 1160 | |
| 1161 void DeterministicMockUDPClientSocket::CompleteWrite() { | |
| 1162 helper_.CompleteWrite(); | |
| 1163 } | |
| 1164 | |
| 1165 int DeterministicMockUDPClientSocket::CompleteRead() { | |
| 1166 return helper_.CompleteRead(); | |
| 1167 } | |
| 1168 | |
| 1169 int DeterministicMockUDPClientSocket::Connect(const IPEndPoint& address) { | |
| 1170 if (connected_) | |
| 1171 return OK; | |
| 1172 connected_ = true; | |
| 1173 peer_address_ = address; | |
| 1174 return helper_.data()->connect_data().result; | |
| 1175 }; | |
| 1176 | |
| 1177 int DeterministicMockUDPClientSocket::Write( | |
| 1178 IOBuffer* buf, | |
| 1179 int buf_len, | |
| 1180 const CompletionCallback& callback) { | |
| 1181 if (!connected_) | |
| 1182 return ERR_UNEXPECTED; | |
| 1183 | |
| 1184 return helper_.Write(buf, buf_len, callback); | |
| 1185 } | |
| 1186 | |
| 1187 int DeterministicMockUDPClientSocket::Read( | |
| 1188 IOBuffer* buf, | |
| 1189 int buf_len, | |
| 1190 const CompletionCallback& callback) { | |
| 1191 if (!connected_) | |
| 1192 return ERR_UNEXPECTED; | |
| 1193 | |
| 1194 return helper_.Read(buf, buf_len, callback); | |
| 1195 } | |
| 1196 | |
| 1197 int DeterministicMockUDPClientSocket::SetReceiveBufferSize(int32 size) { | |
| 1198 return OK; | |
| 1199 } | |
| 1200 | |
| 1201 int DeterministicMockUDPClientSocket::SetSendBufferSize(int32 size) { | |
| 1202 return OK; | |
| 1203 } | |
| 1204 | |
| 1205 void DeterministicMockUDPClientSocket::Close() { | |
| 1206 connected_ = false; | |
| 1207 } | |
| 1208 | |
| 1209 int DeterministicMockUDPClientSocket::GetPeerAddress( | |
| 1210 IPEndPoint* address) const { | |
| 1211 *address = peer_address_; | |
| 1212 return OK; | |
| 1213 } | |
| 1214 | |
| 1215 int DeterministicMockUDPClientSocket::GetLocalAddress( | |
| 1216 IPEndPoint* address) const { | |
| 1217 IPAddressNumber ip; | |
| 1218 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
| 1219 CHECK(rv); | |
| 1220 *address = IPEndPoint(ip, source_port_); | |
| 1221 return OK; | |
| 1222 } | |
| 1223 | |
| 1224 const BoundNetLog& DeterministicMockUDPClientSocket::NetLog() const { | |
| 1225 return helper_.net_log(); | |
| 1226 } | |
| 1227 | |
| 1228 void DeterministicMockUDPClientSocket::OnReadComplete(const MockRead& data) {} | |
| 1229 | |
| 1230 void DeterministicMockUDPClientSocket::OnConnectComplete( | |
| 1231 const MockConnect& data) { | |
| 1232 NOTIMPLEMENTED(); | |
| 1233 } | |
| 1234 | |
| 1235 DeterministicMockTCPClientSocket::DeterministicMockTCPClientSocket( | |
| 1236 net::NetLog* net_log, | |
| 1237 DeterministicSocketData* data) | |
| 1238 : MockClientSocket(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
| 1239 helper_(net_log, data) { | |
| 1240 peer_addr_ = data->connect_data().peer_addr; | |
| 1241 } | |
| 1242 | |
| 1243 DeterministicMockTCPClientSocket::~DeterministicMockTCPClientSocket() {} | |
| 1244 | |
| 1245 bool DeterministicMockTCPClientSocket::WritePending() const { | |
| 1246 return helper_.write_pending(); | |
| 1247 } | |
| 1248 | |
| 1249 bool DeterministicMockTCPClientSocket::ReadPending() const { | |
| 1250 return helper_.read_pending(); | |
| 1251 } | |
| 1252 | |
| 1253 void DeterministicMockTCPClientSocket::CompleteWrite() { | |
| 1254 helper_.CompleteWrite(); | |
| 1255 } | |
| 1256 | |
| 1257 int DeterministicMockTCPClientSocket::CompleteRead() { | |
| 1258 return helper_.CompleteRead(); | |
| 1259 } | |
| 1260 | |
| 1261 int DeterministicMockTCPClientSocket::Write( | |
| 1262 IOBuffer* buf, | |
| 1263 int buf_len, | |
| 1264 const CompletionCallback& callback) { | |
| 1265 if (!connected_) | |
| 1266 return ERR_UNEXPECTED; | |
| 1267 | |
| 1268 return helper_.Write(buf, buf_len, callback); | |
| 1269 } | |
| 1270 | |
| 1271 int DeterministicMockTCPClientSocket::Read( | |
| 1272 IOBuffer* buf, | |
| 1273 int buf_len, | |
| 1274 const CompletionCallback& callback) { | |
| 1275 if (!connected_) | |
| 1276 return ERR_UNEXPECTED; | |
| 1277 | |
| 1278 return helper_.Read(buf, buf_len, callback); | |
| 1279 } | |
| 1280 | |
| 1281 // TODO(erikchen): Support connect sequencing. | |
| 1282 int DeterministicMockTCPClientSocket::Connect( | |
| 1283 const CompletionCallback& callback) { | |
| 1284 if (connected_) | |
| 1285 return OK; | |
| 1286 connected_ = true; | |
| 1287 if (helper_.data()->connect_data().mode == ASYNC) { | |
| 1288 RunCallbackAsync(callback, helper_.data()->connect_data().result); | |
| 1289 return ERR_IO_PENDING; | |
| 1290 } | |
| 1291 return helper_.data()->connect_data().result; | |
| 1292 } | |
| 1293 | |
| 1294 void DeterministicMockTCPClientSocket::Disconnect() { | |
| 1295 MockClientSocket::Disconnect(); | |
| 1296 } | |
| 1297 | |
| 1298 bool DeterministicMockTCPClientSocket::IsConnected() const { | |
| 1299 return connected_ && !helper_.peer_closed_connection(); | |
| 1300 } | |
| 1301 | |
| 1302 bool DeterministicMockTCPClientSocket::IsConnectedAndIdle() const { | |
| 1303 return IsConnected(); | |
| 1304 } | |
| 1305 | |
| 1306 bool DeterministicMockTCPClientSocket::WasEverUsed() const { | |
| 1307 return helper_.was_used_to_convey_data(); | |
| 1308 } | |
| 1309 | |
| 1310 bool DeterministicMockTCPClientSocket::UsingTCPFastOpen() const { | |
| 1311 return false; | |
| 1312 } | |
| 1313 | |
| 1314 bool DeterministicMockTCPClientSocket::WasNpnNegotiated() const { | |
| 1315 return false; | |
| 1316 } | |
| 1317 | |
| 1318 bool DeterministicMockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
| 1319 return false; | |
| 1320 } | |
| 1321 | |
| 1322 void DeterministicMockTCPClientSocket::OnReadComplete(const MockRead& data) {} | |
| 1323 | |
| 1324 void DeterministicMockTCPClientSocket::OnConnectComplete( | |
| 1325 const MockConnect& data) {} | |
| 1326 | |
| 1327 MockSSLClientSocket::MockSSLClientSocket( | |
| 1328 scoped_ptr<ClientSocketHandle> transport_socket, | |
| 1329 const HostPortPair& host_port_pair, | |
| 1330 const SSLConfig& ssl_config, | |
| 1331 SSLSocketDataProvider* data) | |
| 1332 : MockClientSocket( | |
| 1333 // Have to use the right BoundNetLog for LoadTimingInfo regression | |
| 1334 // tests. | |
| 1335 transport_socket->socket()->NetLog()), | |
| 1336 transport_(transport_socket.Pass()), | |
| 1337 host_port_pair_(host_port_pair), | |
| 1338 data_(data), | |
| 1339 is_npn_state_set_(false), | |
| 1340 new_npn_value_(false), | |
| 1341 is_protocol_negotiated_set_(false), | |
| 1342 protocol_negotiated_(kProtoUnknown), | |
| 1343 next_connect_state_(STATE_NONE), | |
| 1344 reached_connect_(false), | |
| 1345 weak_factory_(this) { | |
| 1346 DCHECK(data_); | |
| 1347 peer_addr_ = data->connect.peer_addr; | |
| 1348 } | |
| 1349 | |
| 1350 MockSSLClientSocket::~MockSSLClientSocket() { | |
| 1351 Disconnect(); | |
| 1352 } | |
| 1353 | |
| 1354 int MockSSLClientSocket::Read(IOBuffer* buf, int buf_len, | |
| 1355 const CompletionCallback& callback) { | |
| 1356 return transport_->socket()->Read(buf, buf_len, callback); | |
| 1357 } | |
| 1358 | |
| 1359 int MockSSLClientSocket::Write(IOBuffer* buf, int buf_len, | |
| 1360 const CompletionCallback& callback) { | |
| 1361 return transport_->socket()->Write(buf, buf_len, callback); | |
| 1362 } | |
| 1363 | |
| 1364 int MockSSLClientSocket::Connect(const CompletionCallback& callback) { | |
| 1365 next_connect_state_ = STATE_SSL_CONNECT; | |
| 1366 reached_connect_ = true; | |
| 1367 int rv = DoConnectLoop(OK); | |
| 1368 if (rv == ERR_IO_PENDING) | |
| 1369 connect_callback_ = callback; | |
| 1370 return rv; | |
| 1371 } | |
| 1372 | |
| 1373 void MockSSLClientSocket::Disconnect() { | |
| 1374 weak_factory_.InvalidateWeakPtrs(); | |
| 1375 MockClientSocket::Disconnect(); | |
| 1376 if (transport_->socket() != NULL) | |
| 1377 transport_->socket()->Disconnect(); | |
| 1378 } | |
| 1379 | |
| 1380 bool MockSSLClientSocket::IsConnected() const { | |
| 1381 return transport_->socket()->IsConnected() && connected_; | |
| 1382 } | |
| 1383 | |
| 1384 bool MockSSLClientSocket::WasEverUsed() const { | |
| 1385 return transport_->socket()->WasEverUsed(); | |
| 1386 } | |
| 1387 | |
| 1388 bool MockSSLClientSocket::UsingTCPFastOpen() const { | |
| 1389 return transport_->socket()->UsingTCPFastOpen(); | |
| 1390 } | |
| 1391 | |
| 1392 int MockSSLClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
| 1393 return transport_->socket()->GetPeerAddress(address); | |
| 1394 } | |
| 1395 | |
| 1396 bool MockSSLClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | |
| 1397 ssl_info->Reset(); | |
| 1398 ssl_info->cert = data_->cert; | |
| 1399 ssl_info->client_cert_sent = data_->client_cert_sent; | |
| 1400 ssl_info->channel_id_sent = data_->channel_id_sent; | |
| 1401 ssl_info->connection_status = data_->connection_status; | |
| 1402 return true; | |
| 1403 } | |
| 1404 | |
| 1405 std::string MockSSLClientSocket::GetSessionCacheKey() const { | |
| 1406 // For the purposes of these tests, |host_and_port| will serve as the | |
| 1407 // cache key. | |
| 1408 return host_port_pair_.ToString(); | |
| 1409 } | |
| 1410 | |
| 1411 bool MockSSLClientSocket::InSessionCache() const { | |
| 1412 return data_->is_in_session_cache; | |
| 1413 } | |
| 1414 | |
| 1415 void MockSSLClientSocket::SetHandshakeCompletionCallback( | |
| 1416 const base::Closure& cb) { | |
| 1417 handshake_completion_callback_ = cb; | |
| 1418 } | |
| 1419 | |
| 1420 void MockSSLClientSocket::GetSSLCertRequestInfo( | |
| 1421 SSLCertRequestInfo* cert_request_info) { | |
| 1422 DCHECK(cert_request_info); | |
| 1423 if (data_->cert_request_info) { | |
| 1424 cert_request_info->host_and_port = | |
| 1425 data_->cert_request_info->host_and_port; | |
| 1426 cert_request_info->client_certs = data_->cert_request_info->client_certs; | |
| 1427 } else { | |
| 1428 cert_request_info->Reset(); | |
| 1429 } | |
| 1430 } | |
| 1431 | |
| 1432 SSLClientSocket::NextProtoStatus MockSSLClientSocket::GetNextProto( | |
| 1433 std::string* proto) { | |
| 1434 *proto = data_->next_proto; | |
| 1435 return data_->next_proto_status; | |
| 1436 } | |
| 1437 | |
| 1438 bool MockSSLClientSocket::set_was_npn_negotiated(bool negotiated) { | |
| 1439 is_npn_state_set_ = true; | |
| 1440 return new_npn_value_ = negotiated; | |
| 1441 } | |
| 1442 | |
| 1443 bool MockSSLClientSocket::WasNpnNegotiated() const { | |
| 1444 if (is_npn_state_set_) | |
| 1445 return new_npn_value_; | |
| 1446 return data_->was_npn_negotiated; | |
| 1447 } | |
| 1448 | |
| 1449 NextProto MockSSLClientSocket::GetNegotiatedProtocol() const { | |
| 1450 if (is_protocol_negotiated_set_) | |
| 1451 return protocol_negotiated_; | |
| 1452 return data_->protocol_negotiated; | |
| 1453 } | |
| 1454 | |
| 1455 void MockSSLClientSocket::set_protocol_negotiated( | |
| 1456 NextProto protocol_negotiated) { | |
| 1457 is_protocol_negotiated_set_ = true; | |
| 1458 protocol_negotiated_ = protocol_negotiated; | |
| 1459 } | |
| 1460 | |
| 1461 bool MockSSLClientSocket::WasChannelIDSent() const { | |
| 1462 return data_->channel_id_sent; | |
| 1463 } | |
| 1464 | |
| 1465 void MockSSLClientSocket::set_channel_id_sent(bool channel_id_sent) { | |
| 1466 data_->channel_id_sent = channel_id_sent; | |
| 1467 } | |
| 1468 | |
| 1469 ChannelIDService* MockSSLClientSocket::GetChannelIDService() const { | |
| 1470 return data_->channel_id_service; | |
| 1471 } | |
| 1472 | |
| 1473 void MockSSLClientSocket::OnReadComplete(const MockRead& data) { | |
| 1474 NOTIMPLEMENTED(); | |
| 1475 } | |
| 1476 | |
| 1477 void MockSSLClientSocket::OnConnectComplete(const MockConnect& data) { | |
| 1478 NOTIMPLEMENTED(); | |
| 1479 } | |
| 1480 | |
| 1481 void MockSSLClientSocket::RestartPausedConnect() { | |
| 1482 DCHECK(data_->should_pause_on_connect); | |
| 1483 DCHECK_EQ(next_connect_state_, STATE_SSL_CONNECT_COMPLETE); | |
| 1484 OnIOComplete(data_->connect.result); | |
| 1485 } | |
| 1486 | |
| 1487 void MockSSLClientSocket::OnIOComplete(int result) { | |
| 1488 int rv = DoConnectLoop(result); | |
| 1489 if (rv != ERR_IO_PENDING) | |
| 1490 base::ResetAndReturn(&connect_callback_).Run(rv); | |
| 1491 } | |
| 1492 | |
| 1493 int MockSSLClientSocket::DoConnectLoop(int result) { | |
| 1494 DCHECK_NE(next_connect_state_, STATE_NONE); | |
| 1495 | |
| 1496 int rv = result; | |
| 1497 do { | |
| 1498 ConnectState state = next_connect_state_; | |
| 1499 next_connect_state_ = STATE_NONE; | |
| 1500 switch (state) { | |
| 1501 case STATE_SSL_CONNECT: | |
| 1502 rv = DoSSLConnect(); | |
| 1503 break; | |
| 1504 case STATE_SSL_CONNECT_COMPLETE: | |
| 1505 rv = DoSSLConnectComplete(rv); | |
| 1506 break; | |
| 1507 default: | |
| 1508 NOTREACHED() << "bad state"; | |
| 1509 rv = ERR_UNEXPECTED; | |
| 1510 break; | |
| 1511 } | |
| 1512 } while (rv != ERR_IO_PENDING && next_connect_state_ != STATE_NONE); | |
| 1513 | |
| 1514 return rv; | |
| 1515 } | |
| 1516 | |
| 1517 int MockSSLClientSocket::DoSSLConnect() { | |
| 1518 next_connect_state_ = STATE_SSL_CONNECT_COMPLETE; | |
| 1519 | |
| 1520 if (data_->should_pause_on_connect) | |
| 1521 return ERR_IO_PENDING; | |
| 1522 | |
| 1523 if (data_->connect.mode == ASYNC) { | |
| 1524 base::MessageLoop::current()->PostTask( | |
| 1525 FROM_HERE, | |
| 1526 base::Bind(&MockSSLClientSocket::OnIOComplete, | |
| 1527 weak_factory_.GetWeakPtr(), | |
| 1528 data_->connect.result)); | |
| 1529 return ERR_IO_PENDING; | |
| 1530 } | |
| 1531 | |
| 1532 return data_->connect.result; | |
| 1533 } | |
| 1534 | |
| 1535 int MockSSLClientSocket::DoSSLConnectComplete(int result) { | |
| 1536 if (result == OK) | |
| 1537 connected_ = true; | |
| 1538 | |
| 1539 if (!handshake_completion_callback_.is_null()) | |
| 1540 base::ResetAndReturn(&handshake_completion_callback_).Run(); | |
| 1541 return result; | |
| 1542 } | |
| 1543 | |
| 1544 MockUDPClientSocket::MockUDPClientSocket(SocketDataProvider* data, | |
| 1545 net::NetLog* net_log) | |
| 1546 : connected_(false), | |
| 1547 data_(data), | |
| 1548 read_offset_(0), | |
| 1549 read_data_(SYNCHRONOUS, ERR_UNEXPECTED), | |
| 1550 need_read_data_(true), | |
| 1551 source_port_(123), | |
| 1552 pending_buf_(NULL), | |
| 1553 pending_buf_len_(0), | |
| 1554 net_log_(BoundNetLog::Make(net_log, net::NetLog::SOURCE_NONE)), | |
| 1555 weak_factory_(this) { | |
| 1556 DCHECK(data_); | |
| 1557 data_->Reset(); | |
| 1558 peer_addr_ = data->connect_data().peer_addr; | |
| 1559 } | |
| 1560 | |
| 1561 MockUDPClientSocket::~MockUDPClientSocket() {} | |
| 1562 | |
| 1563 int MockUDPClientSocket::Read(IOBuffer* buf, | |
| 1564 int buf_len, | |
| 1565 const CompletionCallback& callback) { | |
| 1566 if (!connected_) | |
| 1567 return ERR_UNEXPECTED; | |
| 1568 | |
| 1569 // If the buffer is already in use, a read is already in progress! | |
| 1570 DCHECK(pending_buf_.get() == NULL); | |
| 1571 | |
| 1572 // Store our async IO data. | |
| 1573 pending_buf_ = buf; | |
| 1574 pending_buf_len_ = buf_len; | |
| 1575 pending_callback_ = callback; | |
| 1576 | |
| 1577 if (need_read_data_) { | |
| 1578 read_data_ = data_->GetNextRead(); | |
| 1579 // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility | |
| 1580 // to complete the async IO manually later (via OnReadComplete). | |
| 1581 if (read_data_.result == ERR_IO_PENDING) { | |
| 1582 // We need to be using async IO in this case. | |
| 1583 DCHECK(!callback.is_null()); | |
| 1584 return ERR_IO_PENDING; | |
| 1585 } | |
| 1586 need_read_data_ = false; | |
| 1587 } | |
| 1588 | |
| 1589 return CompleteRead(); | |
| 1590 } | |
| 1591 | |
| 1592 int MockUDPClientSocket::Write(IOBuffer* buf, int buf_len, | |
| 1593 const CompletionCallback& callback) { | |
| 1594 DCHECK(buf); | |
| 1595 DCHECK_GT(buf_len, 0); | |
| 1596 | |
| 1597 if (!connected_) | |
| 1598 return ERR_UNEXPECTED; | |
| 1599 | |
| 1600 std::string data(buf->data(), buf_len); | |
| 1601 MockWriteResult write_result = data_->OnWrite(data); | |
| 1602 | |
| 1603 if (write_result.mode == ASYNC) { | |
| 1604 RunCallbackAsync(callback, write_result.result); | |
| 1605 return ERR_IO_PENDING; | |
| 1606 } | |
| 1607 return write_result.result; | |
| 1608 } | |
| 1609 | |
| 1610 int MockUDPClientSocket::SetReceiveBufferSize(int32 size) { | |
| 1611 return OK; | |
| 1612 } | |
| 1613 | |
| 1614 int MockUDPClientSocket::SetSendBufferSize(int32 size) { | |
| 1615 return OK; | |
| 1616 } | |
| 1617 | |
| 1618 void MockUDPClientSocket::Close() { | |
| 1619 connected_ = false; | |
| 1620 } | |
| 1621 | |
| 1622 int MockUDPClientSocket::GetPeerAddress(IPEndPoint* address) const { | |
| 1623 *address = peer_addr_; | |
| 1624 return OK; | |
| 1625 } | |
| 1626 | |
| 1627 int MockUDPClientSocket::GetLocalAddress(IPEndPoint* address) const { | |
| 1628 IPAddressNumber ip; | |
| 1629 bool rv = ParseIPLiteralToNumber("192.0.2.33", &ip); | |
| 1630 CHECK(rv); | |
| 1631 *address = IPEndPoint(ip, source_port_); | |
| 1632 return OK; | |
| 1633 } | |
| 1634 | |
| 1635 const BoundNetLog& MockUDPClientSocket::NetLog() const { | |
| 1636 return net_log_; | |
| 1637 } | |
| 1638 | |
| 1639 int MockUDPClientSocket::Connect(const IPEndPoint& address) { | |
| 1640 connected_ = true; | |
| 1641 peer_addr_ = address; | |
| 1642 return data_->connect_data().result; | |
| 1643 } | |
| 1644 | |
| 1645 void MockUDPClientSocket::OnReadComplete(const MockRead& data) { | |
| 1646 // There must be a read pending. | |
| 1647 DCHECK(pending_buf_.get()); | |
| 1648 // You can't complete a read with another ERR_IO_PENDING status code. | |
| 1649 DCHECK_NE(ERR_IO_PENDING, data.result); | |
| 1650 // Since we've been waiting for data, need_read_data_ should be true. | |
| 1651 DCHECK(need_read_data_); | |
| 1652 | |
| 1653 read_data_ = data; | |
| 1654 need_read_data_ = false; | |
| 1655 | |
| 1656 // The caller is simulating that this IO completes right now. Don't | |
| 1657 // let CompleteRead() schedule a callback. | |
| 1658 read_data_.mode = SYNCHRONOUS; | |
| 1659 | |
| 1660 net::CompletionCallback callback = pending_callback_; | |
| 1661 int rv = CompleteRead(); | |
| 1662 RunCallback(callback, rv); | |
| 1663 } | |
| 1664 | |
| 1665 void MockUDPClientSocket::OnConnectComplete(const MockConnect& data) { | |
| 1666 NOTIMPLEMENTED(); | |
| 1667 } | |
| 1668 | |
| 1669 int MockUDPClientSocket::CompleteRead() { | |
| 1670 DCHECK(pending_buf_.get()); | |
| 1671 DCHECK(pending_buf_len_ > 0); | |
| 1672 | |
| 1673 // Save the pending async IO data and reset our |pending_| state. | |
| 1674 scoped_refptr<IOBuffer> buf = pending_buf_; | |
| 1675 int buf_len = pending_buf_len_; | |
| 1676 CompletionCallback callback = pending_callback_; | |
| 1677 pending_buf_ = NULL; | |
| 1678 pending_buf_len_ = 0; | |
| 1679 pending_callback_.Reset(); | |
| 1680 | |
| 1681 int result = read_data_.result; | |
| 1682 DCHECK(result != ERR_IO_PENDING); | |
| 1683 | |
| 1684 if (read_data_.data) { | |
| 1685 if (read_data_.data_len - read_offset_ > 0) { | |
| 1686 result = std::min(buf_len, read_data_.data_len - read_offset_); | |
| 1687 memcpy(buf->data(), read_data_.data + read_offset_, result); | |
| 1688 read_offset_ += result; | |
| 1689 if (read_offset_ == read_data_.data_len) { | |
| 1690 need_read_data_ = true; | |
| 1691 read_offset_ = 0; | |
| 1692 } | |
| 1693 } else { | |
| 1694 result = 0; // EOF | |
| 1695 } | |
| 1696 } | |
| 1697 | |
| 1698 if (read_data_.mode == ASYNC) { | |
| 1699 DCHECK(!callback.is_null()); | |
| 1700 RunCallbackAsync(callback, result); | |
| 1701 return ERR_IO_PENDING; | |
| 1702 } | |
| 1703 return result; | |
| 1704 } | |
| 1705 | |
| 1706 void MockUDPClientSocket::RunCallbackAsync(const CompletionCallback& callback, | |
| 1707 int result) { | |
| 1708 base::MessageLoop::current()->PostTask( | |
| 1709 FROM_HERE, | |
| 1710 base::Bind(&MockUDPClientSocket::RunCallback, | |
| 1711 weak_factory_.GetWeakPtr(), | |
| 1712 callback, | |
| 1713 result)); | |
| 1714 } | |
| 1715 | |
| 1716 void MockUDPClientSocket::RunCallback(const CompletionCallback& callback, | |
| 1717 int result) { | |
| 1718 if (!callback.is_null()) | |
| 1719 callback.Run(result); | |
| 1720 } | |
| 1721 | |
| 1722 TestSocketRequest::TestSocketRequest( | |
| 1723 std::vector<TestSocketRequest*>* request_order, size_t* completion_count) | |
| 1724 : request_order_(request_order), | |
| 1725 completion_count_(completion_count), | |
| 1726 callback_(base::Bind(&TestSocketRequest::OnComplete, | |
| 1727 base::Unretained(this))) { | |
| 1728 DCHECK(request_order); | |
| 1729 DCHECK(completion_count); | |
| 1730 } | |
| 1731 | |
| 1732 TestSocketRequest::~TestSocketRequest() { | |
| 1733 } | |
| 1734 | |
| 1735 void TestSocketRequest::OnComplete(int result) { | |
| 1736 SetResult(result); | |
| 1737 (*completion_count_)++; | |
| 1738 request_order_->push_back(this); | |
| 1739 } | |
| 1740 | |
| 1741 // static | |
| 1742 const int ClientSocketPoolTest::kIndexOutOfBounds = -1; | |
| 1743 | |
| 1744 // static | |
| 1745 const int ClientSocketPoolTest::kRequestNotFound = -2; | |
| 1746 | |
| 1747 ClientSocketPoolTest::ClientSocketPoolTest() : completion_count_(0) {} | |
| 1748 ClientSocketPoolTest::~ClientSocketPoolTest() {} | |
| 1749 | |
| 1750 int ClientSocketPoolTest::GetOrderOfRequest(size_t index) const { | |
| 1751 index--; | |
| 1752 if (index >= requests_.size()) | |
| 1753 return kIndexOutOfBounds; | |
| 1754 | |
| 1755 for (size_t i = 0; i < request_order_.size(); i++) | |
| 1756 if (requests_[index] == request_order_[i]) | |
| 1757 return i + 1; | |
| 1758 | |
| 1759 return kRequestNotFound; | |
| 1760 } | |
| 1761 | |
| 1762 bool ClientSocketPoolTest::ReleaseOneConnection(KeepAlive keep_alive) { | |
| 1763 ScopedVector<TestSocketRequest>::iterator i; | |
| 1764 for (i = requests_.begin(); i != requests_.end(); ++i) { | |
| 1765 if ((*i)->handle()->is_initialized()) { | |
| 1766 if (keep_alive == NO_KEEP_ALIVE) | |
| 1767 (*i)->handle()->socket()->Disconnect(); | |
| 1768 (*i)->handle()->Reset(); | |
| 1769 base::RunLoop().RunUntilIdle(); | |
| 1770 return true; | |
| 1771 } | |
| 1772 } | |
| 1773 return false; | |
| 1774 } | |
| 1775 | |
| 1776 void ClientSocketPoolTest::ReleaseAllConnections(KeepAlive keep_alive) { | |
| 1777 bool released_one; | |
| 1778 do { | |
| 1779 released_one = ReleaseOneConnection(keep_alive); | |
| 1780 } while (released_one); | |
| 1781 } | |
| 1782 | |
| 1783 MockTransportClientSocketPool::MockConnectJob::MockConnectJob( | |
| 1784 scoped_ptr<StreamSocket> socket, | |
| 1785 ClientSocketHandle* handle, | |
| 1786 const CompletionCallback& callback) | |
| 1787 : socket_(socket.Pass()), | |
| 1788 handle_(handle), | |
| 1789 user_callback_(callback) { | |
| 1790 } | |
| 1791 | |
| 1792 MockTransportClientSocketPool::MockConnectJob::~MockConnectJob() {} | |
| 1793 | |
| 1794 int MockTransportClientSocketPool::MockConnectJob::Connect() { | |
| 1795 int rv = socket_->Connect(base::Bind(&MockConnectJob::OnConnect, | |
| 1796 base::Unretained(this))); | |
| 1797 if (rv == OK) { | |
| 1798 user_callback_.Reset(); | |
| 1799 OnConnect(OK); | |
| 1800 } | |
| 1801 return rv; | |
| 1802 } | |
| 1803 | |
| 1804 bool MockTransportClientSocketPool::MockConnectJob::CancelHandle( | |
| 1805 const ClientSocketHandle* handle) { | |
| 1806 if (handle != handle_) | |
| 1807 return false; | |
| 1808 socket_.reset(); | |
| 1809 handle_ = NULL; | |
| 1810 user_callback_.Reset(); | |
| 1811 return true; | |
| 1812 } | |
| 1813 | |
| 1814 void MockTransportClientSocketPool::MockConnectJob::OnConnect(int rv) { | |
| 1815 if (!socket_.get()) | |
| 1816 return; | |
| 1817 if (rv == OK) { | |
| 1818 handle_->SetSocket(socket_.Pass()); | |
| 1819 | |
| 1820 // Needed for socket pool tests that layer other sockets on top of mock | |
| 1821 // sockets. | |
| 1822 LoadTimingInfo::ConnectTiming connect_timing; | |
| 1823 base::TimeTicks now = base::TimeTicks::Now(); | |
| 1824 connect_timing.dns_start = now; | |
| 1825 connect_timing.dns_end = now; | |
| 1826 connect_timing.connect_start = now; | |
| 1827 connect_timing.connect_end = now; | |
| 1828 handle_->set_connect_timing(connect_timing); | |
| 1829 } else { | |
| 1830 socket_.reset(); | |
| 1831 } | |
| 1832 | |
| 1833 handle_ = NULL; | |
| 1834 | |
| 1835 if (!user_callback_.is_null()) { | |
| 1836 CompletionCallback callback = user_callback_; | |
| 1837 user_callback_.Reset(); | |
| 1838 callback.Run(rv); | |
| 1839 } | |
| 1840 } | |
| 1841 | |
| 1842 MockTransportClientSocketPool::MockTransportClientSocketPool( | |
| 1843 int max_sockets, | |
| 1844 int max_sockets_per_group, | |
| 1845 ClientSocketPoolHistograms* histograms, | |
| 1846 ClientSocketFactory* socket_factory) | |
| 1847 : TransportClientSocketPool(max_sockets, max_sockets_per_group, histograms, | |
| 1848 NULL, NULL, NULL), | |
| 1849 client_socket_factory_(socket_factory), | |
| 1850 last_request_priority_(DEFAULT_PRIORITY), | |
| 1851 release_count_(0), | |
| 1852 cancel_count_(0) { | |
| 1853 } | |
| 1854 | |
| 1855 MockTransportClientSocketPool::~MockTransportClientSocketPool() {} | |
| 1856 | |
| 1857 int MockTransportClientSocketPool::RequestSocket( | |
| 1858 const std::string& group_name, const void* socket_params, | |
| 1859 RequestPriority priority, ClientSocketHandle* handle, | |
| 1860 const CompletionCallback& callback, const BoundNetLog& net_log) { | |
| 1861 last_request_priority_ = priority; | |
| 1862 scoped_ptr<StreamSocket> socket = | |
| 1863 client_socket_factory_->CreateTransportClientSocket( | |
| 1864 AddressList(), net_log.net_log(), net::NetLog::Source()); | |
| 1865 MockConnectJob* job = new MockConnectJob(socket.Pass(), handle, callback); | |
| 1866 job_list_.push_back(job); | |
| 1867 handle->set_pool_id(1); | |
| 1868 return job->Connect(); | |
| 1869 } | |
| 1870 | |
| 1871 void MockTransportClientSocketPool::CancelRequest(const std::string& group_name, | |
| 1872 ClientSocketHandle* handle) { | |
| 1873 std::vector<MockConnectJob*>::iterator i; | |
| 1874 for (i = job_list_.begin(); i != job_list_.end(); ++i) { | |
| 1875 if ((*i)->CancelHandle(handle)) { | |
| 1876 cancel_count_++; | |
| 1877 break; | |
| 1878 } | |
| 1879 } | |
| 1880 } | |
| 1881 | |
| 1882 void MockTransportClientSocketPool::ReleaseSocket( | |
| 1883 const std::string& group_name, | |
| 1884 scoped_ptr<StreamSocket> socket, | |
| 1885 int id) { | |
| 1886 EXPECT_EQ(1, id); | |
| 1887 release_count_++; | |
| 1888 } | |
| 1889 | |
| 1890 DeterministicMockClientSocketFactory::DeterministicMockClientSocketFactory() {} | |
| 1891 | |
| 1892 DeterministicMockClientSocketFactory::~DeterministicMockClientSocketFactory() {} | |
| 1893 | |
| 1894 void DeterministicMockClientSocketFactory::AddSocketDataProvider( | |
| 1895 DeterministicSocketData* data) { | |
| 1896 mock_data_.Add(data); | |
| 1897 } | |
| 1898 | |
| 1899 void DeterministicMockClientSocketFactory::AddSSLSocketDataProvider( | |
| 1900 SSLSocketDataProvider* data) { | |
| 1901 mock_ssl_data_.Add(data); | |
| 1902 } | |
| 1903 | |
| 1904 void DeterministicMockClientSocketFactory::ResetNextMockIndexes() { | |
| 1905 mock_data_.ResetNextIndex(); | |
| 1906 mock_ssl_data_.ResetNextIndex(); | |
| 1907 } | |
| 1908 | |
| 1909 MockSSLClientSocket* DeterministicMockClientSocketFactory:: | |
| 1910 GetMockSSLClientSocket(size_t index) const { | |
| 1911 DCHECK_LT(index, ssl_client_sockets_.size()); | |
| 1912 return ssl_client_sockets_[index]; | |
| 1913 } | |
| 1914 | |
| 1915 scoped_ptr<DatagramClientSocket> | |
| 1916 DeterministicMockClientSocketFactory::CreateDatagramClientSocket( | |
| 1917 DatagramSocket::BindType bind_type, | |
| 1918 const RandIntCallback& rand_int_cb, | |
| 1919 net::NetLog* net_log, | |
| 1920 const NetLog::Source& source) { | |
| 1921 DeterministicSocketData* data_provider = mock_data().GetNext(); | |
| 1922 scoped_ptr<DeterministicMockUDPClientSocket> socket( | |
| 1923 new DeterministicMockUDPClientSocket(net_log, data_provider)); | |
| 1924 data_provider->set_delegate(socket->AsWeakPtr()); | |
| 1925 udp_client_sockets().push_back(socket.get()); | |
| 1926 if (bind_type == DatagramSocket::RANDOM_BIND) | |
| 1927 socket->set_source_port(static_cast<uint16>(rand_int_cb.Run(1025, 65535))); | |
| 1928 return socket.Pass(); | |
| 1929 } | |
| 1930 | |
| 1931 scoped_ptr<StreamSocket> | |
| 1932 DeterministicMockClientSocketFactory::CreateTransportClientSocket( | |
| 1933 const AddressList& addresses, | |
| 1934 net::NetLog* net_log, | |
| 1935 const net::NetLog::Source& source) { | |
| 1936 DeterministicSocketData* data_provider = mock_data().GetNext(); | |
| 1937 scoped_ptr<DeterministicMockTCPClientSocket> socket( | |
| 1938 new DeterministicMockTCPClientSocket(net_log, data_provider)); | |
| 1939 data_provider->set_delegate(socket->AsWeakPtr()); | |
| 1940 tcp_client_sockets().push_back(socket.get()); | |
| 1941 return socket.Pass(); | |
| 1942 } | |
| 1943 | |
| 1944 scoped_ptr<SSLClientSocket> | |
| 1945 DeterministicMockClientSocketFactory::CreateSSLClientSocket( | |
| 1946 scoped_ptr<ClientSocketHandle> transport_socket, | |
| 1947 const HostPortPair& host_and_port, | |
| 1948 const SSLConfig& ssl_config, | |
| 1949 const SSLClientSocketContext& context) { | |
| 1950 scoped_ptr<MockSSLClientSocket> socket( | |
| 1951 new MockSSLClientSocket(transport_socket.Pass(), | |
| 1952 host_and_port, ssl_config, | |
| 1953 mock_ssl_data_.GetNext())); | |
| 1954 ssl_client_sockets_.push_back(socket.get()); | |
| 1955 return socket.Pass(); | |
| 1956 } | |
| 1957 | |
| 1958 void DeterministicMockClientSocketFactory::ClearSSLSessionCache() { | |
| 1959 } | |
| 1960 | |
| 1961 MockSOCKSClientSocketPool::MockSOCKSClientSocketPool( | |
| 1962 int max_sockets, | |
| 1963 int max_sockets_per_group, | |
| 1964 ClientSocketPoolHistograms* histograms, | |
| 1965 TransportClientSocketPool* transport_pool) | |
| 1966 : SOCKSClientSocketPool(max_sockets, max_sockets_per_group, histograms, | |
| 1967 NULL, transport_pool, NULL), | |
| 1968 transport_pool_(transport_pool) { | |
| 1969 } | |
| 1970 | |
| 1971 MockSOCKSClientSocketPool::~MockSOCKSClientSocketPool() {} | |
| 1972 | |
| 1973 int MockSOCKSClientSocketPool::RequestSocket( | |
| 1974 const std::string& group_name, const void* socket_params, | |
| 1975 RequestPriority priority, ClientSocketHandle* handle, | |
| 1976 const CompletionCallback& callback, const BoundNetLog& net_log) { | |
| 1977 return transport_pool_->RequestSocket( | |
| 1978 group_name, socket_params, priority, handle, callback, net_log); | |
| 1979 } | |
| 1980 | |
| 1981 void MockSOCKSClientSocketPool::CancelRequest( | |
| 1982 const std::string& group_name, | |
| 1983 ClientSocketHandle* handle) { | |
| 1984 return transport_pool_->CancelRequest(group_name, handle); | |
| 1985 } | |
| 1986 | |
| 1987 void MockSOCKSClientSocketPool::ReleaseSocket(const std::string& group_name, | |
| 1988 scoped_ptr<StreamSocket> socket, | |
| 1989 int id) { | |
| 1990 return transport_pool_->ReleaseSocket(group_name, socket.Pass(), id); | |
| 1991 } | |
| 1992 | |
| 1993 ScopedWebSocketEndpointZeroUnlockDelay:: | |
| 1994 ScopedWebSocketEndpointZeroUnlockDelay() { | |
| 1995 old_delay_ = | |
| 1996 WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting( | |
| 1997 base::TimeDelta()); | |
| 1998 } | |
| 1999 | |
| 2000 ScopedWebSocketEndpointZeroUnlockDelay:: | |
| 2001 ~ScopedWebSocketEndpointZeroUnlockDelay() { | |
| 2002 base::TimeDelta active_delay = | |
| 2003 WebSocketEndpointLockManager::GetInstance()->SetUnlockDelayForTesting( | |
| 2004 old_delay_); | |
| 2005 EXPECT_EQ(active_delay, base::TimeDelta()); | |
| 2006 } | |
| 2007 | |
| 2008 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; | |
| 2009 const int kSOCKS5GreetRequestLength = arraysize(kSOCKS5GreetRequest); | |
| 2010 | |
| 2011 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; | |
| 2012 const int kSOCKS5GreetResponseLength = arraysize(kSOCKS5GreetResponse); | |
| 2013 | |
| 2014 const char kSOCKS5OkRequest[] = | |
| 2015 { 0x05, 0x01, 0x00, 0x03, 0x04, 'h', 'o', 's', 't', 0x00, 0x50 }; | |
| 2016 const int kSOCKS5OkRequestLength = arraysize(kSOCKS5OkRequest); | |
| 2017 | |
| 2018 const char kSOCKS5OkResponse[] = | |
| 2019 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 }; | |
| 2020 const int kSOCKS5OkResponseLength = arraysize(kSOCKS5OkResponse); | |
| 2021 | |
| 2022 } // namespace net | |
| OLD | NEW |