OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // TODO(ukai): code is similar with http_network_transaction.cc. We should | 5 // TODO(ukai): code is similar with http_network_transaction.cc. We should |
6 // think about ways to share code, if possible. | 6 // think about ways to share code, if possible. |
7 | 7 |
8 #include "net/socket_stream/socket_stream.h" | 8 #include "net/socket_stream/socket_stream.h" |
9 | 9 |
10 #include <set> | 10 #include <set> |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 ALLOW_THIS_IN_INITIALIZER_LIST( | 59 ALLOW_THIS_IN_INITIALIZER_LIST( |
60 read_callback_(this, &SocketStream::OnReadCompleted)), | 60 read_callback_(this, &SocketStream::OnReadCompleted)), |
61 ALLOW_THIS_IN_INITIALIZER_LIST( | 61 ALLOW_THIS_IN_INITIALIZER_LIST( |
62 write_callback_(this, &SocketStream::OnWriteCompleted)), | 62 write_callback_(this, &SocketStream::OnWriteCompleted)), |
63 read_buf_(NULL), | 63 read_buf_(NULL), |
64 write_buf_(NULL), | 64 write_buf_(NULL), |
65 current_write_buf_(NULL), | 65 current_write_buf_(NULL), |
66 write_buf_offset_(0), | 66 write_buf_offset_(0), |
67 write_buf_size_(0), | 67 write_buf_size_(0), |
68 closing_(false), | 68 closing_(false), |
| 69 server_closed_(false), |
69 metrics_(new SocketStreamMetrics(url)) { | 70 metrics_(new SocketStreamMetrics(url)) { |
70 DCHECK(MessageLoop::current()) << | 71 DCHECK(MessageLoop::current()) << |
71 "The current MessageLoop must exist"; | 72 "The current MessageLoop must exist"; |
72 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 73 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
73 "The current MessageLoop must be TYPE_IO"; | 74 "The current MessageLoop must be TYPE_IO"; |
74 DCHECK(delegate_); | 75 DCHECK(delegate_); |
75 } | 76 } |
76 | 77 |
77 SocketStream::~SocketStream() { | 78 SocketStream::~SocketStream() { |
78 set_context(NULL); | 79 set_context(NULL); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 DCHECK(MessageLoop::current()) << | 182 DCHECK(MessageLoop::current()) << |
182 "The current MessageLoop must exist"; | 183 "The current MessageLoop must exist"; |
183 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 184 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
184 "The current MessageLoop must be TYPE_IO"; | 185 "The current MessageLoop must be TYPE_IO"; |
185 // If next_state_ is STATE_NONE, the socket was not opened, or already | 186 // If next_state_ is STATE_NONE, the socket was not opened, or already |
186 // closed. So, return immediately. | 187 // closed. So, return immediately. |
187 // Otherwise, it might call Finish() more than once, so breaks balance | 188 // Otherwise, it might call Finish() more than once, so breaks balance |
188 // of AddRef() and Release() in Connect() and Finish(), respectively. | 189 // of AddRef() and Release() in Connect() and Finish(), respectively. |
189 if (next_state_ == STATE_NONE) | 190 if (next_state_ == STATE_NONE) |
190 return; | 191 return; |
191 closing_ = true; | |
192 // Close asynchronously, so that delegate won't be called | |
193 // back before returning Close(). | |
194 MessageLoop::current()->PostTask( | 192 MessageLoop::current()->PostTask( |
195 FROM_HERE, | 193 FROM_HERE, |
196 NewRunnableMethod(this, &SocketStream::DoLoop, OK)); | 194 NewRunnableMethod(this, &SocketStream::DoClose)); |
| 195 } |
| 196 |
| 197 void SocketStream::DoClose() { |
| 198 closing_ = true; |
| 199 // If next_state_ is STATE_TCP_CONNECT, it's waiting other socket establishing |
| 200 // connection. If next_state_ is STATE_AUTH_REQUIRED, it's waiting for |
| 201 // restarting. In these states, we'll close the SocketStream now. |
| 202 if (next_state_ == STATE_TCP_CONNECT || next_state_ == STATE_AUTH_REQUIRED) { |
| 203 DoLoop(ERR_ABORTED); |
| 204 return; |
| 205 } |
| 206 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close |
| 207 // the SocketStream. |
| 208 // If it's writing now, we should defer the closing after the current |
| 209 // writing is completed. |
| 210 if (next_state_ == STATE_READ_WRITE && !current_write_buf_) |
| 211 DoLoop(ERR_ABORTED); |
| 212 |
| 213 // In other next_state_, we'll wait for callback of other APIs, such as |
| 214 // ResolveProxy(). |
197 } | 215 } |
198 | 216 |
199 void SocketStream::RestartWithAuth( | 217 void SocketStream::RestartWithAuth( |
200 const string16& username, const string16& password) { | 218 const string16& username, const string16& password) { |
201 DCHECK(MessageLoop::current()) << | 219 DCHECK(MessageLoop::current()) << |
202 "The current MessageLoop must exist"; | 220 "The current MessageLoop must exist"; |
203 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 221 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
204 "The current MessageLoop must be TYPE_IO"; | 222 "The current MessageLoop must be TYPE_IO"; |
205 DCHECK(auth_handler_.get()); | 223 DCHECK(auth_handler_.get()); |
206 if (!socket_.get()) { | 224 if (!socket_.get()) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 return OK; | 341 return OK; |
324 } | 342 } |
325 | 343 |
326 void SocketStream::OnIOCompleted(int result) { | 344 void SocketStream::OnIOCompleted(int result) { |
327 DoLoop(result); | 345 DoLoop(result); |
328 } | 346 } |
329 | 347 |
330 void SocketStream::OnReadCompleted(int result) { | 348 void SocketStream::OnReadCompleted(int result) { |
331 if (result == 0) { | 349 if (result == 0) { |
332 // 0 indicates end-of-file, so socket was closed. | 350 // 0 indicates end-of-file, so socket was closed. |
333 next_state_ = STATE_CLOSE; | 351 // Don't close the socket if it's still writing. |
| 352 server_closed_ = true; |
334 } else if (result > 0 && read_buf_) { | 353 } else if (result > 0 && read_buf_) { |
335 result = DidReceiveData(result); | 354 result = DidReceiveData(result); |
336 } | 355 } |
337 DoLoop(result); | 356 DoLoop(result); |
338 } | 357 } |
339 | 358 |
340 void SocketStream::OnWriteCompleted(int result) { | 359 void SocketStream::OnWriteCompleted(int result) { |
341 if (result >= 0 && write_buf_) { | 360 if (result >= 0 && write_buf_) { |
342 result = DidSendData(result); | 361 result = DidSendData(result); |
343 } | 362 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 case STATE_SSL_CONNECT: | 420 case STATE_SSL_CONNECT: |
402 DCHECK_EQ(OK, result); | 421 DCHECK_EQ(OK, result); |
403 result = DoSSLConnect(); | 422 result = DoSSLConnect(); |
404 break; | 423 break; |
405 case STATE_SSL_CONNECT_COMPLETE: | 424 case STATE_SSL_CONNECT_COMPLETE: |
406 result = DoSSLConnectComplete(result); | 425 result = DoSSLConnectComplete(result); |
407 break; | 426 break; |
408 case STATE_READ_WRITE: | 427 case STATE_READ_WRITE: |
409 result = DoReadWrite(result); | 428 result = DoReadWrite(result); |
410 break; | 429 break; |
| 430 case STATE_AUTH_REQUIRED: |
| 431 NOTREACHED() << "Should not run DoLoop in STATE_AUTH_REQUIRED state."; |
| 432 Finish(result); |
| 433 return; |
411 case STATE_CLOSE: | 434 case STATE_CLOSE: |
412 DCHECK_LE(result, OK); | 435 DCHECK_LE(result, OK); |
413 Finish(result); | 436 Finish(result); |
414 return; | 437 return; |
415 default: | 438 default: |
416 NOTREACHED() << "bad state"; | 439 NOTREACHED() << "bad state " << state; |
417 Finish(result); | 440 Finish(result); |
418 return; | 441 return; |
419 } | 442 } |
420 // If the connection is not established yet and had actual errors, | 443 // If the connection is not established yet and had actual errors, |
421 // close the connection. | 444 // close the connection. |
422 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { | 445 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { |
423 DCHECK_EQ(next_state_, STATE_CLOSE); | 446 DCHECK_EQ(next_state_, STATE_CLOSE); |
424 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, | 447 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, |
425 new NetLogIntegerParameter("net_error", result)); | 448 new NetLogIntegerParameter("net_error", result)); |
426 } | 449 } |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 // let's close the socket. | 857 // let's close the socket. |
835 // We don't care about receiving data after the socket is closed. | 858 // We don't care about receiving data after the socket is closed. |
836 if (closing_ && !write_buf_ && pending_write_bufs_.empty()) { | 859 if (closing_ && !write_buf_ && pending_write_bufs_.empty()) { |
837 socket_->Disconnect(); | 860 socket_->Disconnect(); |
838 next_state_ = STATE_CLOSE; | 861 next_state_ = STATE_CLOSE; |
839 return OK; | 862 return OK; |
840 } | 863 } |
841 | 864 |
842 next_state_ = STATE_READ_WRITE; | 865 next_state_ = STATE_READ_WRITE; |
843 | 866 |
844 if (!read_buf_) { | 867 // If server already closed the socket, we don't try to read. |
845 // No read pending. | 868 if (!server_closed_) { |
846 read_buf_ = new IOBuffer(kReadBufferSize); | 869 if (!read_buf_) { |
847 result = socket_->Read(read_buf_, kReadBufferSize, &read_callback_); | 870 // No read pending and server didn't close the socket. |
848 if (result > 0) { | 871 read_buf_ = new IOBuffer(kReadBufferSize); |
849 return DidReceiveData(result); | 872 result = socket_->Read(read_buf_, kReadBufferSize, &read_callback_); |
850 } else if (result == 0) { | 873 if (result > 0) { |
851 // 0 indicates end-of-file, so socket was closed. | 874 return DidReceiveData(result); |
852 next_state_ = STATE_CLOSE; | 875 } else if (result == 0) { |
853 return ERR_CONNECTION_CLOSED; | 876 // 0 indicates end-of-file, so socket was closed. |
| 877 next_state_ = STATE_CLOSE; |
| 878 server_closed_ = true; |
| 879 return ERR_CONNECTION_CLOSED; |
| 880 } |
| 881 // If read is pending, try write as well. |
| 882 // Otherwise, return the result and do next loop (to close the |
| 883 // connection). |
| 884 if (result != ERR_IO_PENDING) { |
| 885 next_state_ = STATE_CLOSE; |
| 886 server_closed_ = true; |
| 887 return result; |
| 888 } |
854 } | 889 } |
855 // If read is pending, try write as well. | 890 // Read is pending. |
856 // Otherwise, return the result and do next loop (to close the connection). | 891 DCHECK(read_buf_); |
857 if (result != ERR_IO_PENDING) { | |
858 next_state_ = STATE_CLOSE; | |
859 return result; | |
860 } | |
861 } | 892 } |
862 // Read is pending. | |
863 DCHECK(read_buf_); | |
864 | 893 |
865 if (write_buf_ && !current_write_buf_) { | 894 if (write_buf_ && !current_write_buf_) { |
866 // No write pending. | 895 // No write pending. |
867 current_write_buf_ = new DrainableIOBuffer(write_buf_, write_buf_size_); | 896 current_write_buf_ = new DrainableIOBuffer(write_buf_, write_buf_size_); |
868 current_write_buf_->SetOffset(write_buf_offset_); | 897 current_write_buf_->SetOffset(write_buf_offset_); |
869 result = socket_->Write(current_write_buf_, | 898 result = socket_->Write(current_write_buf_, |
870 current_write_buf_->BytesRemaining(), | 899 current_write_buf_->BytesRemaining(), |
871 &write_callback_); | 900 &write_callback_); |
872 if (result > 0) { | 901 if (result > 0) { |
873 return DidSendData(result); | 902 return DidSendData(result); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 | 1015 |
987 SSLConfigService* SocketStream::ssl_config_service() const { | 1016 SSLConfigService* SocketStream::ssl_config_service() const { |
988 return context_->ssl_config_service(); | 1017 return context_->ssl_config_service(); |
989 } | 1018 } |
990 | 1019 |
991 ProxyService* SocketStream::proxy_service() const { | 1020 ProxyService* SocketStream::proxy_service() const { |
992 return context_->proxy_service(); | 1021 return context_->proxy_service(); |
993 } | 1022 } |
994 | 1023 |
995 } // namespace net | 1024 } // namespace net |
OLD | NEW |