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

Side by Side Diff: net/socket/ssl_client_socket_unittest.cc

Issue 353713005: Implements new, more robust design for communicating between SSLConnectJobs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated SSLClientSocket tests & fixed bug in SSLSessionCacheOpenSSL Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/socket/ssl_client_socket.h" 5 #include "net/socket/ssl_client_socket.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "net/base/address_list.h" 10 #include "net/base/address_list.h"
11 #include "net/base/io_buffer.h" 11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h" 12 #include "net/base/net_errors.h"
13 #include "net/base/net_log.h" 13 #include "net/base/net_log.h"
14 #include "net/base/net_log_unittest.h" 14 #include "net/base/net_log_unittest.h"
15 #include "net/base/test_completion_callback.h" 15 #include "net/base/test_completion_callback.h"
16 #include "net/base/test_data_directory.h" 16 #include "net/base/test_data_directory.h"
17 #include "net/cert/mock_cert_verifier.h" 17 #include "net/cert/mock_cert_verifier.h"
18 #include "net/cert/test_root_certs.h" 18 #include "net/cert/test_root_certs.h"
19 #include "net/dns/host_resolver.h" 19 #include "net/dns/host_resolver.h"
20 #include "net/http/transport_security_state.h" 20 #include "net/http/transport_security_state.h"
21 #include "net/socket/client_socket_factory.h" 21 #include "net/socket/client_socket_factory.h"
22 #include "net/socket/client_socket_handle.h" 22 #include "net/socket/client_socket_handle.h"
23 #include "net/socket/socket_test_util.h" 23 #include "net/socket/socket_test_util.h"
24 #include "net/socket/tcp_client_socket.h" 24 #include "net/socket/tcp_client_socket.h"
25 #include "net/ssl/default_server_bound_cert_store.h" 25 #include "net/ssl/default_server_bound_cert_store.h"
26 #include "net/ssl/ssl_cert_request_info.h" 26 #include "net/ssl/ssl_cert_request_info.h"
27 #include "net/ssl/ssl_config_service.h" 27 #include "net/ssl/ssl_config_service.h"
28 #include "net/socket/ssl_client_socket_test_util.cc"
wtc 2014/07/31 02:02:25 Delete this line.
mshelley 2014/07/31 20:11:37 Done.
28 #include "net/test/cert_test_util.h" 29 #include "net/test/cert_test_util.h"
29 #include "net/test/spawned_test_server/spawned_test_server.h" 30 #include "net/test/spawned_test_server/spawned_test_server.h"
30 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
31 #include "testing/platform_test.h" 32 #include "testing/platform_test.h"
32 33
33 //----------------------------------------------------------------------------- 34 //-----------------------------------------------------------------------------
34 35
35 namespace net { 36 namespace net {
36 37
37 namespace { 38 namespace {
38
wtc 2014/07/31 02:02:25 Add back this blank line.
39 const SSLConfig kDefaultSSLConfig; 39 const SSLConfig kDefaultSSLConfig;
40 40
41 // WrappedStreamSocket is a base class that wraps an existing StreamSocket,
wtc 2014/07/31 02:02:25 If this big chunk of code is dead code, please del
42 // forwarding the Socket and StreamSocket interfaces to the underlying
43 // transport.
44 // This is to provide a common base class for subclasses to override specific
45 // StreamSocket methods for testing, while still communicating with a 'real'
46 // StreamSocket.
47 class WrappedStreamSocket : public StreamSocket {
48 public:
49 explicit WrappedStreamSocket(scoped_ptr<StreamSocket> transport)
50 : transport_(transport.Pass()) {}
51 virtual ~WrappedStreamSocket() {}
52
53 // StreamSocket implementation:
54 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
55 return transport_->Connect(callback);
56 }
57 virtual void Disconnect() OVERRIDE { transport_->Disconnect(); }
58 virtual bool IsConnected() const OVERRIDE {
59 return transport_->IsConnected();
60 }
61 virtual bool IsConnectedAndIdle() const OVERRIDE {
62 return transport_->IsConnectedAndIdle();
63 }
64 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE {
65 return transport_->GetPeerAddress(address);
66 }
67 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE {
68 return transport_->GetLocalAddress(address);
69 }
70 virtual const BoundNetLog& NetLog() const OVERRIDE {
71 return transport_->NetLog();
72 }
73 virtual void SetSubresourceSpeculation() OVERRIDE {
74 transport_->SetSubresourceSpeculation();
75 }
76 virtual void SetOmniboxSpeculation() OVERRIDE {
77 transport_->SetOmniboxSpeculation();
78 }
79 virtual bool WasEverUsed() const OVERRIDE {
80 return transport_->WasEverUsed();
81 }
82 virtual bool UsingTCPFastOpen() const OVERRIDE {
83 return transport_->UsingTCPFastOpen();
84 }
85 virtual bool WasNpnNegotiated() const OVERRIDE {
86 return transport_->WasNpnNegotiated();
87 }
88 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
89 return transport_->GetNegotiatedProtocol();
90 }
91 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
92 return transport_->GetSSLInfo(ssl_info);
93 }
94
95 // Socket implementation:
96 virtual int Read(IOBuffer* buf,
97 int buf_len,
98 const CompletionCallback& callback) OVERRIDE {
99 return transport_->Read(buf, buf_len, callback);
100 }
101 virtual int Write(IOBuffer* buf,
102 int buf_len,
103 const CompletionCallback& callback) OVERRIDE {
104 return transport_->Write(buf, buf_len, callback);
105 }
106 virtual int SetReceiveBufferSize(int32 size) OVERRIDE {
107 return transport_->SetReceiveBufferSize(size);
108 }
109 virtual int SetSendBufferSize(int32 size) OVERRIDE {
110 return transport_->SetSendBufferSize(size);
111 }
112
113 protected:
114 scoped_ptr<StreamSocket> transport_;
115 };
116
117 // ReadBufferingStreamSocket is a wrapper for an existing StreamSocket that
118 // will ensure a certain amount of data is internally buffered before
119 // satisfying a Read() request. It exists to mimic OS-level internal
120 // buffering, but in a way to guarantee that X number of bytes will be
121 // returned to callers of Read(), regardless of how quickly the OS receives
122 // them from the TestServer.
123 class ReadBufferingStreamSocket : public WrappedStreamSocket {
124 public:
125 explicit ReadBufferingStreamSocket(scoped_ptr<StreamSocket> transport);
126 virtual ~ReadBufferingStreamSocket() {}
127
128 // Socket implementation:
129 virtual int Read(IOBuffer* buf,
130 int buf_len,
131 const CompletionCallback& callback) OVERRIDE;
132
133 // Sets the internal buffer to |size|. This must not be greater than
134 // the largest value supplied to Read() - that is, it does not handle
135 // having "leftovers" at the end of Read().
136 // Each call to Read() will be prevented from completion until at least
137 // |size| data has been read.
138 // Set to 0 to turn off buffering, causing Read() to transparently
139 // read via the underlying transport.
140 void SetBufferSize(int size);
141
142 private:
143 enum State {
144 STATE_NONE,
145 STATE_READ,
146 STATE_READ_COMPLETE,
147 };
148
149 int DoLoop(int result);
150 int DoRead();
151 int DoReadComplete(int result);
152 void OnReadCompleted(int result);
153
154 State state_;
155 scoped_refptr<GrowableIOBuffer> read_buffer_;
156 int buffer_size_;
157
158 scoped_refptr<IOBuffer> user_read_buf_;
159 CompletionCallback user_read_callback_;
160 };
161
162 ReadBufferingStreamSocket::ReadBufferingStreamSocket(
163 scoped_ptr<StreamSocket> transport)
164 : WrappedStreamSocket(transport.Pass()),
165 read_buffer_(new GrowableIOBuffer()),
166 buffer_size_(0) {}
167
168 void ReadBufferingStreamSocket::SetBufferSize(int size) {
169 DCHECK(!user_read_buf_.get());
170 buffer_size_ = size;
171 read_buffer_->SetCapacity(size);
172 }
173
174 int ReadBufferingStreamSocket::Read(IOBuffer* buf,
175 int buf_len,
176 const CompletionCallback& callback) {
177 if (buffer_size_ == 0)
178 return transport_->Read(buf, buf_len, callback);
179
180 if (buf_len < buffer_size_)
181 return ERR_UNEXPECTED;
182
183 state_ = STATE_READ;
184 user_read_buf_ = buf;
185 int result = DoLoop(OK);
186 if (result == ERR_IO_PENDING)
187 user_read_callback_ = callback;
188 else
189 user_read_buf_ = NULL;
190 return result;
191 }
192
193 int ReadBufferingStreamSocket::DoLoop(int result) {
194 int rv = result;
195 do {
196 State current_state = state_;
197 state_ = STATE_NONE;
198 switch (current_state) {
199 case STATE_READ:
200 rv = DoRead();
201 break;
202 case STATE_READ_COMPLETE:
203 rv = DoReadComplete(rv);
204 break;
205 case STATE_NONE:
206 default:
207 NOTREACHED() << "Unexpected state: " << current_state;
208 rv = ERR_UNEXPECTED;
209 break;
210 }
211 } while (rv != ERR_IO_PENDING && state_ != STATE_NONE);
212 return rv;
213 }
214
215 int ReadBufferingStreamSocket::DoRead() {
216 state_ = STATE_READ_COMPLETE;
217 int rv =
218 transport_->Read(read_buffer_.get(),
219 read_buffer_->RemainingCapacity(),
220 base::Bind(&ReadBufferingStreamSocket::OnReadCompleted,
221 base::Unretained(this)));
222 return rv;
223 }
224
225 int ReadBufferingStreamSocket::DoReadComplete(int result) {
226 state_ = STATE_NONE;
227 if (result <= 0)
228 return result;
229
230 read_buffer_->set_offset(read_buffer_->offset() + result);
231 if (read_buffer_->RemainingCapacity() > 0) {
232 state_ = STATE_READ;
233 return OK;
234 }
235
236 memcpy(user_read_buf_->data(),
237 read_buffer_->StartOfBuffer(),
238 read_buffer_->capacity());
239 read_buffer_->set_offset(0);
240 return read_buffer_->capacity();
241 }
242
243 void ReadBufferingStreamSocket::OnReadCompleted(int result) {
244 result = DoLoop(result);
245 if (result == ERR_IO_PENDING)
246 return;
247
248 user_read_buf_ = NULL;
249 base::ResetAndReturn(&user_read_callback_).Run(result);
250 }
251
252 // Simulates synchronously receiving an error during Read() or Write()
253 class SynchronousErrorStreamSocket : public WrappedStreamSocket {
254 public:
255 explicit SynchronousErrorStreamSocket(scoped_ptr<StreamSocket> transport);
256 virtual ~SynchronousErrorStreamSocket() {}
257
258 // Socket implementation:
259 virtual int Read(IOBuffer* buf,
260 int buf_len,
261 const CompletionCallback& callback) OVERRIDE;
262 virtual int Write(IOBuffer* buf,
263 int buf_len,
264 const CompletionCallback& callback) OVERRIDE;
265
266 // Sets the next Read() call and all future calls to return |error|.
267 // If there is already a pending asynchronous read, the configured error
268 // will not be returned until that asynchronous read has completed and Read()
269 // is called again.
270 void SetNextReadError(Error error) {
271 DCHECK_GE(0, error);
272 have_read_error_ = true;
273 pending_read_error_ = error;
274 }
275
276 // Sets the next Write() call and all future calls to return |error|.
277 // If there is already a pending asynchronous write, the configured error
278 // will not be returned until that asynchronous write has completed and
279 // Write() is called again.
280 void SetNextWriteError(Error error) {
281 DCHECK_GE(0, error);
282 have_write_error_ = true;
283 pending_write_error_ = error;
284 }
285
286 private:
287 bool have_read_error_;
288 int pending_read_error_;
289
290 bool have_write_error_;
291 int pending_write_error_;
292
293 DISALLOW_COPY_AND_ASSIGN(SynchronousErrorStreamSocket);
294 };
295
296 SynchronousErrorStreamSocket::SynchronousErrorStreamSocket(
297 scoped_ptr<StreamSocket> transport)
298 : WrappedStreamSocket(transport.Pass()),
299 have_read_error_(false),
300 pending_read_error_(OK),
301 have_write_error_(false),
302 pending_write_error_(OK) {}
303
304 int SynchronousErrorStreamSocket::Read(IOBuffer* buf,
305 int buf_len,
306 const CompletionCallback& callback) {
307 if (have_read_error_)
308 return pending_read_error_;
309 return transport_->Read(buf, buf_len, callback);
310 }
311
312 int SynchronousErrorStreamSocket::Write(IOBuffer* buf,
313 int buf_len,
314 const CompletionCallback& callback) {
315 if (have_write_error_)
316 return pending_write_error_;
317 return transport_->Write(buf, buf_len, callback);
318 }
319
320 // FakeBlockingStreamSocket wraps an existing StreamSocket and simulates the
321 // underlying transport needing to complete things asynchronously in a
322 // deterministic manner (e.g.: independent of the TestServer and the OS's
323 // semantics).
324 class FakeBlockingStreamSocket : public WrappedStreamSocket {
325 public:
326 explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport);
327 virtual ~FakeBlockingStreamSocket() {}
328
329 // Socket implementation:
330 virtual int Read(IOBuffer* buf,
331 int buf_len,
332 const CompletionCallback& callback) OVERRIDE;
333 virtual int Write(IOBuffer* buf,
334 int buf_len,
335 const CompletionCallback& callback) OVERRIDE;
336
337 // Blocks read results on the socket. Reads will not complete until
338 // UnblockReadResult() has been called and a result is ready from the
339 // underlying transport. Note: if BlockReadResult() is called while there is a
340 // hanging asynchronous Read(), that Read is blocked.
341 void BlockReadResult();
342 void UnblockReadResult();
343
344 // Waits for the blocked Read() call to be complete at the underlying
345 // transport.
346 void WaitForReadResult();
347
348 // Causes the next call to Write() to return ERR_IO_PENDING, not beginning the
349 // underlying transport until UnblockWrite() has been called. Note: if there
350 // is a pending asynchronous write, it is NOT blocked. For purposes of
351 // blocking writes, data is considered to have reached the underlying
352 // transport as soon as Write() is called.
353 void BlockWrite();
354 void UnblockWrite();
355
356 // Waits for the blocked Write() call to be scheduled.
357 void WaitForWrite();
358
359 private:
360 // Handles completion from the underlying transport read.
361 void OnReadCompleted(int result);
362
363 // True if read callbacks are blocked.
364 bool should_block_read_;
365
366 // The user callback for the pending read call.
367 CompletionCallback pending_read_callback_;
368
369 // The result for the blocked read callback, or ERR_IO_PENDING if not
370 // completed.
371 int pending_read_result_;
372
373 // WaitForReadResult() wait loop.
374 scoped_ptr<base::RunLoop> read_loop_;
375
376 // True if write calls are blocked.
377 bool should_block_write_;
378
379 // The buffer for the pending write, or NULL if not scheduled.
380 scoped_refptr<IOBuffer> pending_write_buf_;
381
382 // The callback for the pending write call.
383 CompletionCallback pending_write_callback_;
384
385 // The length for the pending write, or -1 if not scheduled.
386 int pending_write_len_;
387
388 // WaitForWrite() wait loop.
389 scoped_ptr<base::RunLoop> write_loop_;
390 };
391
392 FakeBlockingStreamSocket::FakeBlockingStreamSocket(
393 scoped_ptr<StreamSocket> transport)
394 : WrappedStreamSocket(transport.Pass()),
395 should_block_read_(false),
396 pending_read_result_(ERR_IO_PENDING),
397 should_block_write_(false),
398 pending_write_len_(-1) {}
399
400 int FakeBlockingStreamSocket::Read(IOBuffer* buf,
401 int len,
402 const CompletionCallback& callback) {
403 DCHECK(pending_read_callback_.is_null());
404 DCHECK_EQ(ERR_IO_PENDING, pending_read_result_);
405 DCHECK(!callback.is_null());
406
407 int rv = transport_->Read(buf, len, base::Bind(
408 &FakeBlockingStreamSocket::OnReadCompleted, base::Unretained(this)));
409 if (rv == ERR_IO_PENDING) {
410 // Save the callback to be called later.
411 pending_read_callback_ = callback;
412 } else if (should_block_read_) {
413 // Save the callback and read result to be called later.
414 pending_read_callback_ = callback;
415 OnReadCompleted(rv);
416 rv = ERR_IO_PENDING;
417 }
418 return rv;
419 }
420
421 int FakeBlockingStreamSocket::Write(IOBuffer* buf,
422 int len,
423 const CompletionCallback& callback) {
424 DCHECK(buf);
425 DCHECK_LE(0, len);
426
427 if (!should_block_write_)
428 return transport_->Write(buf, len, callback);
429
430 // Schedule the write, but do nothing.
431 DCHECK(!pending_write_buf_);
432 DCHECK_EQ(-1, pending_write_len_);
433 DCHECK(pending_write_callback_.is_null());
434 DCHECK(!callback.is_null());
435 pending_write_buf_ = buf;
436 pending_write_len_ = len;
437 pending_write_callback_ = callback;
438
439 // Stop the write loop, if any.
440 if (write_loop_)
441 write_loop_->Quit();
442 return ERR_IO_PENDING;
443 }
444
445 void FakeBlockingStreamSocket::BlockReadResult() {
446 DCHECK(!should_block_read_);
447 should_block_read_ = true;
448 }
449
450 void FakeBlockingStreamSocket::UnblockReadResult() {
451 DCHECK(should_block_read_);
452 should_block_read_ = false;
453
454 // If the operation is still pending in the underlying transport, immediately
455 // return - OnReadCompleted() will handle invoking the callback once the
456 // transport has completed.
457 if (pending_read_result_ == ERR_IO_PENDING)
458 return;
459 int result = pending_read_result_;
460 pending_read_result_ = ERR_IO_PENDING;
461 base::ResetAndReturn(&pending_read_callback_).Run(result);
462 }
463
464 void FakeBlockingStreamSocket::WaitForReadResult() {
465 DCHECK(should_block_read_);
466 DCHECK(!read_loop_);
467
468 if (pending_read_result_ != ERR_IO_PENDING)
469 return;
470 read_loop_.reset(new base::RunLoop);
471 read_loop_->Run();
472 read_loop_.reset();
473 DCHECK_NE(ERR_IO_PENDING, pending_read_result_);
474 }
475
476 void FakeBlockingStreamSocket::BlockWrite() {
477 DCHECK(!should_block_write_);
478 should_block_write_ = true;
479 }
480
481 void FakeBlockingStreamSocket::UnblockWrite() {
482 DCHECK(should_block_write_);
483 should_block_write_ = false;
484
485 // Do nothing if UnblockWrite() was called after BlockWrite(),
486 // without a Write() in between.
487 if (!pending_write_buf_)
488 return;
489
490 int rv = transport_->Write(pending_write_buf_, pending_write_len_,
491 pending_write_callback_);
492 pending_write_buf_ = NULL;
493 pending_write_len_ = -1;
494 if (rv == ERR_IO_PENDING) {
495 pending_write_callback_.Reset();
496 } else {
497 base::ResetAndReturn(&pending_write_callback_).Run(rv);
498 }
499 }
500
501 void FakeBlockingStreamSocket::WaitForWrite() {
502 DCHECK(should_block_write_);
503 DCHECK(!write_loop_);
504
505 if (pending_write_buf_)
506 return;
507 write_loop_.reset(new base::RunLoop);
508 write_loop_->Run();
509 write_loop_.reset();
510 DCHECK(pending_write_buf_);
511 }
512
513 void FakeBlockingStreamSocket::OnReadCompleted(int result) {
514 DCHECK_EQ(ERR_IO_PENDING, pending_read_result_);
515 DCHECK(!pending_read_callback_.is_null());
516
517 if (should_block_read_) {
518 // Store the result so that the callback can be invoked once Unblock() is
519 // called.
520 pending_read_result_ = result;
521
522 // Stop the WaitForReadResult() call if any.
523 if (read_loop_)
524 read_loop_->Quit();
525 } else {
526 // Either the Read() was never blocked or UnblockReadResult() was called
527 // before the Read() completed. Either way, run the callback.
528 base::ResetAndReturn(&pending_read_callback_).Run(result);
529 }
530 }
531
532 // CompletionCallback that will delete the associated StreamSocket when 41 // CompletionCallback that will delete the associated StreamSocket when
533 // the callback is invoked. 42 // the callback is invoked.
534 class DeleteSocketCallback : public TestCompletionCallbackBase { 43 class DeleteSocketCallback : public TestCompletionCallbackBase {
535 public: 44 public:
536 explicit DeleteSocketCallback(StreamSocket* socket) 45 explicit DeleteSocketCallback(StreamSocket* socket)
537 : socket_(socket), 46 : socket_(socket),
538 callback_(base::Bind(&DeleteSocketCallback::OnComplete, 47 callback_(base::Bind(&DeleteSocketCallback::OnComplete,
539 base::Unretained(this))) {} 48 base::Unretained(this))) {}
540 virtual ~DeleteSocketCallback() {} 49 virtual ~DeleteSocketCallback() {}
541 50
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 2028
2520 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2029 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2521 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2030 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2522 // error codes for now. 2031 // error codes for now.
2523 // http://crbug.com/373670 2032 // http://crbug.com/373670
2524 EXPECT_NE(OK, rv); 2033 EXPECT_NE(OK, rv);
2525 EXPECT_FALSE(sock_->IsConnected()); 2034 EXPECT_FALSE(sock_->IsConnected());
2526 } 2035 }
2527 2036
2528 } // namespace net 2037 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698