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