| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 21 matching lines...) Expand all Loading... |
| 32 #include "net/socket/tcp_client_socket.h" | 32 #include "net/socket/tcp_client_socket.h" |
| 33 #include "net/socket_stream/socket_stream_metrics.h" | 33 #include "net/socket_stream/socket_stream_metrics.h" |
| 34 #include "net/url_request/url_request.h" | 34 #include "net/url_request/url_request.h" |
| 35 | 35 |
| 36 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. | 36 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. |
| 37 static const int kReadBufferSize = 4096; | 37 static const int kReadBufferSize = 4096; |
| 38 | 38 |
| 39 namespace net { | 39 namespace net { |
| 40 | 40 |
| 41 SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {} | 41 SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {} |
| 42 SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; } | |
| 43 | 42 |
| 44 void SocketStream::ResponseHeaders::Realloc(size_t new_size) { | 43 void SocketStream::ResponseHeaders::Realloc(size_t new_size) { |
| 45 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size))); | 44 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size))); |
| 46 } | 45 } |
| 47 | 46 |
| 47 SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; } |
| 48 |
| 48 SocketStream::SocketStream(const GURL& url, Delegate* delegate) | 49 SocketStream::SocketStream(const GURL& url, Delegate* delegate) |
| 49 : delegate_(delegate), | 50 : delegate_(delegate), |
| 50 url_(url), | 51 url_(url), |
| 51 max_pending_send_allowed_(kMaxPendingSendAllowed), | 52 max_pending_send_allowed_(kMaxPendingSendAllowed), |
| 52 next_state_(STATE_NONE), | 53 next_state_(STATE_NONE), |
| 53 host_resolver_(NULL), | 54 host_resolver_(NULL), |
| 54 cert_verifier_(NULL), | 55 cert_verifier_(NULL), |
| 55 http_auth_handler_factory_(NULL), | 56 http_auth_handler_factory_(NULL), |
| 56 factory_(ClientSocketFactory::GetDefaultFactory()), | 57 factory_(ClientSocketFactory::GetDefaultFactory()), |
| 57 proxy_mode_(kDirectConnection), | 58 proxy_mode_(kDirectConnection), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 71 closing_(false), | 72 closing_(false), |
| 72 server_closed_(false), | 73 server_closed_(false), |
| 73 metrics_(new SocketStreamMetrics(url)) { | 74 metrics_(new SocketStreamMetrics(url)) { |
| 74 DCHECK(MessageLoop::current()) << | 75 DCHECK(MessageLoop::current()) << |
| 75 "The current MessageLoop must exist"; | 76 "The current MessageLoop must exist"; |
| 76 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 77 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
| 77 "The current MessageLoop must be TYPE_IO"; | 78 "The current MessageLoop must be TYPE_IO"; |
| 78 DCHECK(delegate_); | 79 DCHECK(delegate_); |
| 79 } | 80 } |
| 80 | 81 |
| 81 SocketStream::~SocketStream() { | |
| 82 set_context(NULL); | |
| 83 DCHECK(!delegate_); | |
| 84 DCHECK(!pac_request_); | |
| 85 } | |
| 86 | |
| 87 SocketStream::UserData* SocketStream::GetUserData( | 82 SocketStream::UserData* SocketStream::GetUserData( |
| 88 const void* key) const { | 83 const void* key) const { |
| 89 UserDataMap::const_iterator found = user_data_.find(key); | 84 UserDataMap::const_iterator found = user_data_.find(key); |
| 90 if (found != user_data_.end()) | 85 if (found != user_data_.end()) |
| 91 return found->second.get(); | 86 return found->second.get(); |
| 92 return NULL; | 87 return NULL; |
| 93 } | 88 } |
| 94 | 89 |
| 95 void SocketStream::SetUserData(const void* key, UserData* data) { | 90 void SocketStream::SetUserData(const void* key, UserData* data) { |
| 96 user_data_[key] = linked_ptr<UserData>(data); | 91 user_data_[key] = linked_ptr<UserData>(data); |
| 97 } | 92 } |
| 98 | 93 |
| 94 bool SocketStream::is_secure() const { |
| 95 return url_.SchemeIs("wss"); |
| 96 } |
| 97 |
| 99 void SocketStream::set_context(URLRequestContext* context) { | 98 void SocketStream::set_context(URLRequestContext* context) { |
| 100 scoped_refptr<URLRequestContext> prev_context = context_; | 99 scoped_refptr<URLRequestContext> prev_context = context_; |
| 101 | 100 |
| 102 context_ = context; | 101 context_ = context; |
| 103 | 102 |
| 104 if (prev_context != context) { | 103 if (prev_context != context) { |
| 105 if (prev_context && pac_request_) { | 104 if (prev_context && pac_request_) { |
| 106 prev_context->proxy_service()->CancelPacRequest(pac_request_); | 105 prev_context->proxy_service()->CancelPacRequest(pac_request_); |
| 107 pac_request_ = NULL; | 106 pac_request_ = NULL; |
| 108 } | 107 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 // closed. So, return immediately. | 192 // closed. So, return immediately. |
| 194 // Otherwise, it might call Finish() more than once, so breaks balance | 193 // Otherwise, it might call Finish() more than once, so breaks balance |
| 195 // of AddRef() and Release() in Connect() and Finish(), respectively. | 194 // of AddRef() and Release() in Connect() and Finish(), respectively. |
| 196 if (next_state_ == STATE_NONE) | 195 if (next_state_ == STATE_NONE) |
| 197 return; | 196 return; |
| 198 MessageLoop::current()->PostTask( | 197 MessageLoop::current()->PostTask( |
| 199 FROM_HERE, | 198 FROM_HERE, |
| 200 NewRunnableMethod(this, &SocketStream::DoClose)); | 199 NewRunnableMethod(this, &SocketStream::DoClose)); |
| 201 } | 200 } |
| 202 | 201 |
| 203 void SocketStream::DoClose() { | |
| 204 closing_ = true; | |
| 205 // If next_state_ is STATE_TCP_CONNECT, it's waiting other socket establishing | |
| 206 // connection. If next_state_ is STATE_AUTH_REQUIRED, it's waiting for | |
| 207 // restarting. In these states, we'll close the SocketStream now. | |
| 208 if (next_state_ == STATE_TCP_CONNECT || next_state_ == STATE_AUTH_REQUIRED) { | |
| 209 DoLoop(ERR_ABORTED); | |
| 210 return; | |
| 211 } | |
| 212 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close | |
| 213 // the SocketStream. | |
| 214 // If it's writing now, we should defer the closing after the current | |
| 215 // writing is completed. | |
| 216 if (next_state_ == STATE_READ_WRITE && !current_write_buf_) | |
| 217 DoLoop(ERR_ABORTED); | |
| 218 | |
| 219 // In other next_state_, we'll wait for callback of other APIs, such as | |
| 220 // ResolveProxy(). | |
| 221 } | |
| 222 | |
| 223 void SocketStream::RestartWithAuth( | 202 void SocketStream::RestartWithAuth( |
| 224 const string16& username, const string16& password) { | 203 const string16& username, const string16& password) { |
| 225 DCHECK(MessageLoop::current()) << | 204 DCHECK(MessageLoop::current()) << |
| 226 "The current MessageLoop must exist"; | 205 "The current MessageLoop must exist"; |
| 227 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 206 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
| 228 "The current MessageLoop must be TYPE_IO"; | 207 "The current MessageLoop must be TYPE_IO"; |
| 229 DCHECK(auth_handler_.get()); | 208 DCHECK(auth_handler_.get()); |
| 230 if (!socket_.get()) { | 209 if (!socket_.get()) { |
| 231 LOG(ERROR) << "Socket is closed before restarting with auth."; | 210 LOG(ERROR) << "Socket is closed before restarting with auth."; |
| 232 return; | 211 return; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 248 void SocketStream::DetachDelegate() { | 227 void SocketStream::DetachDelegate() { |
| 249 if (!delegate_) | 228 if (!delegate_) |
| 250 return; | 229 return; |
| 251 delegate_ = NULL; | 230 delegate_ = NULL; |
| 252 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 231 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
| 253 // We don't need to send pending data when client detach the delegate. | 232 // We don't need to send pending data when client detach the delegate. |
| 254 pending_write_bufs_.clear(); | 233 pending_write_bufs_.clear(); |
| 255 Close(); | 234 Close(); |
| 256 } | 235 } |
| 257 | 236 |
| 237 void SocketStream::SetHostResolver(HostResolver* host_resolver) { |
| 238 DCHECK(host_resolver); |
| 239 host_resolver_ = host_resolver; |
| 240 } |
| 241 |
| 242 void SocketStream::SetClientSocketFactory( |
| 243 ClientSocketFactory* factory) { |
| 244 DCHECK(factory); |
| 245 factory_ = factory; |
| 246 } |
| 247 |
| 248 SocketStream::~SocketStream() { |
| 249 set_context(NULL); |
| 250 DCHECK(!delegate_); |
| 251 DCHECK(!pac_request_); |
| 252 } |
| 253 |
| 254 void SocketStream::CopyAddrInfo(struct addrinfo* head) { |
| 255 addresses_.Copy(head, true); |
| 256 } |
| 257 |
| 258 void SocketStream::DoClose() { |
| 259 closing_ = true; |
| 260 // If next_state_ is STATE_TCP_CONNECT, it's waiting other socket establishing |
| 261 // connection. If next_state_ is STATE_AUTH_REQUIRED, it's waiting for |
| 262 // restarting. In these states, we'll close the SocketStream now. |
| 263 if (next_state_ == STATE_TCP_CONNECT || next_state_ == STATE_AUTH_REQUIRED) { |
| 264 DoLoop(ERR_ABORTED); |
| 265 return; |
| 266 } |
| 267 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close |
| 268 // the SocketStream. |
| 269 // If it's writing now, we should defer the closing after the current |
| 270 // writing is completed. |
| 271 if (next_state_ == STATE_READ_WRITE && !current_write_buf_) |
| 272 DoLoop(ERR_ABORTED); |
| 273 |
| 274 // In other next_state_, we'll wait for callback of other APIs, such as |
| 275 // ResolveProxy(). |
| 276 } |
| 277 |
| 258 void SocketStream::Finish(int result) { | 278 void SocketStream::Finish(int result) { |
| 259 DCHECK(MessageLoop::current()) << | 279 DCHECK(MessageLoop::current()) << |
| 260 "The current MessageLoop must exist"; | 280 "The current MessageLoop must exist"; |
| 261 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 281 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
| 262 "The current MessageLoop must be TYPE_IO"; | 282 "The current MessageLoop must be TYPE_IO"; |
| 263 DCHECK_LE(result, OK); | 283 DCHECK_LE(result, OK); |
| 264 if (result == OK) | 284 if (result == OK) |
| 265 result = ERR_CONNECTION_CLOSED; | 285 result = ERR_CONNECTION_CLOSED; |
| 266 DCHECK_EQ(next_state_, STATE_NONE); | 286 DCHECK_EQ(next_state_, STATE_NONE); |
| 267 DVLOG(1) << "Finish result=" << ErrorToString(result); | 287 DVLOG(1) << "Finish result=" << ErrorToString(result); |
| 268 if (delegate_) | 288 if (delegate_) |
| 269 delegate_->OnError(this, result); | 289 delegate_->OnError(this, result); |
| 270 | 290 |
| 271 metrics_->OnClose(); | 291 metrics_->OnClose(); |
| 272 Delegate* delegate = delegate_; | 292 Delegate* delegate = delegate_; |
| 273 delegate_ = NULL; | 293 delegate_ = NULL; |
| 274 if (delegate) { | 294 if (delegate) { |
| 275 delegate->OnClose(this); | 295 delegate->OnClose(this); |
| 276 } | 296 } |
| 277 Release(); | 297 Release(); |
| 278 } | 298 } |
| 279 | 299 |
| 280 void SocketStream::SetHostResolver(HostResolver* host_resolver) { | |
| 281 DCHECK(host_resolver); | |
| 282 host_resolver_ = host_resolver; | |
| 283 } | |
| 284 | |
| 285 void SocketStream::SetClientSocketFactory( | |
| 286 ClientSocketFactory* factory) { | |
| 287 DCHECK(factory); | |
| 288 factory_ = factory; | |
| 289 } | |
| 290 | |
| 291 void SocketStream::CopyAddrInfo(struct addrinfo* head) { | |
| 292 addresses_.Copy(head, true); | |
| 293 } | |
| 294 | |
| 295 int SocketStream::DidEstablishConnection() { | 300 int SocketStream::DidEstablishConnection() { |
| 296 if (!socket_.get() || !socket_->IsConnected()) { | 301 if (!socket_.get() || !socket_->IsConnected()) { |
| 297 next_state_ = STATE_CLOSE; | 302 next_state_ = STATE_CLOSE; |
| 298 return ERR_CONNECTION_FAILED; | 303 return ERR_CONNECTION_FAILED; |
| 299 } | 304 } |
| 300 next_state_ = STATE_READ_WRITE; | 305 next_state_ = STATE_READ_WRITE; |
| 301 metrics_->OnConnected(); | 306 metrics_->OnConnected(); |
| 302 | 307 |
| 303 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); | 308 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT, NULL); |
| 304 if (delegate_) | 309 if (delegate_) |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 case ERR_CERT_DATE_INVALID: | 1021 case ERR_CERT_DATE_INVALID: |
| 1017 case ERR_CERT_AUTHORITY_INVALID: | 1022 case ERR_CERT_AUTHORITY_INVALID: |
| 1018 result = OK; | 1023 result = OK; |
| 1019 break; | 1024 break; |
| 1020 default: | 1025 default: |
| 1021 break; | 1026 break; |
| 1022 } | 1027 } |
| 1023 return result; | 1028 return result; |
| 1024 } | 1029 } |
| 1025 | 1030 |
| 1026 bool SocketStream::is_secure() const { | |
| 1027 return url_.SchemeIs("wss"); | |
| 1028 } | |
| 1029 | |
| 1030 SSLConfigService* SocketStream::ssl_config_service() const { | 1031 SSLConfigService* SocketStream::ssl_config_service() const { |
| 1031 return context_->ssl_config_service(); | 1032 return context_->ssl_config_service(); |
| 1032 } | 1033 } |
| 1033 | 1034 |
| 1034 ProxyService* SocketStream::proxy_service() const { | 1035 ProxyService* SocketStream::proxy_service() const { |
| 1035 return context_->proxy_service(); | 1036 return context_->proxy_service(); |
| 1036 } | 1037 } |
| 1037 | 1038 |
| 1038 } // namespace net | 1039 } // namespace net |
| OLD | NEW |