[GCM] Passing GCMClient::AccountTokenInfo list to GCMDriver
[chromium-blink-merge.git] / net / socket_stream / socket_stream.cc
blob422d61d45203c324fd48ed381b58dd34a3e2fd95
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
3 // found in the LICENSE file.
4 //
5 // TODO(ukai): code is similar with http_network_transaction.cc. We should
6 // think about ways to share code, if possible.
8 #include "net/socket_stream/socket_stream.h"
10 #include <set>
11 #include <string>
12 #include <vector>
14 #include "base/bind.h"
15 #include "base/bind_helpers.h"
16 #include "base/compiler_specific.h"
17 #include "base/logging.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/strings/string_util.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "net/base/auth.h"
23 #include "net/base/io_buffer.h"
24 #include "net/base/load_flags.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/net_util.h"
27 #include "net/dns/host_resolver.h"
28 #include "net/http/http_auth_controller.h"
29 #include "net/http/http_network_session.h"
30 #include "net/http/http_request_headers.h"
31 #include "net/http/http_request_info.h"
32 #include "net/http/http_response_headers.h"
33 #include "net/http/http_stream_factory.h"
34 #include "net/http/http_transaction_factory.h"
35 #include "net/http/http_util.h"
36 #include "net/socket/client_socket_factory.h"
37 #include "net/socket/client_socket_handle.h"
38 #include "net/socket/socks5_client_socket.h"
39 #include "net/socket/socks_client_socket.h"
40 #include "net/socket/ssl_client_socket.h"
41 #include "net/socket/tcp_client_socket.h"
42 #include "net/socket_stream/socket_stream_metrics.h"
43 #include "net/ssl/ssl_cert_request_info.h"
44 #include "net/ssl/ssl_info.h"
45 #include "net/url_request/url_request.h"
46 #include "net/url_request/url_request_context.h"
48 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes.
49 static const int kReadBufferSize = 4096;
51 namespace net {
53 int SocketStream::Delegate::OnStartOpenConnection(
54 SocketStream* socket, const CompletionCallback& callback) {
55 return OK;
58 void SocketStream::Delegate::OnAuthRequired(SocketStream* socket,
59 AuthChallengeInfo* auth_info) {
60 // By default, no credential is available and close the connection.
61 socket->Close();
64 void SocketStream::Delegate::OnSSLCertificateError(
65 SocketStream* socket,
66 const SSLInfo& ssl_info,
67 bool fatal) {
68 socket->CancelWithSSLError(ssl_info);
71 bool SocketStream::Delegate::CanGetCookies(SocketStream* socket,
72 const GURL& url) {
73 return true;
76 bool SocketStream::Delegate::CanSetCookie(SocketStream* request,
77 const GURL& url,
78 const std::string& cookie_line,
79 CookieOptions* options) {
80 return true;
83 SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {}
85 void SocketStream::ResponseHeaders::Realloc(size_t new_size) {
86 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size)));
89 SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; }
91 SocketStream::SocketStream(const GURL& url, Delegate* delegate,
92 URLRequestContext* context,
93 CookieStore* cookie_store)
94 : delegate_(delegate),
95 url_(url),
96 max_pending_send_allowed_(kMaxPendingSendAllowed),
97 context_(context),
98 next_state_(STATE_NONE),
99 factory_(ClientSocketFactory::GetDefaultFactory()),
100 proxy_mode_(kDirectConnection),
101 proxy_url_(url),
102 pac_request_(NULL),
103 connection_(new ClientSocketHandle),
104 privacy_mode_(PRIVACY_MODE_DISABLED),
105 // Unretained() is required; without it, Bind() creates a circular
106 // dependency and the SocketStream object will not be freed.
107 io_callback_(base::Bind(&SocketStream::OnIOCompleted,
108 base::Unretained(this))),
109 read_buf_(NULL),
110 current_write_buf_(NULL),
111 waiting_for_write_completion_(false),
112 closing_(false),
113 server_closed_(false),
114 metrics_(new SocketStreamMetrics(url)),
115 cookie_store_(cookie_store) {
116 DCHECK(base::MessageLoop::current())
117 << "The current base::MessageLoop must exist";
118 DCHECK(base::MessageLoopForIO::IsCurrent())
119 << "The current base::MessageLoop must be TYPE_IO";
120 DCHECK(delegate_);
122 if (context_) {
123 if (!cookie_store_.get())
124 cookie_store_ = context_->cookie_store();
126 net_log_ = BoundNetLog::Make(
127 context->net_log(),
128 NetLog::SOURCE_SOCKET_STREAM);
130 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
134 SocketStream::UserData* SocketStream::GetUserData(
135 const void* key) const {
136 UserDataMap::const_iterator found = user_data_.find(key);
137 if (found != user_data_.end())
138 return found->second.get();
139 return NULL;
142 void SocketStream::SetUserData(const void* key, UserData* data) {
143 user_data_[key] = linked_ptr<UserData>(data);
146 bool SocketStream::is_secure() const {
147 return url_.SchemeIs("wss");
150 void SocketStream::DetachContext() {
151 if (!context_)
152 return;
154 if (pac_request_) {
155 context_->proxy_service()->CancelPacRequest(pac_request_);
156 pac_request_ = NULL;
159 net_log_.EndEvent(NetLog::TYPE_REQUEST_ALIVE);
160 net_log_ = BoundNetLog();
162 context_ = NULL;
163 cookie_store_ = NULL;
166 void SocketStream::CheckPrivacyMode() {
167 if (context_ && context_->network_delegate()) {
168 bool enable = context_->network_delegate()->CanEnablePrivacyMode(url_,
169 url_);
170 privacy_mode_ = enable ? PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED;
171 // Disable Channel ID if privacy mode is enabled.
172 if (enable)
173 server_ssl_config_.channel_id_enabled = false;
177 void SocketStream::Connect() {
178 DCHECK(base::MessageLoop::current())
179 << "The current base::MessageLoop must exist";
180 DCHECK(base::MessageLoopForIO::IsCurrent())
181 << "The current base::MessageLoop must be TYPE_IO";
182 if (context_) {
183 context_->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
184 proxy_ssl_config_ = server_ssl_config_;
186 CheckPrivacyMode();
188 DCHECK_EQ(next_state_, STATE_NONE);
190 AddRef(); // Released in Finish()
191 // Open a connection asynchronously, so that delegate won't be called
192 // back before returning Connect().
193 next_state_ = STATE_BEFORE_CONNECT;
194 net_log_.BeginEvent(
195 NetLog::TYPE_SOCKET_STREAM_CONNECT,
196 NetLog::StringCallback("url", &url_.possibly_invalid_spec()));
197 base::MessageLoop::current()->PostTask(
198 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
201 size_t SocketStream::GetTotalSizeOfPendingWriteBufs() const {
202 size_t total_size = 0;
203 for (PendingDataQueue::const_iterator iter = pending_write_bufs_.begin();
204 iter != pending_write_bufs_.end();
205 ++iter)
206 total_size += (*iter)->size();
207 return total_size;
210 bool SocketStream::SendData(const char* data, int len) {
211 DCHECK(base::MessageLoop::current())
212 << "The current base::MessageLoop must exist";
213 DCHECK(base::MessageLoopForIO::IsCurrent())
214 << "The current base::MessageLoop must be TYPE_IO";
215 DCHECK_GT(len, 0);
217 if (!connection_->socket() ||
218 !connection_->socket()->IsConnected() || next_state_ == STATE_NONE) {
219 return false;
222 int total_buffered_bytes = len;
223 if (current_write_buf_.get()) {
224 // Since
225 // - the purpose of this check is to limit the amount of buffer used by
226 // this instance.
227 // - the DrainableIOBuffer doesn't release consumed memory.
228 // we need to use not BytesRemaining() but size() here.
229 total_buffered_bytes += current_write_buf_->size();
231 total_buffered_bytes += GetTotalSizeOfPendingWriteBufs();
232 if (total_buffered_bytes > max_pending_send_allowed_)
233 return false;
235 // TODO(tyoshino): Split data into smaller chunks e.g. 8KiB to free consumed
236 // buffer progressively
237 pending_write_bufs_.push_back(make_scoped_refptr(
238 new IOBufferWithSize(len)));
239 memcpy(pending_write_bufs_.back()->data(), data, len);
241 // If current_write_buf_ is not NULL, it means that a) there's ongoing write
242 // operation or b) the connection is being closed. If a), the buffer we just
243 // pushed will be automatically handled when the completion callback runs
244 // the loop, and therefore we don't need to enqueue DoLoop(). If b), it's ok
245 // to do nothing. If current_write_buf_ is NULL, to make sure DoLoop() is
246 // ran soon, enequeue it.
247 if (!current_write_buf_.get()) {
248 // Send pending data asynchronously, so that delegate won't be called
249 // back before returning from SendData().
250 base::MessageLoop::current()->PostTask(
251 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
254 return true;
257 void SocketStream::Close() {
258 DCHECK(base::MessageLoop::current())
259 << "The current base::MessageLoop must exist";
260 DCHECK(base::MessageLoopForIO::IsCurrent())
261 << "The current base::MessageLoop must be TYPE_IO";
262 // If next_state_ is STATE_NONE, the socket was not opened, or already
263 // closed. So, return immediately.
264 // Otherwise, it might call Finish() more than once, so breaks balance
265 // of AddRef() and Release() in Connect() and Finish(), respectively.
266 if (next_state_ == STATE_NONE)
267 return;
268 base::MessageLoop::current()->PostTask(
269 FROM_HERE, base::Bind(&SocketStream::DoClose, this));
272 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) {
273 DCHECK(base::MessageLoop::current())
274 << "The current base::MessageLoop must exist";
275 DCHECK(base::MessageLoopForIO::IsCurrent())
276 << "The current base::MessageLoop must be TYPE_IO";
277 DCHECK(proxy_auth_controller_.get());
278 if (!connection_->socket()) {
279 DVLOG(1) << "Socket is closed before restarting with auth.";
280 return;
283 proxy_auth_controller_->ResetAuth(credentials);
285 base::MessageLoop::current()->PostTask(
286 FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
289 void SocketStream::DetachDelegate() {
290 if (!delegate_)
291 return;
292 delegate_ = NULL;
293 // Prevent the rest of the function from executing if we are being called from
294 // within Finish().
295 if (next_state_ == STATE_NONE)
296 return;
297 net_log_.AddEvent(NetLog::TYPE_CANCELLED);
298 // We don't need to send pending data when client detach the delegate.
299 pending_write_bufs_.clear();
300 Close();
303 const ProxyServer& SocketStream::proxy_server() const {
304 return proxy_info_.proxy_server();
307 void SocketStream::SetClientSocketFactory(
308 ClientSocketFactory* factory) {
309 DCHECK(factory);
310 factory_ = factory;
313 void SocketStream::CancelWithError(int error) {
314 base::MessageLoop::current()->PostTask(
315 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, error));
318 void SocketStream::CancelWithSSLError(const SSLInfo& ssl_info) {
319 CancelWithError(MapCertStatusToNetError(ssl_info.cert_status));
322 void SocketStream::ContinueDespiteError() {
323 base::MessageLoop::current()->PostTask(
324 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
327 SocketStream::~SocketStream() {
328 DetachContext();
329 DCHECK(!delegate_);
330 DCHECK(!pac_request_);
333 SocketStream::RequestHeaders::~RequestHeaders() { data_ = NULL; }
335 void SocketStream::set_addresses(const AddressList& addresses) {
336 addresses_ = addresses;
339 void SocketStream::DoClose() {
340 closing_ = true;
341 // If next_state_ is:
342 // - STATE_TCP_CONNECT_COMPLETE, it's waiting other socket establishing
343 // connection.
344 // - STATE_AUTH_REQUIRED, it's waiting for restarting.
345 // - STATE_RESOLVE_PROTOCOL_COMPLETE, it's waiting for delegate_ to finish
346 // OnStartOpenConnection method call
347 // In these states, we'll close the SocketStream now.
348 if (next_state_ == STATE_TCP_CONNECT_COMPLETE ||
349 next_state_ == STATE_AUTH_REQUIRED ||
350 next_state_ == STATE_RESOLVE_PROTOCOL_COMPLETE) {
351 DoLoop(ERR_ABORTED);
352 return;
354 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close
355 // the SocketStream.
356 // If it's writing now, we should defer the closing after the current
357 // writing is completed.
358 if (next_state_ == STATE_READ_WRITE && !current_write_buf_.get())
359 DoLoop(ERR_ABORTED);
361 // In other next_state_, we'll wait for callback of other APIs, such as
362 // ResolveProxy().
365 void SocketStream::Finish(int result) {
366 DCHECK(base::MessageLoop::current())
367 << "The current base::MessageLoop must exist";
368 DCHECK(base::MessageLoopForIO::IsCurrent())
369 << "The current base::MessageLoop must be TYPE_IO";
370 DCHECK_LE(result, OK);
371 if (result == OK)
372 result = ERR_CONNECTION_CLOSED;
373 DCHECK_EQ(next_state_, STATE_NONE);
374 DVLOG(1) << "Finish result=" << ErrorToString(result);
376 metrics_->OnClose();
378 if (result != ERR_CONNECTION_CLOSED && delegate_)
379 delegate_->OnError(this, result);
380 if (result != ERR_PROTOCOL_SWITCHED && delegate_)
381 delegate_->OnClose(this);
382 delegate_ = NULL;
384 Release();
387 int SocketStream::DidEstablishConnection() {
388 if (!connection_->socket() || !connection_->socket()->IsConnected()) {
389 next_state_ = STATE_CLOSE;
390 return ERR_CONNECTION_FAILED;
392 next_state_ = STATE_READ_WRITE;
393 metrics_->OnConnected();
395 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT);
396 if (delegate_)
397 delegate_->OnConnected(this, max_pending_send_allowed_);
399 return OK;
402 int SocketStream::DidReceiveData(int result) {
403 DCHECK(read_buf_.get());
404 DCHECK_GT(result, 0);
405 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_RECEIVED);
406 int len = result;
407 metrics_->OnRead(len);
408 if (delegate_) {
409 // Notify recevied data to delegate.
410 delegate_->OnReceivedData(this, read_buf_->data(), len);
412 read_buf_ = NULL;
413 return OK;
416 void SocketStream::DidSendData(int result) {
417 DCHECK_GT(result, 0);
418 DCHECK(current_write_buf_.get());
419 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_SENT);
421 int bytes_sent = result;
423 metrics_->OnWrite(bytes_sent);
425 current_write_buf_->DidConsume(result);
427 if (current_write_buf_->BytesRemaining())
428 return;
430 size_t bytes_freed = current_write_buf_->size();
432 current_write_buf_ = NULL;
434 // We freed current_write_buf_ and this instance is now able to accept more
435 // data via SendData() (note that DidConsume() doesn't free consumed memory).
436 // We can tell that to delegate_ by calling OnSentData().
437 if (delegate_)
438 delegate_->OnSentData(this, bytes_freed);
441 void SocketStream::OnIOCompleted(int result) {
442 DoLoop(result);
445 void SocketStream::OnReadCompleted(int result) {
446 if (result == 0) {
447 // 0 indicates end-of-file, so socket was closed.
448 // Don't close the socket if it's still writing.
449 server_closed_ = true;
450 } else if (result > 0 && read_buf_.get()) {
451 result = DidReceiveData(result);
453 DoLoop(result);
456 void SocketStream::OnWriteCompleted(int result) {
457 waiting_for_write_completion_ = false;
458 if (result > 0) {
459 DidSendData(result);
460 result = OK;
462 DoLoop(result);
465 void SocketStream::DoLoop(int result) {
466 if (next_state_ == STATE_NONE)
467 return;
469 // If context was not set, close immediately.
470 if (!context_)
471 next_state_ = STATE_CLOSE;
473 do {
474 State state = next_state_;
475 next_state_ = STATE_NONE;
476 switch (state) {
477 case STATE_BEFORE_CONNECT:
478 DCHECK_EQ(OK, result);
479 result = DoBeforeConnect();
480 break;
481 case STATE_BEFORE_CONNECT_COMPLETE:
482 result = DoBeforeConnectComplete(result);
483 break;
484 case STATE_RESOLVE_PROXY:
485 DCHECK_EQ(OK, result);
486 result = DoResolveProxy();
487 break;
488 case STATE_RESOLVE_PROXY_COMPLETE:
489 result = DoResolveProxyComplete(result);
490 break;
491 case STATE_RESOLVE_HOST:
492 DCHECK_EQ(OK, result);
493 result = DoResolveHost();
494 break;
495 case STATE_RESOLVE_HOST_COMPLETE:
496 result = DoResolveHostComplete(result);
497 break;
498 case STATE_RESOLVE_PROTOCOL:
499 result = DoResolveProtocol(result);
500 break;
501 case STATE_RESOLVE_PROTOCOL_COMPLETE:
502 result = DoResolveProtocolComplete(result);
503 break;
504 case STATE_TCP_CONNECT:
505 result = DoTcpConnect(result);
506 break;
507 case STATE_TCP_CONNECT_COMPLETE:
508 result = DoTcpConnectComplete(result);
509 break;
510 case STATE_GENERATE_PROXY_AUTH_TOKEN:
511 result = DoGenerateProxyAuthToken();
512 break;
513 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
514 result = DoGenerateProxyAuthTokenComplete(result);
515 break;
516 case STATE_WRITE_TUNNEL_HEADERS:
517 DCHECK_EQ(OK, result);
518 result = DoWriteTunnelHeaders();
519 break;
520 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
521 result = DoWriteTunnelHeadersComplete(result);
522 break;
523 case STATE_READ_TUNNEL_HEADERS:
524 DCHECK_EQ(OK, result);
525 result = DoReadTunnelHeaders();
526 break;
527 case STATE_READ_TUNNEL_HEADERS_COMPLETE:
528 result = DoReadTunnelHeadersComplete(result);
529 break;
530 case STATE_SOCKS_CONNECT:
531 DCHECK_EQ(OK, result);
532 result = DoSOCKSConnect();
533 break;
534 case STATE_SOCKS_CONNECT_COMPLETE:
535 result = DoSOCKSConnectComplete(result);
536 break;
537 case STATE_SECURE_PROXY_CONNECT:
538 DCHECK_EQ(OK, result);
539 result = DoSecureProxyConnect();
540 break;
541 case STATE_SECURE_PROXY_CONNECT_COMPLETE:
542 result = DoSecureProxyConnectComplete(result);
543 break;
544 case STATE_SECURE_PROXY_HANDLE_CERT_ERROR:
545 result = DoSecureProxyHandleCertError(result);
546 break;
547 case STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE:
548 result = DoSecureProxyHandleCertErrorComplete(result);
549 break;
550 case STATE_SSL_CONNECT:
551 DCHECK_EQ(OK, result);
552 result = DoSSLConnect();
553 break;
554 case STATE_SSL_CONNECT_COMPLETE:
555 result = DoSSLConnectComplete(result);
556 break;
557 case STATE_SSL_HANDLE_CERT_ERROR:
558 result = DoSSLHandleCertError(result);
559 break;
560 case STATE_SSL_HANDLE_CERT_ERROR_COMPLETE:
561 result = DoSSLHandleCertErrorComplete(result);
562 break;
563 case STATE_READ_WRITE:
564 result = DoReadWrite(result);
565 break;
566 case STATE_AUTH_REQUIRED:
567 // It might be called when DoClose is called while waiting in
568 // STATE_AUTH_REQUIRED.
569 Finish(result);
570 return;
571 case STATE_CLOSE:
572 DCHECK_LE(result, OK);
573 Finish(result);
574 return;
575 default:
576 NOTREACHED() << "bad state " << state;
577 Finish(result);
578 return;
580 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED)
581 continue;
582 // If the connection is not established yet and had actual errors,
583 // record the error. In next iteration, it will close the connection.
584 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) {
585 net_log_.EndEventWithNetErrorCode(
586 NetLog::TYPE_SOCKET_STREAM_CONNECT, result);
588 } while (result != ERR_IO_PENDING);
591 int SocketStream::DoBeforeConnect() {
592 next_state_ = STATE_BEFORE_CONNECT_COMPLETE;
593 if (!context_ || !context_->network_delegate())
594 return OK;
596 int result = context_->network_delegate()->NotifyBeforeSocketStreamConnect(
597 this, io_callback_);
598 if (result != OK && result != ERR_IO_PENDING)
599 next_state_ = STATE_CLOSE;
601 return result;
604 int SocketStream::DoBeforeConnectComplete(int result) {
605 DCHECK_NE(ERR_IO_PENDING, result);
607 if (result == OK)
608 next_state_ = STATE_RESOLVE_PROXY;
609 else
610 next_state_ = STATE_CLOSE;
612 return result;
615 int SocketStream::DoResolveProxy() {
616 DCHECK(context_);
617 DCHECK(!pac_request_);
618 next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
620 if (!proxy_url_.is_valid()) {
621 next_state_ = STATE_CLOSE;
622 return ERR_INVALID_ARGUMENT;
625 // TODO(toyoshim): Check server advertisement of SPDY through the HTTP
626 // Alternate-Protocol header, then switch to SPDY if SPDY is available.
627 // Usually we already have a session to the SPDY server because JavaScript
628 // running WebSocket itself would be served by SPDY. But, in some situation
629 // (E.g. Used by Chrome Extensions or used for cross origin connection), this
630 // connection might be the first one. At that time, we should check
631 // Alternate-Protocol header here for ws:// or TLS NPN extension for wss:// .
633 return context_->proxy_service()->ResolveProxy(
634 proxy_url_, net::LOAD_NORMAL, &proxy_info_, io_callback_, &pac_request_,
635 NULL, net_log_);
638 int SocketStream::DoResolveProxyComplete(int result) {
639 pac_request_ = NULL;
640 if (result != OK) {
641 DVLOG(1) << "Failed to resolve proxy: " << result;
642 if (delegate_)
643 delegate_->OnError(this, result);
644 proxy_info_.UseDirect();
646 if (proxy_info_.is_direct()) {
647 // If proxy was not found for original URL (i.e. websocket URL),
648 // try again with https URL, like Safari implementation.
649 // Note that we don't want to use http proxy, because we'll use tunnel
650 // proxy using CONNECT method, which is used by https proxy.
651 if (!proxy_url_.SchemeIs("https")) {
652 const std::string scheme = "https";
653 GURL::Replacements repl;
654 repl.SetSchemeStr(scheme);
655 proxy_url_ = url_.ReplaceComponents(repl);
656 DVLOG(1) << "Try https proxy: " << proxy_url_;
657 next_state_ = STATE_RESOLVE_PROXY;
658 return OK;
662 if (proxy_info_.is_empty()) {
663 // No proxies/direct to choose from. This happens when we don't support any
664 // of the proxies in the returned list.
665 return ERR_NO_SUPPORTED_PROXIES;
668 next_state_ = STATE_RESOLVE_HOST;
669 return OK;
672 int SocketStream::DoResolveHost() {
673 next_state_ = STATE_RESOLVE_HOST_COMPLETE;
675 DCHECK(!proxy_info_.is_empty());
676 if (proxy_info_.is_direct())
677 proxy_mode_ = kDirectConnection;
678 else if (proxy_info_.proxy_server().is_socks())
679 proxy_mode_ = kSOCKSProxy;
680 else
681 proxy_mode_ = kTunnelProxy;
683 // Determine the host and port to connect to.
684 HostPortPair host_port_pair;
685 if (proxy_mode_ != kDirectConnection) {
686 host_port_pair = proxy_info_.proxy_server().host_port_pair();
687 } else {
688 host_port_pair = HostPortPair::FromURL(url_);
691 HostResolver::RequestInfo resolve_info(host_port_pair);
693 DCHECK(context_->host_resolver());
694 resolver_.reset(new SingleRequestHostResolver(context_->host_resolver()));
695 return resolver_->Resolve(resolve_info,
696 DEFAULT_PRIORITY,
697 &addresses_,
698 base::Bind(&SocketStream::OnIOCompleted, this),
699 net_log_);
702 int SocketStream::DoResolveHostComplete(int result) {
703 if (result == OK)
704 next_state_ = STATE_RESOLVE_PROTOCOL;
705 else
706 next_state_ = STATE_CLOSE;
707 // TODO(ukai): if error occured, reconsider proxy after error.
708 return result;
711 int SocketStream::DoResolveProtocol(int result) {
712 DCHECK_EQ(OK, result);
714 if (!delegate_) {
715 next_state_ = STATE_CLOSE;
716 return result;
719 next_state_ = STATE_RESOLVE_PROTOCOL_COMPLETE;
720 result = delegate_->OnStartOpenConnection(this, io_callback_);
721 if (result == ERR_IO_PENDING)
722 metrics_->OnWaitConnection();
723 else if (result != OK && result != ERR_PROTOCOL_SWITCHED)
724 next_state_ = STATE_CLOSE;
725 return result;
728 int SocketStream::DoResolveProtocolComplete(int result) {
729 DCHECK_NE(ERR_IO_PENDING, result);
731 if (result == ERR_PROTOCOL_SWITCHED) {
732 next_state_ = STATE_CLOSE;
733 metrics_->OnCountWireProtocolType(
734 SocketStreamMetrics::WIRE_PROTOCOL_SPDY);
735 } else if (result == OK) {
736 next_state_ = STATE_TCP_CONNECT;
737 metrics_->OnCountWireProtocolType(
738 SocketStreamMetrics::WIRE_PROTOCOL_WEBSOCKET);
739 } else {
740 next_state_ = STATE_CLOSE;
742 return result;
745 int SocketStream::DoTcpConnect(int result) {
746 if (result != OK) {
747 next_state_ = STATE_CLOSE;
748 return result;
750 next_state_ = STATE_TCP_CONNECT_COMPLETE;
751 DCHECK(factory_);
752 connection_->SetSocket(
753 factory_->CreateTransportClientSocket(addresses_,
754 net_log_.net_log(),
755 net_log_.source()));
756 metrics_->OnStartConnection();
757 return connection_->socket()->Connect(io_callback_);
760 int SocketStream::DoTcpConnectComplete(int result) {
761 // TODO(ukai): if error occured, reconsider proxy after error.
762 if (result != OK) {
763 next_state_ = STATE_CLOSE;
764 return result;
767 if (proxy_mode_ == kTunnelProxy) {
768 if (proxy_info_.is_https())
769 next_state_ = STATE_SECURE_PROXY_CONNECT;
770 else
771 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
772 } else if (proxy_mode_ == kSOCKSProxy) {
773 next_state_ = STATE_SOCKS_CONNECT;
774 } else if (is_secure()) {
775 next_state_ = STATE_SSL_CONNECT;
776 } else {
777 result = DidEstablishConnection();
779 return result;
782 int SocketStream::DoGenerateProxyAuthToken() {
783 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
784 if (!proxy_auth_controller_.get()) {
785 DCHECK(context_);
786 DCHECK(context_->http_transaction_factory());
787 DCHECK(context_->http_transaction_factory()->GetSession());
788 HttpNetworkSession* session =
789 context_->http_transaction_factory()->GetSession();
790 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
791 GURL auth_url(scheme +
792 proxy_info_.proxy_server().host_port_pair().ToString());
793 proxy_auth_controller_ =
794 new HttpAuthController(HttpAuth::AUTH_PROXY,
795 auth_url,
796 session->http_auth_cache(),
797 session->http_auth_handler_factory());
799 HttpRequestInfo request_info;
800 request_info.url = url_;
801 request_info.method = "CONNECT";
802 return proxy_auth_controller_->MaybeGenerateAuthToken(
803 &request_info, io_callback_, net_log_);
806 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
807 if (result != OK) {
808 next_state_ = STATE_CLOSE;
809 return result;
812 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
813 return result;
816 int SocketStream::DoWriteTunnelHeaders() {
817 DCHECK_EQ(kTunnelProxy, proxy_mode_);
819 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
821 if (!tunnel_request_headers_.get()) {
822 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
823 tunnel_request_headers_ = new RequestHeaders();
824 tunnel_request_headers_bytes_sent_ = 0;
826 if (tunnel_request_headers_->headers_.empty()) {
827 HttpRequestHeaders request_headers;
828 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
829 request_headers.SetHeader("Proxy-Connection", "keep-alive");
830 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
831 proxy_auth_controller_->AddAuthorizationHeader(&request_headers);
832 tunnel_request_headers_->headers_ = base::StringPrintf(
833 "CONNECT %s HTTP/1.1\r\n"
834 "%s",
835 GetHostAndPort(url_).c_str(),
836 request_headers.ToString().c_str());
838 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
839 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
840 tunnel_request_headers_bytes_sent_);
841 DCHECK_GT(buf_len, 0);
842 return connection_->socket()->Write(
843 tunnel_request_headers_.get(), buf_len, io_callback_);
846 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
847 DCHECK_EQ(kTunnelProxy, proxy_mode_);
849 if (result < 0) {
850 next_state_ = STATE_CLOSE;
851 return result;
854 tunnel_request_headers_bytes_sent_ += result;
855 if (tunnel_request_headers_bytes_sent_ <
856 tunnel_request_headers_->headers_.size()) {
857 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
858 } else {
859 // Handling a cert error or a client cert request requires reconnection.
860 // DoWriteTunnelHeaders() will be called again.
861 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for
862 // sending |tunnel_request_headers_| correctly.
863 tunnel_request_headers_bytes_sent_ = 0;
864 next_state_ = STATE_READ_TUNNEL_HEADERS;
866 return OK;
869 int SocketStream::DoReadTunnelHeaders() {
870 DCHECK_EQ(kTunnelProxy, proxy_mode_);
872 next_state_ = STATE_READ_TUNNEL_HEADERS_COMPLETE;
874 if (!tunnel_response_headers_.get()) {
875 tunnel_response_headers_ = new ResponseHeaders();
876 tunnel_response_headers_capacity_ = kMaxTunnelResponseHeadersSize;
877 tunnel_response_headers_->Realloc(tunnel_response_headers_capacity_);
878 tunnel_response_headers_len_ = 0;
881 int buf_len = tunnel_response_headers_capacity_ -
882 tunnel_response_headers_len_;
883 tunnel_response_headers_->SetDataOffset(tunnel_response_headers_len_);
884 CHECK(tunnel_response_headers_->data());
886 return connection_->socket()->Read(
887 tunnel_response_headers_.get(), buf_len, io_callback_);
890 int SocketStream::DoReadTunnelHeadersComplete(int result) {
891 DCHECK_EQ(kTunnelProxy, proxy_mode_);
893 if (result < 0) {
894 next_state_ = STATE_CLOSE;
895 return result;
898 if (result == 0) {
899 // 0 indicates end-of-file, so socket was closed.
900 next_state_ = STATE_CLOSE;
901 return ERR_CONNECTION_CLOSED;
904 tunnel_response_headers_len_ += result;
905 DCHECK(tunnel_response_headers_len_ <= tunnel_response_headers_capacity_);
907 int eoh = HttpUtil::LocateEndOfHeaders(
908 tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0);
909 if (eoh == -1) {
910 if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) {
911 next_state_ = STATE_CLOSE;
912 return ERR_RESPONSE_HEADERS_TOO_BIG;
915 next_state_ = STATE_READ_TUNNEL_HEADERS;
916 return OK;
918 // DidReadResponseHeaders
919 scoped_refptr<HttpResponseHeaders> headers;
920 headers = new HttpResponseHeaders(
921 HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh));
922 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
923 // Require the "HTTP/1.x" status line.
924 next_state_ = STATE_CLOSE;
925 return ERR_TUNNEL_CONNECTION_FAILED;
927 switch (headers->response_code()) {
928 case 200: // OK
929 if (is_secure()) {
930 DCHECK_EQ(eoh, tunnel_response_headers_len_);
931 next_state_ = STATE_SSL_CONNECT;
932 } else {
933 result = DidEstablishConnection();
934 if (result < 0) {
935 next_state_ = STATE_CLOSE;
936 return result;
938 if ((eoh < tunnel_response_headers_len_) && delegate_)
939 delegate_->OnReceivedData(
940 this, tunnel_response_headers_->headers() + eoh,
941 tunnel_response_headers_len_ - eoh);
943 return OK;
944 case 407: // Proxy Authentication Required.
945 if (proxy_mode_ != kTunnelProxy)
946 return ERR_UNEXPECTED_PROXY_AUTH;
948 result = proxy_auth_controller_->HandleAuthChallenge(
949 headers, false, true, net_log_);
950 if (result != OK)
951 return result;
952 DCHECK(!proxy_info_.is_empty());
953 next_state_ = STATE_AUTH_REQUIRED;
954 if (proxy_auth_controller_->HaveAuth()) {
955 base::MessageLoop::current()->PostTask(
956 FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
957 return ERR_IO_PENDING;
959 if (delegate_) {
960 // Wait until RestartWithAuth or Close is called.
961 base::MessageLoop::current()->PostTask(
962 FROM_HERE, base::Bind(&SocketStream::DoAuthRequired, this));
963 return ERR_IO_PENDING;
965 break;
966 default:
967 break;
969 next_state_ = STATE_CLOSE;
970 return ERR_TUNNEL_CONNECTION_FAILED;
973 int SocketStream::DoSOCKSConnect() {
974 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
976 next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
978 HostResolver::RequestInfo req_info(HostPortPair::FromURL(url_));
980 DCHECK(!proxy_info_.is_empty());
981 scoped_ptr<StreamSocket> s;
982 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) {
983 s.reset(new SOCKS5ClientSocket(connection_.Pass(), req_info));
984 } else {
985 s.reset(new SOCKSClientSocket(connection_.Pass(),
986 req_info,
987 DEFAULT_PRIORITY,
988 context_->host_resolver()));
990 connection_.reset(new ClientSocketHandle);
991 connection_->SetSocket(s.Pass());
992 metrics_->OnCountConnectionType(SocketStreamMetrics::SOCKS_CONNECTION);
993 return connection_->socket()->Connect(io_callback_);
996 int SocketStream::DoSOCKSConnectComplete(int result) {
997 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
999 if (result == OK) {
1000 if (is_secure())
1001 next_state_ = STATE_SSL_CONNECT;
1002 else
1003 result = DidEstablishConnection();
1004 } else {
1005 next_state_ = STATE_CLOSE;
1007 return result;
1010 int SocketStream::DoSecureProxyConnect() {
1011 DCHECK(factory_);
1012 SSLClientSocketContext ssl_context;
1013 ssl_context.cert_verifier = context_->cert_verifier();
1014 ssl_context.transport_security_state = context_->transport_security_state();
1015 ssl_context.channel_id_service = context_->channel_id_service();
1016 scoped_ptr<StreamSocket> socket(factory_->CreateSSLClientSocket(
1017 connection_.Pass(),
1018 proxy_info_.proxy_server().host_port_pair(),
1019 proxy_ssl_config_,
1020 ssl_context));
1021 connection_.reset(new ClientSocketHandle);
1022 connection_->SetSocket(socket.Pass());
1023 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE;
1024 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION);
1025 return connection_->socket()->Connect(io_callback_);
1028 int SocketStream::DoSecureProxyConnectComplete(int result) {
1029 DCHECK_EQ(STATE_NONE, next_state_);
1030 // Reconnect with client authentication.
1031 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
1032 return HandleCertificateRequest(result, &proxy_ssl_config_);
1034 if (IsCertificateError(result))
1035 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR;
1036 else if (result == OK)
1037 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1038 else
1039 next_state_ = STATE_CLOSE;
1040 return result;
1043 int SocketStream::DoSecureProxyHandleCertError(int result) {
1044 DCHECK_EQ(STATE_NONE, next_state_);
1045 DCHECK(IsCertificateError(result));
1046 result = HandleCertificateError(result);
1047 if (result == ERR_IO_PENDING)
1048 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE;
1049 else
1050 next_state_ = STATE_CLOSE;
1051 return result;
1054 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) {
1055 DCHECK_EQ(STATE_NONE, next_state_);
1056 if (result == OK) {
1057 if (!connection_->socket()->IsConnectedAndIdle())
1058 return AllowCertErrorForReconnection(&proxy_ssl_config_);
1059 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1060 } else {
1061 next_state_ = STATE_CLOSE;
1063 return result;
1066 int SocketStream::DoSSLConnect() {
1067 DCHECK(factory_);
1068 SSLClientSocketContext ssl_context;
1069 ssl_context.cert_verifier = context_->cert_verifier();
1070 ssl_context.transport_security_state = context_->transport_security_state();
1071 ssl_context.channel_id_service = context_->channel_id_service();
1072 scoped_ptr<StreamSocket> socket(
1073 factory_->CreateSSLClientSocket(connection_.Pass(),
1074 HostPortPair::FromURL(url_),
1075 server_ssl_config_,
1076 ssl_context));
1077 connection_.reset(new ClientSocketHandle);
1078 connection_->SetSocket(socket.Pass());
1079 next_state_ = STATE_SSL_CONNECT_COMPLETE;
1080 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION);
1081 return connection_->socket()->Connect(io_callback_);
1084 int SocketStream::DoSSLConnectComplete(int result) {
1085 DCHECK_EQ(STATE_NONE, next_state_);
1086 // Reconnect with client authentication.
1087 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
1088 return HandleCertificateRequest(result, &server_ssl_config_);
1090 if (IsCertificateError(result))
1091 next_state_ = STATE_SSL_HANDLE_CERT_ERROR;
1092 else if (result == OK)
1093 result = DidEstablishConnection();
1094 else
1095 next_state_ = STATE_CLOSE;
1096 return result;
1099 int SocketStream::DoSSLHandleCertError(int result) {
1100 DCHECK_EQ(STATE_NONE, next_state_);
1101 DCHECK(IsCertificateError(result));
1102 result = HandleCertificateError(result);
1103 if (result == OK || result == ERR_IO_PENDING)
1104 next_state_ = STATE_SSL_HANDLE_CERT_ERROR_COMPLETE;
1105 else
1106 next_state_ = STATE_CLOSE;
1107 return result;
1110 int SocketStream::DoSSLHandleCertErrorComplete(int result) {
1111 DCHECK_EQ(STATE_NONE, next_state_);
1112 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible.
1113 // If we use HTTPS and this is the first connection to the SPDY server,
1114 // we should take care of TLS NPN extension here.
1116 if (result == OK) {
1117 if (!connection_->socket()->IsConnectedAndIdle())
1118 return AllowCertErrorForReconnection(&server_ssl_config_);
1119 result = DidEstablishConnection();
1120 } else {
1121 next_state_ = STATE_CLOSE;
1123 return result;
1126 int SocketStream::DoReadWrite(int result) {
1127 if (result < OK) {
1128 next_state_ = STATE_CLOSE;
1129 return result;
1131 if (!connection_->socket() || !connection_->socket()->IsConnected()) {
1132 next_state_ = STATE_CLOSE;
1133 return ERR_CONNECTION_CLOSED;
1136 // If client has requested close(), and there's nothing to write, then
1137 // let's close the socket.
1138 // We don't care about receiving data after the socket is closed.
1139 if (closing_ && !current_write_buf_.get() && pending_write_bufs_.empty()) {
1140 connection_->socket()->Disconnect();
1141 next_state_ = STATE_CLOSE;
1142 return OK;
1145 next_state_ = STATE_READ_WRITE;
1147 // If server already closed the socket, we don't try to read.
1148 if (!server_closed_) {
1149 if (!read_buf_.get()) {
1150 // No read pending and server didn't close the socket.
1151 read_buf_ = new IOBuffer(kReadBufferSize);
1152 result = connection_->socket()->Read(
1153 read_buf_.get(),
1154 kReadBufferSize,
1155 base::Bind(&SocketStream::OnReadCompleted, base::Unretained(this)));
1156 if (result > 0) {
1157 return DidReceiveData(result);
1158 } else if (result == 0) {
1159 // 0 indicates end-of-file, so socket was closed.
1160 next_state_ = STATE_CLOSE;
1161 server_closed_ = true;
1162 return ERR_CONNECTION_CLOSED;
1164 // If read is pending, try write as well.
1165 // Otherwise, return the result and do next loop (to close the
1166 // connection).
1167 if (result != ERR_IO_PENDING) {
1168 next_state_ = STATE_CLOSE;
1169 server_closed_ = true;
1170 return result;
1173 // Read is pending.
1174 DCHECK(read_buf_.get());
1177 if (waiting_for_write_completion_)
1178 return ERR_IO_PENDING;
1180 if (!current_write_buf_.get()) {
1181 if (pending_write_bufs_.empty()) {
1182 // Nothing buffered for send.
1183 return ERR_IO_PENDING;
1186 current_write_buf_ = new DrainableIOBuffer(
1187 pending_write_bufs_.front().get(), pending_write_bufs_.front()->size());
1188 pending_write_bufs_.pop_front();
1191 result = connection_->socket()->Write(
1192 current_write_buf_.get(),
1193 current_write_buf_->BytesRemaining(),
1194 base::Bind(&SocketStream::OnWriteCompleted, base::Unretained(this)));
1196 if (result == ERR_IO_PENDING) {
1197 waiting_for_write_completion_ = true;
1198 } else if (result < 0) {
1199 // Shortcut. Enter STATE_CLOSE now by changing next_state_ here than by
1200 // calling DoReadWrite() again with the error code.
1201 next_state_ = STATE_CLOSE;
1202 } else if (result > 0) {
1203 // Write is not pending. Return OK and do next loop.
1204 DidSendData(result);
1205 result = OK;
1208 return result;
1211 GURL SocketStream::ProxyAuthOrigin() const {
1212 DCHECK(!proxy_info_.is_empty());
1213 return GURL("http://" +
1214 proxy_info_.proxy_server().host_port_pair().ToString());
1217 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1218 if (ssl_config->send_client_cert) {
1219 // We already have performed SSL client authentication once and failed.
1220 return result;
1223 DCHECK(connection_->socket());
1224 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1225 SSLClientSocket* ssl_socket =
1226 static_cast<SSLClientSocket*>(connection_->socket());
1227 ssl_socket->GetSSLCertRequestInfo(cert_request_info.get());
1229 HttpTransactionFactory* factory = context_->http_transaction_factory();
1230 if (!factory)
1231 return result;
1232 scoped_refptr<HttpNetworkSession> session = factory->GetSession();
1233 if (!session.get())
1234 return result;
1236 // If the user selected one of the certificates in client_certs or declined
1237 // to provide one for this server before, use the past decision
1238 // automatically.
1239 scoped_refptr<X509Certificate> client_cert;
1240 if (!session->ssl_client_auth_cache()->Lookup(
1241 cert_request_info->host_and_port, &client_cert)) {
1242 return result;
1245 // Note: |client_cert| may be NULL, indicating that the caller
1246 // wishes to proceed anonymously (eg: continue the handshake
1247 // without sending a client cert)
1249 // Check that the certificate selected is still a certificate the server
1250 // is likely to accept, based on the criteria supplied in the
1251 // CertificateRequest message.
1252 const std::vector<std::string>& cert_authorities =
1253 cert_request_info->cert_authorities;
1254 if (client_cert.get() && !cert_authorities.empty() &&
1255 !client_cert->IsIssuedByEncoded(cert_authorities)) {
1256 return result;
1259 ssl_config->send_client_cert = true;
1260 ssl_config->client_cert = client_cert;
1261 next_state_ = STATE_TCP_CONNECT;
1262 return OK;
1265 int SocketStream::AllowCertErrorForReconnection(SSLConfig* ssl_config) {
1266 DCHECK(ssl_config);
1267 // The SSL handshake didn't finish, or the server closed the SSL connection.
1268 // So, we should restart establishing connection with the certificate in
1269 // allowed bad certificates in |ssl_config|.
1270 // See also net/http/http_network_transaction.cc HandleCertificateError() and
1271 // RestartIgnoringLastError().
1272 SSLClientSocket* ssl_socket =
1273 static_cast<SSLClientSocket*>(connection_->socket());
1274 SSLInfo ssl_info;
1275 ssl_socket->GetSSLInfo(&ssl_info);
1276 if (ssl_info.cert.get() == NULL ||
1277 ssl_config->IsAllowedBadCert(ssl_info.cert.get(), NULL)) {
1278 // If we already have the certificate in the set of allowed bad
1279 // certificates, we did try it and failed again, so we should not
1280 // retry again: the connection should fail at last.
1281 next_state_ = STATE_CLOSE;
1282 return ERR_UNEXPECTED;
1284 // Add the bad certificate to the set of allowed certificates in the
1285 // SSL config object.
1286 SSLConfig::CertAndStatus bad_cert;
1287 if (!X509Certificate::GetDEREncoded(ssl_info.cert->os_cert_handle(),
1288 &bad_cert.der_cert)) {
1289 next_state_ = STATE_CLOSE;
1290 return ERR_UNEXPECTED;
1292 bad_cert.cert_status = ssl_info.cert_status;
1293 ssl_config->allowed_bad_certs.push_back(bad_cert);
1294 // Restart connection ignoring the bad certificate.
1295 connection_->socket()->Disconnect();
1296 connection_->SetSocket(scoped_ptr<StreamSocket>());
1297 next_state_ = STATE_TCP_CONNECT;
1298 return OK;
1301 void SocketStream::DoAuthRequired() {
1302 if (delegate_ && proxy_auth_controller_.get())
1303 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1304 else
1305 DoLoop(ERR_UNEXPECTED);
1308 void SocketStream::DoRestartWithAuth() {
1309 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
1310 tunnel_request_headers_ = NULL;
1311 tunnel_request_headers_bytes_sent_ = 0;
1312 tunnel_response_headers_ = NULL;
1313 tunnel_response_headers_capacity_ = 0;
1314 tunnel_response_headers_len_ = 0;
1316 next_state_ = STATE_TCP_CONNECT;
1317 DoLoop(OK);
1320 int SocketStream::HandleCertificateError(int result) {
1321 DCHECK(IsCertificateError(result));
1322 SSLClientSocket* ssl_socket =
1323 static_cast<SSLClientSocket*>(connection_->socket());
1324 DCHECK(ssl_socket);
1326 if (!context_)
1327 return result;
1329 if (SSLClientSocket::IgnoreCertError(result, LOAD_IGNORE_ALL_CERT_ERRORS)) {
1330 const HttpNetworkSession::Params* session_params =
1331 context_->GetNetworkSessionParams();
1332 if (session_params && session_params->ignore_certificate_errors)
1333 return OK;
1336 if (!delegate_)
1337 return result;
1339 SSLInfo ssl_info;
1340 ssl_socket->GetSSLInfo(&ssl_info);
1342 TransportSecurityState* state = context_->transport_security_state();
1343 const bool fatal = state && state->ShouldSSLErrorsBeFatal(url_.host());
1345 delegate_->OnSSLCertificateError(this, ssl_info, fatal);
1346 return ERR_IO_PENDING;
1349 CookieStore* SocketStream::cookie_store() const {
1350 return cookie_store_.get();
1353 } // namespace net