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 <string> | 10 #include <string> |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 ALLOW_THIS_IN_INITIALIZER_LIST( | 55 ALLOW_THIS_IN_INITIALIZER_LIST( |
56 write_callback_(this, &SocketStream::OnWriteCompleted)), | 56 write_callback_(this, &SocketStream::OnWriteCompleted)), |
57 read_buf_(NULL), | 57 read_buf_(NULL), |
58 write_buf_(NULL), | 58 write_buf_(NULL), |
59 current_write_buf_(NULL), | 59 current_write_buf_(NULL), |
60 write_buf_offset_(0), | 60 write_buf_offset_(0), |
61 write_buf_size_(0), | 61 write_buf_size_(0), |
62 throttle_( | 62 throttle_( |
63 SocketStreamThrottle::GetSocketStreamThrottleForScheme( | 63 SocketStreamThrottle::GetSocketStreamThrottleForScheme( |
64 url.scheme())), | 64 url.scheme())), |
65 metrics_(new SocketStreamMetrics(url)), | 65 metrics_(new SocketStreamMetrics(url)) { |
66 ALLOW_THIS_IN_INITIALIZER_LIST( | |
67 request_tracker_node_(this)) { | |
68 DCHECK(MessageLoop::current()) << | 66 DCHECK(MessageLoop::current()) << |
69 "The current MessageLoop must exist"; | 67 "The current MessageLoop must exist"; |
70 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 68 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
71 "The current MessageLoop must be TYPE_IO"; | 69 "The current MessageLoop must be TYPE_IO"; |
72 DCHECK(delegate_); | 70 DCHECK(delegate_); |
73 DCHECK(throttle_); | 71 DCHECK(throttle_); |
74 } | 72 } |
75 | 73 |
76 SocketStream::~SocketStream() { | 74 SocketStream::~SocketStream() { |
77 set_context(NULL); | 75 set_context(NULL); |
(...skipping 11 matching lines...) Expand all Loading... |
89 void SocketStream::SetUserData(const void* key, UserData* data) { | 87 void SocketStream::SetUserData(const void* key, UserData* data) { |
90 user_data_[key] = linked_ptr<UserData>(data); | 88 user_data_[key] = linked_ptr<UserData>(data); |
91 } | 89 } |
92 | 90 |
93 void SocketStream::set_context(URLRequestContext* context) { | 91 void SocketStream::set_context(URLRequestContext* context) { |
94 scoped_refptr<URLRequestContext> prev_context = context_; | 92 scoped_refptr<URLRequestContext> prev_context = context_; |
95 | 93 |
96 context_ = context; | 94 context_ = context; |
97 | 95 |
98 if (prev_context != context) { | 96 if (prev_context != context) { |
99 if (prev_context) | 97 net_log_.AddEvent(NetLog::TYPE_REQUEST_ALIVE); |
100 prev_context->socket_stream_tracker()->Remove(this); | 98 net_log_ = BoundNetLog(); |
| 99 |
101 if (context) { | 100 if (context) { |
102 if (!load_log_) { | 101 net_log_ = BoundNetLog::Make( |
103 // Create the LoadLog -- we waited until now to create it so we know | 102 context->net_log(), |
104 // what constraints the URLRequestContext is enforcing on log levels. | 103 NetLog::SOURCE_SOCKET_STREAM); |
105 load_log_ = context->socket_stream_tracker()->CreateLoadLog(); | 104 |
106 } | 105 net_log_.BeginEventWithString(NetLog::TYPE_REQUEST_ALIVE, |
107 context->socket_stream_tracker()->Add(this); | 106 url_.possibly_invalid_spec()); |
108 } | 107 } |
109 } | 108 } |
110 | 109 |
111 if (context_) { | 110 if (context_) { |
112 host_resolver_ = context_->host_resolver(); | 111 host_resolver_ = context_->host_resolver(); |
113 http_auth_handler_factory_ = context_->http_auth_handler_factory(); | 112 http_auth_handler_factory_ = context_->http_auth_handler_factory(); |
114 } | 113 } |
115 } | 114 } |
116 | 115 |
117 void SocketStream::Connect() { | 116 void SocketStream::Connect() { |
118 DCHECK(MessageLoop::current()) << | 117 DCHECK(MessageLoop::current()) << |
119 "The current MessageLoop must exist"; | 118 "The current MessageLoop must exist"; |
120 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 119 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
121 "The current MessageLoop must be TYPE_IO"; | 120 "The current MessageLoop must be TYPE_IO"; |
122 if (context_) | 121 if (context_) |
123 ssl_config_service()->GetSSLConfig(&ssl_config_); | 122 ssl_config_service()->GetSSLConfig(&ssl_config_); |
124 DCHECK_EQ(next_state_, STATE_NONE); | 123 DCHECK_EQ(next_state_, STATE_NONE); |
125 | 124 |
126 AddRef(); // Released in Finish() | 125 AddRef(); // Released in Finish() |
127 // Open a connection asynchronously, so that delegate won't be called | 126 // Open a connection asynchronously, so that delegate won't be called |
128 // back before returning Connect(). | 127 // back before returning Connect(). |
129 next_state_ = STATE_RESOLVE_PROXY; | 128 next_state_ = STATE_RESOLVE_PROXY; |
130 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT); | 129 net_log_.BeginEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT); |
131 MessageLoop::current()->PostTask( | 130 MessageLoop::current()->PostTask( |
132 FROM_HERE, | 131 FROM_HERE, |
133 NewRunnableMethod(this, &SocketStream::DoLoop, OK)); | 132 NewRunnableMethod(this, &SocketStream::DoLoop, OK)); |
134 } | 133 } |
135 | 134 |
136 bool SocketStream::SendData(const char* data, int len) { | 135 bool SocketStream::SendData(const char* data, int len) { |
137 DCHECK(MessageLoop::current()) << | 136 DCHECK(MessageLoop::current()) << |
138 "The current MessageLoop must exist"; | 137 "The current MessageLoop must exist"; |
139 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 138 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
140 "The current MessageLoop must be TYPE_IO"; | 139 "The current MessageLoop must be TYPE_IO"; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 | 205 |
207 MessageLoop::current()->PostTask( | 206 MessageLoop::current()->PostTask( |
208 FROM_HERE, | 207 FROM_HERE, |
209 NewRunnableMethod(this, &SocketStream::DoRestartWithAuth)); | 208 NewRunnableMethod(this, &SocketStream::DoRestartWithAuth)); |
210 } | 209 } |
211 | 210 |
212 void SocketStream::DetachDelegate() { | 211 void SocketStream::DetachDelegate() { |
213 if (!delegate_) | 212 if (!delegate_) |
214 return; | 213 return; |
215 delegate_ = NULL; | 214 delegate_ = NULL; |
216 LoadLog::AddEvent(load_log_, LoadLog::TYPE_CANCELLED); | 215 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
217 Close(); | 216 Close(); |
218 } | 217 } |
219 | 218 |
220 void SocketStream::Finish(int result) { | 219 void SocketStream::Finish(int result) { |
221 DCHECK(MessageLoop::current()) << | 220 DCHECK(MessageLoop::current()) << |
222 "The current MessageLoop must exist"; | 221 "The current MessageLoop must exist"; |
223 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << | 222 DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()) << |
224 "The current MessageLoop must be TYPE_IO"; | 223 "The current MessageLoop must be TYPE_IO"; |
225 DCHECK_LE(result, OK); | 224 DCHECK_LE(result, OK); |
226 if (result == OK) | 225 if (result == OK) |
(...skipping 29 matching lines...) Expand all Loading... |
256 } | 255 } |
257 | 256 |
258 int SocketStream::DidEstablishConnection() { | 257 int SocketStream::DidEstablishConnection() { |
259 if (!socket_.get() || !socket_->IsConnected()) { | 258 if (!socket_.get() || !socket_->IsConnected()) { |
260 next_state_ = STATE_CLOSE; | 259 next_state_ = STATE_CLOSE; |
261 return ERR_CONNECTION_FAILED; | 260 return ERR_CONNECTION_FAILED; |
262 } | 261 } |
263 next_state_ = STATE_READ_WRITE; | 262 next_state_ = STATE_READ_WRITE; |
264 metrics_->OnConnected(); | 263 metrics_->OnConnected(); |
265 | 264 |
266 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT); | 265 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT); |
267 if (delegate_) | 266 if (delegate_) |
268 delegate_->OnConnected(this, max_pending_send_allowed_); | 267 delegate_->OnConnected(this, max_pending_send_allowed_); |
269 | 268 |
270 return OK; | 269 return OK; |
271 } | 270 } |
272 | 271 |
273 int SocketStream::DidReceiveData(int result) { | 272 int SocketStream::DidReceiveData(int result) { |
274 DCHECK(read_buf_); | 273 DCHECK(read_buf_); |
275 DCHECK_GT(result, 0); | 274 DCHECK_GT(result, 0); |
276 LoadLog::AddEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_RECEIVED); | 275 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_RECEIVED); |
277 int len = result; | 276 int len = result; |
278 metrics_->OnRead(len); | 277 metrics_->OnRead(len); |
279 result = throttle_->OnRead(this, read_buf_->data(), len, &io_callback_); | 278 result = throttle_->OnRead(this, read_buf_->data(), len, &io_callback_); |
280 if (delegate_) { | 279 if (delegate_) { |
281 // Notify recevied data to delegate. | 280 // Notify recevied data to delegate. |
282 delegate_->OnReceivedData(this, read_buf_->data(), len); | 281 delegate_->OnReceivedData(this, read_buf_->data(), len); |
283 } | 282 } |
284 read_buf_ = NULL; | 283 read_buf_ = NULL; |
285 return result; | 284 return result; |
286 } | 285 } |
287 | 286 |
288 int SocketStream::DidSendData(int result) { | 287 int SocketStream::DidSendData(int result) { |
289 DCHECK_GT(result, 0); | 288 DCHECK_GT(result, 0); |
290 LoadLog::AddEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_SENT); | 289 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_SENT); |
291 int len = result; | 290 int len = result; |
292 metrics_->OnWrite(len); | 291 metrics_->OnWrite(len); |
293 result = throttle_->OnWrite(this, current_write_buf_->data(), len, | 292 result = throttle_->OnWrite(this, current_write_buf_->data(), len, |
294 &io_callback_); | 293 &io_callback_); |
295 current_write_buf_ = NULL; | 294 current_write_buf_ = NULL; |
296 if (delegate_) | 295 if (delegate_) |
297 delegate_->OnSentData(this, len); | 296 delegate_->OnSentData(this, len); |
298 | 297 |
299 int remaining_size = write_buf_size_ - write_buf_offset_ - len; | 298 int remaining_size = write_buf_size_ - write_buf_offset_ - len; |
300 if (remaining_size == 0) { | 299 if (remaining_size == 0) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 return; | 403 return; |
405 default: | 404 default: |
406 NOTREACHED() << "bad state"; | 405 NOTREACHED() << "bad state"; |
407 Finish(result); | 406 Finish(result); |
408 return; | 407 return; |
409 } | 408 } |
410 // If the connection is not established yet and had actual errors, | 409 // If the connection is not established yet and had actual errors, |
411 // close the connection. | 410 // close the connection. |
412 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { | 411 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) { |
413 DCHECK_EQ(next_state_, STATE_CLOSE); | 412 DCHECK_EQ(next_state_, STATE_CLOSE); |
414 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKET_STREAM_CONNECT); | 413 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT); |
415 } | 414 } |
416 } while (result != ERR_IO_PENDING); | 415 } while (result != ERR_IO_PENDING); |
417 } | 416 } |
418 | 417 |
419 int SocketStream::DoResolveProxy() { | 418 int SocketStream::DoResolveProxy() { |
420 DCHECK(!pac_request_); | 419 DCHECK(!pac_request_); |
421 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | 420 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
422 | 421 |
423 if (!proxy_url_.is_valid()) { | 422 if (!proxy_url_.is_valid()) { |
424 next_state_ = STATE_CLOSE; | 423 next_state_ = STATE_CLOSE; |
425 return ERR_INVALID_ARGUMENT; | 424 return ERR_INVALID_ARGUMENT; |
426 } | 425 } |
427 | 426 |
428 return proxy_service()->ResolveProxy( | 427 return proxy_service()->ResolveProxy( |
429 proxy_url_, &proxy_info_, &io_callback_, &pac_request_, load_log_); | 428 proxy_url_, &proxy_info_, &io_callback_, &pac_request_, net_log_); |
430 } | 429 } |
431 | 430 |
432 int SocketStream::DoResolveProxyComplete(int result) { | 431 int SocketStream::DoResolveProxyComplete(int result) { |
433 next_state_ = STATE_RESOLVE_HOST; | 432 next_state_ = STATE_RESOLVE_HOST; |
434 | 433 |
435 pac_request_ = NULL; | 434 pac_request_ = NULL; |
436 if (result != OK) { | 435 if (result != OK) { |
437 LOG(ERROR) << "Failed to resolve proxy: " << result; | 436 LOG(ERROR) << "Failed to resolve proxy: " << result; |
438 if (delegate_) | 437 if (delegate_) |
439 delegate_->OnError(this, result); | 438 delegate_->OnError(this, result); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 } else { | 477 } else { |
479 host = url_.HostNoBrackets(); | 478 host = url_.HostNoBrackets(); |
480 port = url_.EffectiveIntPort(); | 479 port = url_.EffectiveIntPort(); |
481 } | 480 } |
482 | 481 |
483 HostResolver::RequestInfo resolve_info(host, port); | 482 HostResolver::RequestInfo resolve_info(host, port); |
484 | 483 |
485 DCHECK(host_resolver_.get()); | 484 DCHECK(host_resolver_.get()); |
486 resolver_.reset(new SingleRequestHostResolver(host_resolver_.get())); | 485 resolver_.reset(new SingleRequestHostResolver(host_resolver_.get())); |
487 return resolver_->Resolve(resolve_info, &addresses_, &io_callback_, | 486 return resolver_->Resolve(resolve_info, &addresses_, &io_callback_, |
488 load_log_); | 487 net_log_); |
489 } | 488 } |
490 | 489 |
491 int SocketStream::DoResolveHostComplete(int result) { | 490 int SocketStream::DoResolveHostComplete(int result) { |
492 if (result == OK) { | 491 if (result == OK) { |
493 next_state_ = STATE_TCP_CONNECT; | 492 next_state_ = STATE_TCP_CONNECT; |
494 result = throttle_->OnStartOpenConnection(this, &io_callback_); | 493 result = throttle_->OnStartOpenConnection(this, &io_callback_); |
495 if (result == net::ERR_IO_PENDING) | 494 if (result == net::ERR_IO_PENDING) |
496 metrics_->OnWaitConnection(); | 495 metrics_->OnWaitConnection(); |
497 } else { | 496 } else { |
498 next_state_ = STATE_CLOSE; | 497 next_state_ = STATE_CLOSE; |
499 } | 498 } |
500 // TODO(ukai): if error occured, reconsider proxy after error. | 499 // TODO(ukai): if error occured, reconsider proxy after error. |
501 return result; | 500 return result; |
502 } | 501 } |
503 | 502 |
504 int SocketStream::DoTcpConnect() { | 503 int SocketStream::DoTcpConnect() { |
505 next_state_ = STATE_TCP_CONNECT_COMPLETE; | 504 next_state_ = STATE_TCP_CONNECT_COMPLETE; |
506 DCHECK(factory_); | 505 DCHECK(factory_); |
507 socket_.reset(factory_->CreateTCPClientSocket(addresses_)); | 506 socket_.reset(factory_->CreateTCPClientSocket(addresses_)); |
508 metrics_->OnStartConnection(); | 507 metrics_->OnStartConnection(); |
509 return socket_->Connect(&io_callback_, load_log_); | 508 return socket_->Connect(&io_callback_, net_log_); |
510 } | 509 } |
511 | 510 |
512 int SocketStream::DoTcpConnectComplete(int result) { | 511 int SocketStream::DoTcpConnectComplete(int result) { |
513 // TODO(ukai): if error occured, reconsider proxy after error. | 512 // TODO(ukai): if error occured, reconsider proxy after error. |
514 if (result != OK) { | 513 if (result != OK) { |
515 next_state_ = STATE_CLOSE; | 514 next_state_ = STATE_CLOSE; |
516 return result; | 515 return result; |
517 } | 516 } |
518 | 517 |
519 if (proxy_mode_ == kTunnelProxy) | 518 if (proxy_mode_ == kTunnelProxy) |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 ClientSocket* s = socket_.release(); | 714 ClientSocket* s = socket_.release(); |
716 HostResolver::RequestInfo req_info(url_.HostNoBrackets(), | 715 HostResolver::RequestInfo req_info(url_.HostNoBrackets(), |
717 url_.EffectiveIntPort()); | 716 url_.EffectiveIntPort()); |
718 | 717 |
719 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) | 718 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) |
720 s = new SOCKS5ClientSocket(s, req_info); | 719 s = new SOCKS5ClientSocket(s, req_info); |
721 else | 720 else |
722 s = new SOCKSClientSocket(s, req_info, host_resolver_.get()); | 721 s = new SOCKSClientSocket(s, req_info, host_resolver_.get()); |
723 socket_.reset(s); | 722 socket_.reset(s); |
724 metrics_->OnSOCKSProxy(); | 723 metrics_->OnSOCKSProxy(); |
725 return socket_->Connect(&io_callback_, load_log_); | 724 return socket_->Connect(&io_callback_, net_log_); |
726 } | 725 } |
727 | 726 |
728 int SocketStream::DoSOCKSConnectComplete(int result) { | 727 int SocketStream::DoSOCKSConnectComplete(int result) { |
729 DCHECK_EQ(kSOCKSProxy, proxy_mode_); | 728 DCHECK_EQ(kSOCKSProxy, proxy_mode_); |
730 | 729 |
731 if (result == OK) { | 730 if (result == OK) { |
732 if (is_secure()) | 731 if (is_secure()) |
733 next_state_ = STATE_SSL_CONNECT; | 732 next_state_ = STATE_SSL_CONNECT; |
734 else | 733 else |
735 result = DidEstablishConnection(); | 734 result = DidEstablishConnection(); |
736 } else { | 735 } else { |
737 next_state_ = STATE_CLOSE; | 736 next_state_ = STATE_CLOSE; |
738 } | 737 } |
739 return result; | 738 return result; |
740 } | 739 } |
741 | 740 |
742 int SocketStream::DoSSLConnect() { | 741 int SocketStream::DoSSLConnect() { |
743 DCHECK(factory_); | 742 DCHECK(factory_); |
744 socket_.reset(factory_->CreateSSLClientSocket( | 743 socket_.reset(factory_->CreateSSLClientSocket( |
745 socket_.release(), url_.HostNoBrackets(), ssl_config_)); | 744 socket_.release(), url_.HostNoBrackets(), ssl_config_)); |
746 next_state_ = STATE_SSL_CONNECT_COMPLETE; | 745 next_state_ = STATE_SSL_CONNECT_COMPLETE; |
747 metrics_->OnSSLConnection(); | 746 metrics_->OnSSLConnection(); |
748 return socket_->Connect(&io_callback_, load_log_); | 747 return socket_->Connect(&io_callback_, net_log_); |
749 } | 748 } |
750 | 749 |
751 int SocketStream::DoSSLConnectComplete(int result) { | 750 int SocketStream::DoSSLConnectComplete(int result) { |
752 if (IsCertificateError(result)) { | 751 if (IsCertificateError(result)) { |
753 if (socket_->IsConnectedAndIdle()) { | 752 if (socket_->IsConnectedAndIdle()) { |
754 result = HandleCertificateError(result); | 753 result = HandleCertificateError(result); |
755 } else { | 754 } else { |
756 // SSLClientSocket for Mac will report socket is not connected, | 755 // SSLClientSocket for Mac will report socket is not connected, |
757 // if it returns cert verification error. It didn't perform | 756 // if it returns cert verification error. It didn't perform |
758 // SSLHandshake yet. | 757 // SSLHandshake yet. |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 } | 941 } |
943 | 942 |
944 SSLConfigService* SocketStream::ssl_config_service() const { | 943 SSLConfigService* SocketStream::ssl_config_service() const { |
945 return context_->ssl_config_service(); | 944 return context_->ssl_config_service(); |
946 } | 945 } |
947 | 946 |
948 ProxyService* SocketStream::proxy_service() const { | 947 ProxyService* SocketStream::proxy_service() const { |
949 return context_->proxy_service(); | 948 return context_->proxy_service(); |
950 } | 949 } |
951 | 950 |
952 void SocketStream::GetInfoForTracker( | |
953 RequestTracker<SocketStream>::RecentRequestInfo* info) const { | |
954 info->original_url = url_; | |
955 info->load_log = load_log_; | |
956 } | |
957 | |
958 } // namespace net | 951 } // namespace net |
OLD | NEW |