Add default implementations for AppWindowRegistry::Observer notifications.
[chromium-blink-merge.git] / net / socket_stream / socket_stream.cc
blob5979dd19c9288cf8e9b5d76bbe79f0930ed56b77
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/net_errors.h"
25 #include "net/base/net_util.h"
26 #include "net/dns/host_resolver.h"
27 #include "net/http/http_auth_controller.h"
28 #include "net/http/http_network_session.h"
29 #include "net/http/http_request_headers.h"
30 #include "net/http/http_request_info.h"
31 #include "net/http/http_response_headers.h"
32 #include "net/http/http_stream_factory.h"
33 #include "net/http/http_transaction_factory.h"
34 #include "net/http/http_util.h"
35 #include "net/socket/client_socket_factory.h"
36 #include "net/socket/client_socket_handle.h"
37 #include "net/socket/socks5_client_socket.h"
38 #include "net/socket/socks_client_socket.h"
39 #include "net/socket/ssl_client_socket.h"
40 #include "net/socket/tcp_client_socket.h"
41 #include "net/socket_stream/socket_stream_metrics.h"
42 #include "net/ssl/ssl_cert_request_info.h"
43 #include "net/ssl/ssl_info.h"
44 #include "net/url_request/url_request.h"
45 #include "net/url_request/url_request_context.h"
47 static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes.
48 static const int kReadBufferSize = 4096;
50 namespace net {
52 int SocketStream::Delegate::OnStartOpenConnection(
53 SocketStream* socket, const CompletionCallback& callback) {
54 return OK;
57 void SocketStream::Delegate::OnAuthRequired(SocketStream* socket,
58 AuthChallengeInfo* auth_info) {
59 // By default, no credential is available and close the connection.
60 socket->Close();
63 void SocketStream::Delegate::OnSSLCertificateError(
64 SocketStream* socket,
65 const SSLInfo& ssl_info,
66 bool fatal) {
67 socket->CancelWithSSLError(ssl_info);
70 bool SocketStream::Delegate::CanGetCookies(SocketStream* socket,
71 const GURL& url) {
72 return true;
75 bool SocketStream::Delegate::CanSetCookie(SocketStream* request,
76 const GURL& url,
77 const std::string& cookie_line,
78 CookieOptions* options) {
79 return true;
82 SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {}
84 void SocketStream::ResponseHeaders::Realloc(size_t new_size) {
85 headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size)));
88 SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; }
90 SocketStream::SocketStream(const GURL& url, Delegate* delegate,
91 URLRequestContext* context,
92 CookieStore* cookie_store)
93 : delegate_(delegate),
94 url_(url),
95 max_pending_send_allowed_(kMaxPendingSendAllowed),
96 context_(context),
97 next_state_(STATE_NONE),
98 factory_(ClientSocketFactory::GetDefaultFactory()),
99 proxy_mode_(kDirectConnection),
100 proxy_url_(url),
101 pac_request_(NULL),
102 connection_(new ClientSocketHandle),
103 privacy_mode_(PRIVACY_MODE_DISABLED),
104 // Unretained() is required; without it, Bind() creates a circular
105 // dependency and the SocketStream object will not be freed.
106 io_callback_(base::Bind(&SocketStream::OnIOCompleted,
107 base::Unretained(this))),
108 read_buf_(NULL),
109 current_write_buf_(NULL),
110 waiting_for_write_completion_(false),
111 closing_(false),
112 server_closed_(false),
113 metrics_(new SocketStreamMetrics(url)),
114 cookie_store_(cookie_store) {
115 DCHECK(base::MessageLoop::current())
116 << "The current base::MessageLoop must exist";
117 DCHECK(base::MessageLoopForIO::IsCurrent())
118 << "The current base::MessageLoop must be TYPE_IO";
119 DCHECK(delegate_);
121 if (context_) {
122 if (!cookie_store_)
123 cookie_store_ = context_->cookie_store();
125 net_log_ = BoundNetLog::Make(
126 context->net_log(),
127 NetLog::SOURCE_SOCKET_STREAM);
129 net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
133 SocketStream::UserData* SocketStream::GetUserData(
134 const void* key) const {
135 UserDataMap::const_iterator found = user_data_.find(key);
136 if (found != user_data_.end())
137 return found->second.get();
138 return NULL;
141 void SocketStream::SetUserData(const void* key, UserData* data) {
142 user_data_[key] = linked_ptr<UserData>(data);
145 bool SocketStream::is_secure() const {
146 return url_.SchemeIs("wss");
149 void SocketStream::DetachContext() {
150 if (!context_)
151 return;
153 if (pac_request_) {
154 context_->proxy_service()->CancelPacRequest(pac_request_);
155 pac_request_ = NULL;
158 net_log_.EndEvent(NetLog::TYPE_REQUEST_ALIVE);
159 net_log_ = BoundNetLog();
161 context_ = NULL;
162 cookie_store_ = NULL;
165 void SocketStream::CheckPrivacyMode() {
166 if (context_ && context_->network_delegate()) {
167 bool enable = context_->network_delegate()->CanEnablePrivacyMode(url_,
168 url_);
169 privacy_mode_ = enable ? PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED;
170 // Disable Channel ID if privacy mode is enabled.
171 if (enable)
172 server_ssl_config_.channel_id_enabled = false;
176 void SocketStream::Connect() {
177 DCHECK(base::MessageLoop::current())
178 << "The current base::MessageLoop must exist";
179 DCHECK(base::MessageLoopForIO::IsCurrent())
180 << "The current base::MessageLoop must be TYPE_IO";
181 if (context_) {
182 context_->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
183 proxy_ssl_config_ = server_ssl_config_;
185 CheckPrivacyMode();
187 DCHECK_EQ(next_state_, STATE_NONE);
189 AddRef(); // Released in Finish()
190 // Open a connection asynchronously, so that delegate won't be called
191 // back before returning Connect().
192 next_state_ = STATE_BEFORE_CONNECT;
193 net_log_.BeginEvent(
194 NetLog::TYPE_SOCKET_STREAM_CONNECT,
195 NetLog::StringCallback("url", &url_.possibly_invalid_spec()));
196 base::MessageLoop::current()->PostTask(
197 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
200 size_t SocketStream::GetTotalSizeOfPendingWriteBufs() const {
201 size_t total_size = 0;
202 for (PendingDataQueue::const_iterator iter = pending_write_bufs_.begin();
203 iter != pending_write_bufs_.end();
204 ++iter)
205 total_size += (*iter)->size();
206 return total_size;
209 bool SocketStream::SendData(const char* data, int len) {
210 DCHECK(base::MessageLoop::current())
211 << "The current base::MessageLoop must exist";
212 DCHECK(base::MessageLoopForIO::IsCurrent())
213 << "The current base::MessageLoop must be TYPE_IO";
214 DCHECK_GT(len, 0);
216 if (!connection_->socket() ||
217 !connection_->socket()->IsConnected() || next_state_ == STATE_NONE) {
218 return false;
221 int total_buffered_bytes = len;
222 if (current_write_buf_.get()) {
223 // Since
224 // - the purpose of this check is to limit the amount of buffer used by
225 // this instance.
226 // - the DrainableIOBuffer doesn't release consumed memory.
227 // we need to use not BytesRemaining() but size() here.
228 total_buffered_bytes += current_write_buf_->size();
230 total_buffered_bytes += GetTotalSizeOfPendingWriteBufs();
231 if (total_buffered_bytes > max_pending_send_allowed_)
232 return false;
234 // TODO(tyoshino): Split data into smaller chunks e.g. 8KiB to free consumed
235 // buffer progressively
236 pending_write_bufs_.push_back(make_scoped_refptr(
237 new IOBufferWithSize(len)));
238 memcpy(pending_write_bufs_.back()->data(), data, len);
240 // If current_write_buf_ is not NULL, it means that a) there's ongoing write
241 // operation or b) the connection is being closed. If a), the buffer we just
242 // pushed will be automatically handled when the completion callback runs
243 // the loop, and therefore we don't need to enqueue DoLoop(). If b), it's ok
244 // to do nothing. If current_write_buf_ is NULL, to make sure DoLoop() is
245 // ran soon, enequeue it.
246 if (!current_write_buf_.get()) {
247 // Send pending data asynchronously, so that delegate won't be called
248 // back before returning from SendData().
249 base::MessageLoop::current()->PostTask(
250 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
253 return true;
256 void SocketStream::Close() {
257 DCHECK(base::MessageLoop::current())
258 << "The current base::MessageLoop must exist";
259 DCHECK(base::MessageLoopForIO::IsCurrent())
260 << "The current base::MessageLoop must be TYPE_IO";
261 // If next_state_ is STATE_NONE, the socket was not opened, or already
262 // closed. So, return immediately.
263 // Otherwise, it might call Finish() more than once, so breaks balance
264 // of AddRef() and Release() in Connect() and Finish(), respectively.
265 if (next_state_ == STATE_NONE)
266 return;
267 base::MessageLoop::current()->PostTask(
268 FROM_HERE, base::Bind(&SocketStream::DoClose, this));
271 void SocketStream::RestartWithAuth(const AuthCredentials& credentials) {
272 DCHECK(base::MessageLoop::current())
273 << "The current base::MessageLoop must exist";
274 DCHECK(base::MessageLoopForIO::IsCurrent())
275 << "The current base::MessageLoop must be TYPE_IO";
276 DCHECK(proxy_auth_controller_.get());
277 if (!connection_->socket()) {
278 DVLOG(1) << "Socket is closed before restarting with auth.";
279 return;
282 proxy_auth_controller_->ResetAuth(credentials);
284 base::MessageLoop::current()->PostTask(
285 FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
288 void SocketStream::DetachDelegate() {
289 if (!delegate_)
290 return;
291 delegate_ = NULL;
292 // Prevent the rest of the function from executing if we are being called from
293 // within Finish().
294 if (next_state_ == STATE_NONE)
295 return;
296 net_log_.AddEvent(NetLog::TYPE_CANCELLED);
297 // We don't need to send pending data when client detach the delegate.
298 pending_write_bufs_.clear();
299 Close();
302 const ProxyServer& SocketStream::proxy_server() const {
303 return proxy_info_.proxy_server();
306 void SocketStream::SetClientSocketFactory(
307 ClientSocketFactory* factory) {
308 DCHECK(factory);
309 factory_ = factory;
312 void SocketStream::CancelWithError(int error) {
313 base::MessageLoop::current()->PostTask(
314 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, error));
317 void SocketStream::CancelWithSSLError(const SSLInfo& ssl_info) {
318 CancelWithError(MapCertStatusToNetError(ssl_info.cert_status));
321 void SocketStream::ContinueDespiteError() {
322 base::MessageLoop::current()->PostTask(
323 FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
326 SocketStream::~SocketStream() {
327 DetachContext();
328 DCHECK(!delegate_);
329 DCHECK(!pac_request_);
332 SocketStream::RequestHeaders::~RequestHeaders() { data_ = NULL; }
334 void SocketStream::set_addresses(const AddressList& addresses) {
335 addresses_ = addresses;
338 void SocketStream::DoClose() {
339 closing_ = true;
340 // If next_state_ is:
341 // - STATE_TCP_CONNECT_COMPLETE, it's waiting other socket establishing
342 // connection.
343 // - STATE_AUTH_REQUIRED, it's waiting for restarting.
344 // - STATE_RESOLVE_PROTOCOL_COMPLETE, it's waiting for delegate_ to finish
345 // OnStartOpenConnection method call
346 // In these states, we'll close the SocketStream now.
347 if (next_state_ == STATE_TCP_CONNECT_COMPLETE ||
348 next_state_ == STATE_AUTH_REQUIRED ||
349 next_state_ == STATE_RESOLVE_PROTOCOL_COMPLETE) {
350 DoLoop(ERR_ABORTED);
351 return;
353 // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close
354 // the SocketStream.
355 // If it's writing now, we should defer the closing after the current
356 // writing is completed.
357 if (next_state_ == STATE_READ_WRITE && !current_write_buf_.get())
358 DoLoop(ERR_ABORTED);
360 // In other next_state_, we'll wait for callback of other APIs, such as
361 // ResolveProxy().
364 void SocketStream::Finish(int result) {
365 DCHECK(base::MessageLoop::current())
366 << "The current base::MessageLoop must exist";
367 DCHECK(base::MessageLoopForIO::IsCurrent())
368 << "The current base::MessageLoop must be TYPE_IO";
369 DCHECK_LE(result, OK);
370 if (result == OK)
371 result = ERR_CONNECTION_CLOSED;
372 DCHECK_EQ(next_state_, STATE_NONE);
373 DVLOG(1) << "Finish result=" << ErrorToString(result);
375 metrics_->OnClose();
377 if (result != ERR_CONNECTION_CLOSED && delegate_)
378 delegate_->OnError(this, result);
379 if (result != ERR_PROTOCOL_SWITCHED && delegate_)
380 delegate_->OnClose(this);
381 delegate_ = NULL;
383 Release();
386 int SocketStream::DidEstablishConnection() {
387 if (!connection_->socket() || !connection_->socket()->IsConnected()) {
388 next_state_ = STATE_CLOSE;
389 return ERR_CONNECTION_FAILED;
391 next_state_ = STATE_READ_WRITE;
392 metrics_->OnConnected();
394 net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT);
395 if (delegate_)
396 delegate_->OnConnected(this, max_pending_send_allowed_);
398 return OK;
401 int SocketStream::DidReceiveData(int result) {
402 DCHECK(read_buf_.get());
403 DCHECK_GT(result, 0);
404 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_RECEIVED);
405 int len = result;
406 metrics_->OnRead(len);
407 if (delegate_) {
408 // Notify recevied data to delegate.
409 delegate_->OnReceivedData(this, read_buf_->data(), len);
411 read_buf_ = NULL;
412 return OK;
415 void SocketStream::DidSendData(int result) {
416 DCHECK_GT(result, 0);
417 DCHECK(current_write_buf_.get());
418 net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_SENT);
420 int bytes_sent = result;
422 metrics_->OnWrite(bytes_sent);
424 current_write_buf_->DidConsume(result);
426 if (current_write_buf_->BytesRemaining())
427 return;
429 size_t bytes_freed = current_write_buf_->size();
431 current_write_buf_ = NULL;
433 // We freed current_write_buf_ and this instance is now able to accept more
434 // data via SendData() (note that DidConsume() doesn't free consumed memory).
435 // We can tell that to delegate_ by calling OnSentData().
436 if (delegate_)
437 delegate_->OnSentData(this, bytes_freed);
440 void SocketStream::OnIOCompleted(int result) {
441 DoLoop(result);
444 void SocketStream::OnReadCompleted(int result) {
445 if (result == 0) {
446 // 0 indicates end-of-file, so socket was closed.
447 // Don't close the socket if it's still writing.
448 server_closed_ = true;
449 } else if (result > 0 && read_buf_.get()) {
450 result = DidReceiveData(result);
452 DoLoop(result);
455 void SocketStream::OnWriteCompleted(int result) {
456 waiting_for_write_completion_ = false;
457 if (result > 0) {
458 DidSendData(result);
459 result = OK;
461 DoLoop(result);
464 void SocketStream::DoLoop(int result) {
465 if (next_state_ == STATE_NONE)
466 return;
468 // If context was not set, close immediately.
469 if (!context_)
470 next_state_ = STATE_CLOSE;
472 do {
473 State state = next_state_;
474 next_state_ = STATE_NONE;
475 switch (state) {
476 case STATE_BEFORE_CONNECT:
477 DCHECK_EQ(OK, result);
478 result = DoBeforeConnect();
479 break;
480 case STATE_BEFORE_CONNECT_COMPLETE:
481 result = DoBeforeConnectComplete(result);
482 break;
483 case STATE_RESOLVE_PROXY:
484 DCHECK_EQ(OK, result);
485 result = DoResolveProxy();
486 break;
487 case STATE_RESOLVE_PROXY_COMPLETE:
488 result = DoResolveProxyComplete(result);
489 break;
490 case STATE_RESOLVE_HOST:
491 DCHECK_EQ(OK, result);
492 result = DoResolveHost();
493 break;
494 case STATE_RESOLVE_HOST_COMPLETE:
495 result = DoResolveHostComplete(result);
496 break;
497 case STATE_RESOLVE_PROTOCOL:
498 result = DoResolveProtocol(result);
499 break;
500 case STATE_RESOLVE_PROTOCOL_COMPLETE:
501 result = DoResolveProtocolComplete(result);
502 break;
503 case STATE_TCP_CONNECT:
504 result = DoTcpConnect(result);
505 break;
506 case STATE_TCP_CONNECT_COMPLETE:
507 result = DoTcpConnectComplete(result);
508 break;
509 case STATE_GENERATE_PROXY_AUTH_TOKEN:
510 result = DoGenerateProxyAuthToken();
511 break;
512 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
513 result = DoGenerateProxyAuthTokenComplete(result);
514 break;
515 case STATE_WRITE_TUNNEL_HEADERS:
516 DCHECK_EQ(OK, result);
517 result = DoWriteTunnelHeaders();
518 break;
519 case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
520 result = DoWriteTunnelHeadersComplete(result);
521 break;
522 case STATE_READ_TUNNEL_HEADERS:
523 DCHECK_EQ(OK, result);
524 result = DoReadTunnelHeaders();
525 break;
526 case STATE_READ_TUNNEL_HEADERS_COMPLETE:
527 result = DoReadTunnelHeadersComplete(result);
528 break;
529 case STATE_SOCKS_CONNECT:
530 DCHECK_EQ(OK, result);
531 result = DoSOCKSConnect();
532 break;
533 case STATE_SOCKS_CONNECT_COMPLETE:
534 result = DoSOCKSConnectComplete(result);
535 break;
536 case STATE_SECURE_PROXY_CONNECT:
537 DCHECK_EQ(OK, result);
538 result = DoSecureProxyConnect();
539 break;
540 case STATE_SECURE_PROXY_CONNECT_COMPLETE:
541 result = DoSecureProxyConnectComplete(result);
542 break;
543 case STATE_SECURE_PROXY_HANDLE_CERT_ERROR:
544 result = DoSecureProxyHandleCertError(result);
545 break;
546 case STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE:
547 result = DoSecureProxyHandleCertErrorComplete(result);
548 break;
549 case STATE_SSL_CONNECT:
550 DCHECK_EQ(OK, result);
551 result = DoSSLConnect();
552 break;
553 case STATE_SSL_CONNECT_COMPLETE:
554 result = DoSSLConnectComplete(result);
555 break;
556 case STATE_SSL_HANDLE_CERT_ERROR:
557 result = DoSSLHandleCertError(result);
558 break;
559 case STATE_SSL_HANDLE_CERT_ERROR_COMPLETE:
560 result = DoSSLHandleCertErrorComplete(result);
561 break;
562 case STATE_READ_WRITE:
563 result = DoReadWrite(result);
564 break;
565 case STATE_AUTH_REQUIRED:
566 // It might be called when DoClose is called while waiting in
567 // STATE_AUTH_REQUIRED.
568 Finish(result);
569 return;
570 case STATE_CLOSE:
571 DCHECK_LE(result, OK);
572 Finish(result);
573 return;
574 default:
575 NOTREACHED() << "bad state " << state;
576 Finish(result);
577 return;
579 if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED)
580 continue;
581 // If the connection is not established yet and had actual errors,
582 // record the error. In next iteration, it will close the connection.
583 if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) {
584 net_log_.EndEventWithNetErrorCode(
585 NetLog::TYPE_SOCKET_STREAM_CONNECT, result);
587 } while (result != ERR_IO_PENDING);
590 int SocketStream::DoBeforeConnect() {
591 next_state_ = STATE_BEFORE_CONNECT_COMPLETE;
592 if (!context_ || !context_->network_delegate())
593 return OK;
595 int result = context_->network_delegate()->NotifyBeforeSocketStreamConnect(
596 this, io_callback_);
597 if (result != OK && result != ERR_IO_PENDING)
598 next_state_ = STATE_CLOSE;
600 return result;
603 int SocketStream::DoBeforeConnectComplete(int result) {
604 DCHECK_NE(ERR_IO_PENDING, result);
606 if (result == OK)
607 next_state_ = STATE_RESOLVE_PROXY;
608 else
609 next_state_ = STATE_CLOSE;
611 return result;
614 int SocketStream::DoResolveProxy() {
615 DCHECK(context_);
616 DCHECK(!pac_request_);
617 next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
619 if (!proxy_url_.is_valid()) {
620 next_state_ = STATE_CLOSE;
621 return ERR_INVALID_ARGUMENT;
624 // TODO(toyoshim): Check server advertisement of SPDY through the HTTP
625 // Alternate-Protocol header, then switch to SPDY if SPDY is available.
626 // Usually we already have a session to the SPDY server because JavaScript
627 // running WebSocket itself would be served by SPDY. But, in some situation
628 // (E.g. Used by Chrome Extensions or used for cross origin connection), this
629 // connection might be the first one. At that time, we should check
630 // Alternate-Protocol header here for ws:// or TLS NPN extension for wss:// .
632 return context_->proxy_service()->ResolveProxy(
633 proxy_url_, &proxy_info_, io_callback_, &pac_request_, net_log_);
636 int SocketStream::DoResolveProxyComplete(int result) {
637 pac_request_ = NULL;
638 if (result != OK) {
639 DVLOG(1) << "Failed to resolve proxy: " << result;
640 if (delegate_)
641 delegate_->OnError(this, result);
642 proxy_info_.UseDirect();
644 if (proxy_info_.is_direct()) {
645 // If proxy was not found for original URL (i.e. websocket URL),
646 // try again with https URL, like Safari implementation.
647 // Note that we don't want to use http proxy, because we'll use tunnel
648 // proxy using CONNECT method, which is used by https proxy.
649 if (!proxy_url_.SchemeIs("https")) {
650 const std::string scheme = "https";
651 GURL::Replacements repl;
652 repl.SetSchemeStr(scheme);
653 proxy_url_ = url_.ReplaceComponents(repl);
654 DVLOG(1) << "Try https proxy: " << proxy_url_;
655 next_state_ = STATE_RESOLVE_PROXY;
656 return OK;
660 if (proxy_info_.is_empty()) {
661 // No proxies/direct to choose from. This happens when we don't support any
662 // of the proxies in the returned list.
663 return ERR_NO_SUPPORTED_PROXIES;
666 next_state_ = STATE_RESOLVE_HOST;
667 return OK;
670 int SocketStream::DoResolveHost() {
671 next_state_ = STATE_RESOLVE_HOST_COMPLETE;
673 DCHECK(!proxy_info_.is_empty());
674 if (proxy_info_.is_direct())
675 proxy_mode_ = kDirectConnection;
676 else if (proxy_info_.proxy_server().is_socks())
677 proxy_mode_ = kSOCKSProxy;
678 else
679 proxy_mode_ = kTunnelProxy;
681 // Determine the host and port to connect to.
682 HostPortPair host_port_pair;
683 if (proxy_mode_ != kDirectConnection) {
684 host_port_pair = proxy_info_.proxy_server().host_port_pair();
685 } else {
686 host_port_pair = HostPortPair::FromURL(url_);
689 HostResolver::RequestInfo resolve_info(host_port_pair);
691 DCHECK(context_->host_resolver());
692 resolver_.reset(new SingleRequestHostResolver(context_->host_resolver()));
693 return resolver_->Resolve(resolve_info,
694 DEFAULT_PRIORITY,
695 &addresses_,
696 base::Bind(&SocketStream::OnIOCompleted, this),
697 net_log_);
700 int SocketStream::DoResolveHostComplete(int result) {
701 if (result == OK)
702 next_state_ = STATE_RESOLVE_PROTOCOL;
703 else
704 next_state_ = STATE_CLOSE;
705 // TODO(ukai): if error occured, reconsider proxy after error.
706 return result;
709 int SocketStream::DoResolveProtocol(int result) {
710 DCHECK_EQ(OK, result);
712 if (!delegate_) {
713 next_state_ = STATE_CLOSE;
714 return result;
717 next_state_ = STATE_RESOLVE_PROTOCOL_COMPLETE;
718 result = delegate_->OnStartOpenConnection(this, io_callback_);
719 if (result == ERR_IO_PENDING)
720 metrics_->OnWaitConnection();
721 else if (result != OK && result != ERR_PROTOCOL_SWITCHED)
722 next_state_ = STATE_CLOSE;
723 return result;
726 int SocketStream::DoResolveProtocolComplete(int result) {
727 DCHECK_NE(ERR_IO_PENDING, result);
729 if (result == ERR_PROTOCOL_SWITCHED) {
730 next_state_ = STATE_CLOSE;
731 metrics_->OnCountWireProtocolType(
732 SocketStreamMetrics::WIRE_PROTOCOL_SPDY);
733 } else if (result == OK) {
734 next_state_ = STATE_TCP_CONNECT;
735 metrics_->OnCountWireProtocolType(
736 SocketStreamMetrics::WIRE_PROTOCOL_WEBSOCKET);
737 } else {
738 next_state_ = STATE_CLOSE;
740 return result;
743 int SocketStream::DoTcpConnect(int result) {
744 if (result != OK) {
745 next_state_ = STATE_CLOSE;
746 return result;
748 next_state_ = STATE_TCP_CONNECT_COMPLETE;
749 DCHECK(factory_);
750 connection_->SetSocket(
751 factory_->CreateTransportClientSocket(addresses_,
752 net_log_.net_log(),
753 net_log_.source()));
754 metrics_->OnStartConnection();
755 return connection_->socket()->Connect(io_callback_);
758 int SocketStream::DoTcpConnectComplete(int result) {
759 // TODO(ukai): if error occured, reconsider proxy after error.
760 if (result != OK) {
761 next_state_ = STATE_CLOSE;
762 return result;
765 if (proxy_mode_ == kTunnelProxy) {
766 if (proxy_info_.is_https())
767 next_state_ = STATE_SECURE_PROXY_CONNECT;
768 else
769 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
770 } else if (proxy_mode_ == kSOCKSProxy) {
771 next_state_ = STATE_SOCKS_CONNECT;
772 } else if (is_secure()) {
773 next_state_ = STATE_SSL_CONNECT;
774 } else {
775 result = DidEstablishConnection();
777 return result;
780 int SocketStream::DoGenerateProxyAuthToken() {
781 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
782 if (!proxy_auth_controller_.get()) {
783 DCHECK(context_);
784 DCHECK(context_->http_transaction_factory());
785 DCHECK(context_->http_transaction_factory()->GetSession());
786 HttpNetworkSession* session =
787 context_->http_transaction_factory()->GetSession();
788 const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
789 GURL auth_url(scheme +
790 proxy_info_.proxy_server().host_port_pair().ToString());
791 proxy_auth_controller_ =
792 new HttpAuthController(HttpAuth::AUTH_PROXY,
793 auth_url,
794 session->http_auth_cache(),
795 session->http_auth_handler_factory());
797 HttpRequestInfo request_info;
798 request_info.url = url_;
799 request_info.method = "CONNECT";
800 return proxy_auth_controller_->MaybeGenerateAuthToken(
801 &request_info, io_callback_, net_log_);
804 int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
805 if (result != OK) {
806 next_state_ = STATE_CLOSE;
807 return result;
810 next_state_ = STATE_WRITE_TUNNEL_HEADERS;
811 return result;
814 int SocketStream::DoWriteTunnelHeaders() {
815 DCHECK_EQ(kTunnelProxy, proxy_mode_);
817 next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
819 if (!tunnel_request_headers_.get()) {
820 metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
821 tunnel_request_headers_ = new RequestHeaders();
822 tunnel_request_headers_bytes_sent_ = 0;
824 if (tunnel_request_headers_->headers_.empty()) {
825 HttpRequestHeaders request_headers;
826 request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
827 request_headers.SetHeader("Proxy-Connection", "keep-alive");
828 if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
829 proxy_auth_controller_->AddAuthorizationHeader(&request_headers);
830 tunnel_request_headers_->headers_ = base::StringPrintf(
831 "CONNECT %s HTTP/1.1\r\n"
832 "%s",
833 GetHostAndPort(url_).c_str(),
834 request_headers.ToString().c_str());
836 tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
837 int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
838 tunnel_request_headers_bytes_sent_);
839 DCHECK_GT(buf_len, 0);
840 return connection_->socket()->Write(
841 tunnel_request_headers_.get(), buf_len, io_callback_);
844 int SocketStream::DoWriteTunnelHeadersComplete(int result) {
845 DCHECK_EQ(kTunnelProxy, proxy_mode_);
847 if (result < 0) {
848 next_state_ = STATE_CLOSE;
849 return result;
852 tunnel_request_headers_bytes_sent_ += result;
853 if (tunnel_request_headers_bytes_sent_ <
854 tunnel_request_headers_->headers_.size()) {
855 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
856 } else {
857 // Handling a cert error or a client cert request requires reconnection.
858 // DoWriteTunnelHeaders() will be called again.
859 // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for
860 // sending |tunnel_request_headers_| correctly.
861 tunnel_request_headers_bytes_sent_ = 0;
862 next_state_ = STATE_READ_TUNNEL_HEADERS;
864 return OK;
867 int SocketStream::DoReadTunnelHeaders() {
868 DCHECK_EQ(kTunnelProxy, proxy_mode_);
870 next_state_ = STATE_READ_TUNNEL_HEADERS_COMPLETE;
872 if (!tunnel_response_headers_.get()) {
873 tunnel_response_headers_ = new ResponseHeaders();
874 tunnel_response_headers_capacity_ = kMaxTunnelResponseHeadersSize;
875 tunnel_response_headers_->Realloc(tunnel_response_headers_capacity_);
876 tunnel_response_headers_len_ = 0;
879 int buf_len = tunnel_response_headers_capacity_ -
880 tunnel_response_headers_len_;
881 tunnel_response_headers_->SetDataOffset(tunnel_response_headers_len_);
882 CHECK(tunnel_response_headers_->data());
884 return connection_->socket()->Read(
885 tunnel_response_headers_.get(), buf_len, io_callback_);
888 int SocketStream::DoReadTunnelHeadersComplete(int result) {
889 DCHECK_EQ(kTunnelProxy, proxy_mode_);
891 if (result < 0) {
892 next_state_ = STATE_CLOSE;
893 return result;
896 if (result == 0) {
897 // 0 indicates end-of-file, so socket was closed.
898 next_state_ = STATE_CLOSE;
899 return ERR_CONNECTION_CLOSED;
902 tunnel_response_headers_len_ += result;
903 DCHECK(tunnel_response_headers_len_ <= tunnel_response_headers_capacity_);
905 int eoh = HttpUtil::LocateEndOfHeaders(
906 tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0);
907 if (eoh == -1) {
908 if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) {
909 next_state_ = STATE_CLOSE;
910 return ERR_RESPONSE_HEADERS_TOO_BIG;
913 next_state_ = STATE_READ_TUNNEL_HEADERS;
914 return OK;
916 // DidReadResponseHeaders
917 scoped_refptr<HttpResponseHeaders> headers;
918 headers = new HttpResponseHeaders(
919 HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh));
920 if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
921 // Require the "HTTP/1.x" status line.
922 next_state_ = STATE_CLOSE;
923 return ERR_TUNNEL_CONNECTION_FAILED;
925 switch (headers->response_code()) {
926 case 200: // OK
927 if (is_secure()) {
928 DCHECK_EQ(eoh, tunnel_response_headers_len_);
929 next_state_ = STATE_SSL_CONNECT;
930 } else {
931 result = DidEstablishConnection();
932 if (result < 0) {
933 next_state_ = STATE_CLOSE;
934 return result;
936 if ((eoh < tunnel_response_headers_len_) && delegate_)
937 delegate_->OnReceivedData(
938 this, tunnel_response_headers_->headers() + eoh,
939 tunnel_response_headers_len_ - eoh);
941 return OK;
942 case 407: // Proxy Authentication Required.
943 if (proxy_mode_ != kTunnelProxy)
944 return ERR_UNEXPECTED_PROXY_AUTH;
946 result = proxy_auth_controller_->HandleAuthChallenge(
947 headers, false, true, net_log_);
948 if (result != OK)
949 return result;
950 DCHECK(!proxy_info_.is_empty());
951 next_state_ = STATE_AUTH_REQUIRED;
952 if (proxy_auth_controller_->HaveAuth()) {
953 base::MessageLoop::current()->PostTask(
954 FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
955 return ERR_IO_PENDING;
957 if (delegate_) {
958 // Wait until RestartWithAuth or Close is called.
959 base::MessageLoop::current()->PostTask(
960 FROM_HERE, base::Bind(&SocketStream::DoAuthRequired, this));
961 return ERR_IO_PENDING;
963 break;
964 default:
965 break;
967 next_state_ = STATE_CLOSE;
968 return ERR_TUNNEL_CONNECTION_FAILED;
971 int SocketStream::DoSOCKSConnect() {
972 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
974 next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
976 HostResolver::RequestInfo req_info(HostPortPair::FromURL(url_));
978 DCHECK(!proxy_info_.is_empty());
979 scoped_ptr<StreamSocket> s;
980 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) {
981 s.reset(new SOCKS5ClientSocket(connection_.Pass(), req_info));
982 } else {
983 s.reset(new SOCKSClientSocket(connection_.Pass(),
984 req_info,
985 DEFAULT_PRIORITY,
986 context_->host_resolver()));
988 connection_.reset(new ClientSocketHandle);
989 connection_->SetSocket(s.Pass());
990 metrics_->OnCountConnectionType(SocketStreamMetrics::SOCKS_CONNECTION);
991 return connection_->socket()->Connect(io_callback_);
994 int SocketStream::DoSOCKSConnectComplete(int result) {
995 DCHECK_EQ(kSOCKSProxy, proxy_mode_);
997 if (result == OK) {
998 if (is_secure())
999 next_state_ = STATE_SSL_CONNECT;
1000 else
1001 result = DidEstablishConnection();
1002 } else {
1003 next_state_ = STATE_CLOSE;
1005 return result;
1008 int SocketStream::DoSecureProxyConnect() {
1009 DCHECK(factory_);
1010 SSLClientSocketContext ssl_context;
1011 ssl_context.cert_verifier = context_->cert_verifier();
1012 ssl_context.transport_security_state = context_->transport_security_state();
1013 ssl_context.server_bound_cert_service = context_->server_bound_cert_service();
1014 scoped_ptr<StreamSocket> socket(factory_->CreateSSLClientSocket(
1015 connection_.Pass(),
1016 proxy_info_.proxy_server().host_port_pair(),
1017 proxy_ssl_config_,
1018 ssl_context));
1019 connection_.reset(new ClientSocketHandle);
1020 connection_->SetSocket(socket.Pass());
1021 next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE;
1022 metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION);
1023 return connection_->socket()->Connect(io_callback_);
1026 int SocketStream::DoSecureProxyConnectComplete(int result) {
1027 DCHECK_EQ(STATE_NONE, next_state_);
1028 // Reconnect with client authentication.
1029 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
1030 return HandleCertificateRequest(result, &proxy_ssl_config_);
1032 if (IsCertificateError(result))
1033 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR;
1034 else if (result == OK)
1035 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1036 else
1037 next_state_ = STATE_CLOSE;
1038 return result;
1041 int SocketStream::DoSecureProxyHandleCertError(int result) {
1042 DCHECK_EQ(STATE_NONE, next_state_);
1043 DCHECK(IsCertificateError(result));
1044 result = HandleCertificateError(result);
1045 if (result == ERR_IO_PENDING)
1046 next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE;
1047 else
1048 next_state_ = STATE_CLOSE;
1049 return result;
1052 int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) {
1053 DCHECK_EQ(STATE_NONE, next_state_);
1054 if (result == OK) {
1055 if (!connection_->socket()->IsConnectedAndIdle())
1056 return AllowCertErrorForReconnection(&proxy_ssl_config_);
1057 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
1058 } else {
1059 next_state_ = STATE_CLOSE;
1061 return result;
1064 int SocketStream::DoSSLConnect() {
1065 DCHECK(factory_);
1066 SSLClientSocketContext ssl_context;
1067 ssl_context.cert_verifier = context_->cert_verifier();
1068 ssl_context.transport_security_state = context_->transport_security_state();
1069 ssl_context.server_bound_cert_service = context_->server_bound_cert_service();
1070 scoped_ptr<StreamSocket> socket(
1071 factory_->CreateSSLClientSocket(connection_.Pass(),
1072 HostPortPair::FromURL(url_),
1073 server_ssl_config_,
1074 ssl_context));
1075 connection_.reset(new ClientSocketHandle);
1076 connection_->SetSocket(socket.Pass());
1077 next_state_ = STATE_SSL_CONNECT_COMPLETE;
1078 metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION);
1079 return connection_->socket()->Connect(io_callback_);
1082 int SocketStream::DoSSLConnectComplete(int result) {
1083 DCHECK_EQ(STATE_NONE, next_state_);
1084 // Reconnect with client authentication.
1085 if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
1086 return HandleCertificateRequest(result, &server_ssl_config_);
1088 if (IsCertificateError(result))
1089 next_state_ = STATE_SSL_HANDLE_CERT_ERROR;
1090 else if (result == OK)
1091 result = DidEstablishConnection();
1092 else
1093 next_state_ = STATE_CLOSE;
1094 return result;
1097 int SocketStream::DoSSLHandleCertError(int result) {
1098 DCHECK_EQ(STATE_NONE, next_state_);
1099 DCHECK(IsCertificateError(result));
1100 result = HandleCertificateError(result);
1101 if (result == OK || result == ERR_IO_PENDING)
1102 next_state_ = STATE_SSL_HANDLE_CERT_ERROR_COMPLETE;
1103 else
1104 next_state_ = STATE_CLOSE;
1105 return result;
1108 int SocketStream::DoSSLHandleCertErrorComplete(int result) {
1109 DCHECK_EQ(STATE_NONE, next_state_);
1110 // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible.
1111 // If we use HTTPS and this is the first connection to the SPDY server,
1112 // we should take care of TLS NPN extension here.
1114 if (result == OK) {
1115 if (!connection_->socket()->IsConnectedAndIdle())
1116 return AllowCertErrorForReconnection(&server_ssl_config_);
1117 result = DidEstablishConnection();
1118 } else {
1119 next_state_ = STATE_CLOSE;
1121 return result;
1124 int SocketStream::DoReadWrite(int result) {
1125 if (result < OK) {
1126 next_state_ = STATE_CLOSE;
1127 return result;
1129 if (!connection_->socket() || !connection_->socket()->IsConnected()) {
1130 next_state_ = STATE_CLOSE;
1131 return ERR_CONNECTION_CLOSED;
1134 // If client has requested close(), and there's nothing to write, then
1135 // let's close the socket.
1136 // We don't care about receiving data after the socket is closed.
1137 if (closing_ && !current_write_buf_.get() && pending_write_bufs_.empty()) {
1138 connection_->socket()->Disconnect();
1139 next_state_ = STATE_CLOSE;
1140 return OK;
1143 next_state_ = STATE_READ_WRITE;
1145 // If server already closed the socket, we don't try to read.
1146 if (!server_closed_) {
1147 if (!read_buf_.get()) {
1148 // No read pending and server didn't close the socket.
1149 read_buf_ = new IOBuffer(kReadBufferSize);
1150 result = connection_->socket()->Read(
1151 read_buf_.get(),
1152 kReadBufferSize,
1153 base::Bind(&SocketStream::OnReadCompleted, base::Unretained(this)));
1154 if (result > 0) {
1155 return DidReceiveData(result);
1156 } else if (result == 0) {
1157 // 0 indicates end-of-file, so socket was closed.
1158 next_state_ = STATE_CLOSE;
1159 server_closed_ = true;
1160 return ERR_CONNECTION_CLOSED;
1162 // If read is pending, try write as well.
1163 // Otherwise, return the result and do next loop (to close the
1164 // connection).
1165 if (result != ERR_IO_PENDING) {
1166 next_state_ = STATE_CLOSE;
1167 server_closed_ = true;
1168 return result;
1171 // Read is pending.
1172 DCHECK(read_buf_.get());
1175 if (waiting_for_write_completion_)
1176 return ERR_IO_PENDING;
1178 if (!current_write_buf_.get()) {
1179 if (pending_write_bufs_.empty()) {
1180 // Nothing buffered for send.
1181 return ERR_IO_PENDING;
1184 current_write_buf_ = new DrainableIOBuffer(
1185 pending_write_bufs_.front().get(), pending_write_bufs_.front()->size());
1186 pending_write_bufs_.pop_front();
1189 result = connection_->socket()->Write(
1190 current_write_buf_.get(),
1191 current_write_buf_->BytesRemaining(),
1192 base::Bind(&SocketStream::OnWriteCompleted, base::Unretained(this)));
1194 if (result == ERR_IO_PENDING) {
1195 waiting_for_write_completion_ = true;
1196 } else if (result < 0) {
1197 // Shortcut. Enter STATE_CLOSE now by changing next_state_ here than by
1198 // calling DoReadWrite() again with the error code.
1199 next_state_ = STATE_CLOSE;
1200 } else if (result > 0) {
1201 // Write is not pending. Return OK and do next loop.
1202 DidSendData(result);
1203 result = OK;
1206 return result;
1209 GURL SocketStream::ProxyAuthOrigin() const {
1210 DCHECK(!proxy_info_.is_empty());
1211 return GURL("http://" +
1212 proxy_info_.proxy_server().host_port_pair().ToString());
1215 int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
1216 if (ssl_config->send_client_cert) {
1217 // We already have performed SSL client authentication once and failed.
1218 return result;
1221 DCHECK(connection_->socket());
1222 scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
1223 SSLClientSocket* ssl_socket =
1224 static_cast<SSLClientSocket*>(connection_->socket());
1225 ssl_socket->GetSSLCertRequestInfo(cert_request_info.get());
1227 HttpTransactionFactory* factory = context_->http_transaction_factory();
1228 if (!factory)
1229 return result;
1230 scoped_refptr<HttpNetworkSession> session = factory->GetSession();
1231 if (!session.get())
1232 return result;
1234 // If the user selected one of the certificates in client_certs or declined
1235 // to provide one for this server before, use the past decision
1236 // automatically.
1237 scoped_refptr<X509Certificate> client_cert;
1238 if (!session->ssl_client_auth_cache()->Lookup(
1239 cert_request_info->host_and_port, &client_cert)) {
1240 return result;
1243 // Note: |client_cert| may be NULL, indicating that the caller
1244 // wishes to proceed anonymously (eg: continue the handshake
1245 // without sending a client cert)
1247 // Check that the certificate selected is still a certificate the server
1248 // is likely to accept, based on the criteria supplied in the
1249 // CertificateRequest message.
1250 const std::vector<std::string>& cert_authorities =
1251 cert_request_info->cert_authorities;
1252 if (client_cert.get() && !cert_authorities.empty() &&
1253 !client_cert->IsIssuedByEncoded(cert_authorities)) {
1254 return result;
1257 ssl_config->send_client_cert = true;
1258 ssl_config->client_cert = client_cert;
1259 next_state_ = STATE_TCP_CONNECT;
1260 return OK;
1263 int SocketStream::AllowCertErrorForReconnection(SSLConfig* ssl_config) {
1264 DCHECK(ssl_config);
1265 // The SSL handshake didn't finish, or the server closed the SSL connection.
1266 // So, we should restart establishing connection with the certificate in
1267 // allowed bad certificates in |ssl_config|.
1268 // See also net/http/http_network_transaction.cc HandleCertificateError() and
1269 // RestartIgnoringLastError().
1270 SSLClientSocket* ssl_socket =
1271 static_cast<SSLClientSocket*>(connection_->socket());
1272 SSLInfo ssl_info;
1273 ssl_socket->GetSSLInfo(&ssl_info);
1274 if (ssl_info.cert.get() == NULL ||
1275 ssl_config->IsAllowedBadCert(ssl_info.cert.get(), NULL)) {
1276 // If we already have the certificate in the set of allowed bad
1277 // certificates, we did try it and failed again, so we should not
1278 // retry again: the connection should fail at last.
1279 next_state_ = STATE_CLOSE;
1280 return ERR_UNEXPECTED;
1282 // Add the bad certificate to the set of allowed certificates in the
1283 // SSL config object.
1284 SSLConfig::CertAndStatus bad_cert;
1285 if (!X509Certificate::GetDEREncoded(ssl_info.cert->os_cert_handle(),
1286 &bad_cert.der_cert)) {
1287 next_state_ = STATE_CLOSE;
1288 return ERR_UNEXPECTED;
1290 bad_cert.cert_status = ssl_info.cert_status;
1291 ssl_config->allowed_bad_certs.push_back(bad_cert);
1292 // Restart connection ignoring the bad certificate.
1293 connection_->socket()->Disconnect();
1294 connection_->SetSocket(scoped_ptr<StreamSocket>());
1295 next_state_ = STATE_TCP_CONNECT;
1296 return OK;
1299 void SocketStream::DoAuthRequired() {
1300 if (delegate_ && proxy_auth_controller_.get())
1301 delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
1302 else
1303 DoLoop(ERR_UNEXPECTED);
1306 void SocketStream::DoRestartWithAuth() {
1307 DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
1308 tunnel_request_headers_ = NULL;
1309 tunnel_request_headers_bytes_sent_ = 0;
1310 tunnel_response_headers_ = NULL;
1311 tunnel_response_headers_capacity_ = 0;
1312 tunnel_response_headers_len_ = 0;
1314 next_state_ = STATE_TCP_CONNECT;
1315 DoLoop(OK);
1318 int SocketStream::HandleCertificateError(int result) {
1319 DCHECK(IsCertificateError(result));
1320 SSLClientSocket* ssl_socket =
1321 static_cast<SSLClientSocket*>(connection_->socket());
1322 DCHECK(ssl_socket);
1324 if (!context_)
1325 return result;
1327 if (SSLClientSocket::IgnoreCertError(result, LOAD_IGNORE_ALL_CERT_ERRORS)) {
1328 const HttpNetworkSession::Params* session_params =
1329 context_->GetNetworkSessionParams();
1330 if (session_params && session_params->ignore_certificate_errors)
1331 return OK;
1334 if (!delegate_)
1335 return result;
1337 SSLInfo ssl_info;
1338 ssl_socket->GetSSLInfo(&ssl_info);
1340 TransportSecurityState::DomainState domain_state;
1341 const bool fatal = context_->transport_security_state() &&
1342 context_->transport_security_state()->GetDomainState(url_.host(),
1343 SSLConfigService::IsSNIAvailable(context_->ssl_config_service()),
1344 &domain_state) &&
1345 domain_state.ShouldSSLErrorsBeFatal();
1347 delegate_->OnSSLCertificateError(this, ssl_info, fatal);
1348 return ERR_IO_PENDING;
1351 CookieStore* SocketStream::cookie_store() const {
1352 return cookie_store_;
1355 } // namespace net