OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/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 Loading... | |
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 |
OLD | NEW |