Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: net/socket_stream/socket_stream.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_job.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/socket_stream/socket_stream.cc
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
deleted file mode 100644
index 422d61d45203c324fd48ed381b58dd34a3e2fd95..0000000000000000000000000000000000000000
--- a/net/socket_stream/socket_stream.cc
+++ /dev/null
@@ -1,1353 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// TODO(ukai): code is similar with http_network_transaction.cc. We should
-// think about ways to share code, if possible.
-
-#include "net/socket_stream/socket_stream.h"
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "net/base/auth.h"
-#include "net/base/io_buffer.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "net/dns/host_resolver.h"
-#include "net/http/http_auth_controller.h"
-#include "net/http/http_network_session.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_stream_factory.h"
-#include "net/http/http_transaction_factory.h"
-#include "net/http/http_util.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/socket/client_socket_handle.h"
-#include "net/socket/socks5_client_socket.h"
-#include "net/socket/socks_client_socket.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/socket/tcp_client_socket.h"
-#include "net/socket_stream/socket_stream_metrics.h"
-#include "net/ssl/ssl_cert_request_info.h"
-#include "net/ssl/ssl_info.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-
-static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes.
-static const int kReadBufferSize = 4096;
-
-namespace net {
-
-int SocketStream::Delegate::OnStartOpenConnection(
- SocketStream* socket, const CompletionCallback& callback) {
- return OK;
-}
-
-void SocketStream::Delegate::OnAuthRequired(SocketStream* socket,
- AuthChallengeInfo* auth_info) {
- // By default, no credential is available and close the connection.
- socket->Close();
-}
-
-void SocketStream::Delegate::OnSSLCertificateError(
- SocketStream* socket,
- const SSLInfo& ssl_info,
- bool fatal) {
- socket->CancelWithSSLError(ssl_info);
-}
-
-bool SocketStream::Delegate::CanGetCookies(SocketStream* socket,
- const GURL& url) {
- return true;
-}
-
-bool SocketStream::Delegate::CanSetCookie(SocketStream* request,
- const GURL& url,
- const std::string& cookie_line,
- CookieOptions* options) {
- return true;
-}
-
-SocketStream::ResponseHeaders::ResponseHeaders() : IOBuffer() {}
-
-void SocketStream::ResponseHeaders::Realloc(size_t new_size) {
- headers_.reset(static_cast<char*>(realloc(headers_.release(), new_size)));
-}
-
-SocketStream::ResponseHeaders::~ResponseHeaders() { data_ = NULL; }
-
-SocketStream::SocketStream(const GURL& url, Delegate* delegate,
- URLRequestContext* context,
- CookieStore* cookie_store)
- : delegate_(delegate),
- url_(url),
- max_pending_send_allowed_(kMaxPendingSendAllowed),
- context_(context),
- next_state_(STATE_NONE),
- factory_(ClientSocketFactory::GetDefaultFactory()),
- proxy_mode_(kDirectConnection),
- proxy_url_(url),
- pac_request_(NULL),
- connection_(new ClientSocketHandle),
- privacy_mode_(PRIVACY_MODE_DISABLED),
- // Unretained() is required; without it, Bind() creates a circular
- // dependency and the SocketStream object will not be freed.
- io_callback_(base::Bind(&SocketStream::OnIOCompleted,
- base::Unretained(this))),
- read_buf_(NULL),
- current_write_buf_(NULL),
- waiting_for_write_completion_(false),
- closing_(false),
- server_closed_(false),
- metrics_(new SocketStreamMetrics(url)),
- cookie_store_(cookie_store) {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- DCHECK(delegate_);
-
- if (context_) {
- if (!cookie_store_.get())
- cookie_store_ = context_->cookie_store();
-
- net_log_ = BoundNetLog::Make(
- context->net_log(),
- NetLog::SOURCE_SOCKET_STREAM);
-
- net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
- }
-}
-
-SocketStream::UserData* SocketStream::GetUserData(
- const void* key) const {
- UserDataMap::const_iterator found = user_data_.find(key);
- if (found != user_data_.end())
- return found->second.get();
- return NULL;
-}
-
-void SocketStream::SetUserData(const void* key, UserData* data) {
- user_data_[key] = linked_ptr<UserData>(data);
-}
-
-bool SocketStream::is_secure() const {
- return url_.SchemeIs("wss");
-}
-
-void SocketStream::DetachContext() {
- if (!context_)
- return;
-
- if (pac_request_) {
- context_->proxy_service()->CancelPacRequest(pac_request_);
- pac_request_ = NULL;
- }
-
- net_log_.EndEvent(NetLog::TYPE_REQUEST_ALIVE);
- net_log_ = BoundNetLog();
-
- context_ = NULL;
- cookie_store_ = NULL;
-}
-
-void SocketStream::CheckPrivacyMode() {
- if (context_ && context_->network_delegate()) {
- bool enable = context_->network_delegate()->CanEnablePrivacyMode(url_,
- url_);
- privacy_mode_ = enable ? PRIVACY_MODE_ENABLED : PRIVACY_MODE_DISABLED;
- // Disable Channel ID if privacy mode is enabled.
- if (enable)
- server_ssl_config_.channel_id_enabled = false;
- }
-}
-
-void SocketStream::Connect() {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- if (context_) {
- context_->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
- proxy_ssl_config_ = server_ssl_config_;
- }
- CheckPrivacyMode();
-
- DCHECK_EQ(next_state_, STATE_NONE);
-
- AddRef(); // Released in Finish()
- // Open a connection asynchronously, so that delegate won't be called
- // back before returning Connect().
- next_state_ = STATE_BEFORE_CONNECT;
- net_log_.BeginEvent(
- NetLog::TYPE_SOCKET_STREAM_CONNECT,
- NetLog::StringCallback("url", &url_.possibly_invalid_spec()));
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
-}
-
-size_t SocketStream::GetTotalSizeOfPendingWriteBufs() const {
- size_t total_size = 0;
- for (PendingDataQueue::const_iterator iter = pending_write_bufs_.begin();
- iter != pending_write_bufs_.end();
- ++iter)
- total_size += (*iter)->size();
- return total_size;
-}
-
-bool SocketStream::SendData(const char* data, int len) {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- DCHECK_GT(len, 0);
-
- if (!connection_->socket() ||
- !connection_->socket()->IsConnected() || next_state_ == STATE_NONE) {
- return false;
- }
-
- int total_buffered_bytes = len;
- if (current_write_buf_.get()) {
- // Since
- // - the purpose of this check is to limit the amount of buffer used by
- // this instance.
- // - the DrainableIOBuffer doesn't release consumed memory.
- // we need to use not BytesRemaining() but size() here.
- total_buffered_bytes += current_write_buf_->size();
- }
- total_buffered_bytes += GetTotalSizeOfPendingWriteBufs();
- if (total_buffered_bytes > max_pending_send_allowed_)
- return false;
-
- // TODO(tyoshino): Split data into smaller chunks e.g. 8KiB to free consumed
- // buffer progressively
- pending_write_bufs_.push_back(make_scoped_refptr(
- new IOBufferWithSize(len)));
- memcpy(pending_write_bufs_.back()->data(), data, len);
-
- // If current_write_buf_ is not NULL, it means that a) there's ongoing write
- // operation or b) the connection is being closed. If a), the buffer we just
- // pushed will be automatically handled when the completion callback runs
- // the loop, and therefore we don't need to enqueue DoLoop(). If b), it's ok
- // to do nothing. If current_write_buf_ is NULL, to make sure DoLoop() is
- // ran soon, enequeue it.
- if (!current_write_buf_.get()) {
- // Send pending data asynchronously, so that delegate won't be called
- // back before returning from SendData().
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
- }
-
- return true;
-}
-
-void SocketStream::Close() {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- // If next_state_ is STATE_NONE, the socket was not opened, or already
- // closed. So, return immediately.
- // Otherwise, it might call Finish() more than once, so breaks balance
- // of AddRef() and Release() in Connect() and Finish(), respectively.
- if (next_state_ == STATE_NONE)
- return;
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoClose, this));
-}
-
-void SocketStream::RestartWithAuth(const AuthCredentials& credentials) {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- DCHECK(proxy_auth_controller_.get());
- if (!connection_->socket()) {
- DVLOG(1) << "Socket is closed before restarting with auth.";
- return;
- }
-
- proxy_auth_controller_->ResetAuth(credentials);
-
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
-}
-
-void SocketStream::DetachDelegate() {
- if (!delegate_)
- return;
- delegate_ = NULL;
- // Prevent the rest of the function from executing if we are being called from
- // within Finish().
- if (next_state_ == STATE_NONE)
- return;
- net_log_.AddEvent(NetLog::TYPE_CANCELLED);
- // We don't need to send pending data when client detach the delegate.
- pending_write_bufs_.clear();
- Close();
-}
-
-const ProxyServer& SocketStream::proxy_server() const {
- return proxy_info_.proxy_server();
-}
-
-void SocketStream::SetClientSocketFactory(
- ClientSocketFactory* factory) {
- DCHECK(factory);
- factory_ = factory;
-}
-
-void SocketStream::CancelWithError(int error) {
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoLoop, this, error));
-}
-
-void SocketStream::CancelWithSSLError(const SSLInfo& ssl_info) {
- CancelWithError(MapCertStatusToNetError(ssl_info.cert_status));
-}
-
-void SocketStream::ContinueDespiteError() {
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoLoop, this, OK));
-}
-
-SocketStream::~SocketStream() {
- DetachContext();
- DCHECK(!delegate_);
- DCHECK(!pac_request_);
-}
-
-SocketStream::RequestHeaders::~RequestHeaders() { data_ = NULL; }
-
-void SocketStream::set_addresses(const AddressList& addresses) {
- addresses_ = addresses;
-}
-
-void SocketStream::DoClose() {
- closing_ = true;
- // If next_state_ is:
- // - STATE_TCP_CONNECT_COMPLETE, it's waiting other socket establishing
- // connection.
- // - STATE_AUTH_REQUIRED, it's waiting for restarting.
- // - STATE_RESOLVE_PROTOCOL_COMPLETE, it's waiting for delegate_ to finish
- // OnStartOpenConnection method call
- // In these states, we'll close the SocketStream now.
- if (next_state_ == STATE_TCP_CONNECT_COMPLETE ||
- next_state_ == STATE_AUTH_REQUIRED ||
- next_state_ == STATE_RESOLVE_PROTOCOL_COMPLETE) {
- DoLoop(ERR_ABORTED);
- return;
- }
- // If next_state_ is STATE_READ_WRITE, we'll run DoLoop and close
- // the SocketStream.
- // If it's writing now, we should defer the closing after the current
- // writing is completed.
- if (next_state_ == STATE_READ_WRITE && !current_write_buf_.get())
- DoLoop(ERR_ABORTED);
-
- // In other next_state_, we'll wait for callback of other APIs, such as
- // ResolveProxy().
-}
-
-void SocketStream::Finish(int result) {
- DCHECK(base::MessageLoop::current())
- << "The current base::MessageLoop must exist";
- DCHECK(base::MessageLoopForIO::IsCurrent())
- << "The current base::MessageLoop must be TYPE_IO";
- DCHECK_LE(result, OK);
- if (result == OK)
- result = ERR_CONNECTION_CLOSED;
- DCHECK_EQ(next_state_, STATE_NONE);
- DVLOG(1) << "Finish result=" << ErrorToString(result);
-
- metrics_->OnClose();
-
- if (result != ERR_CONNECTION_CLOSED && delegate_)
- delegate_->OnError(this, result);
- if (result != ERR_PROTOCOL_SWITCHED && delegate_)
- delegate_->OnClose(this);
- delegate_ = NULL;
-
- Release();
-}
-
-int SocketStream::DidEstablishConnection() {
- if (!connection_->socket() || !connection_->socket()->IsConnected()) {
- next_state_ = STATE_CLOSE;
- return ERR_CONNECTION_FAILED;
- }
- next_state_ = STATE_READ_WRITE;
- metrics_->OnConnected();
-
- net_log_.EndEvent(NetLog::TYPE_SOCKET_STREAM_CONNECT);
- if (delegate_)
- delegate_->OnConnected(this, max_pending_send_allowed_);
-
- return OK;
-}
-
-int SocketStream::DidReceiveData(int result) {
- DCHECK(read_buf_.get());
- DCHECK_GT(result, 0);
- net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_RECEIVED);
- int len = result;
- metrics_->OnRead(len);
- if (delegate_) {
- // Notify recevied data to delegate.
- delegate_->OnReceivedData(this, read_buf_->data(), len);
- }
- read_buf_ = NULL;
- return OK;
-}
-
-void SocketStream::DidSendData(int result) {
- DCHECK_GT(result, 0);
- DCHECK(current_write_buf_.get());
- net_log_.AddEvent(NetLog::TYPE_SOCKET_STREAM_SENT);
-
- int bytes_sent = result;
-
- metrics_->OnWrite(bytes_sent);
-
- current_write_buf_->DidConsume(result);
-
- if (current_write_buf_->BytesRemaining())
- return;
-
- size_t bytes_freed = current_write_buf_->size();
-
- current_write_buf_ = NULL;
-
- // We freed current_write_buf_ and this instance is now able to accept more
- // data via SendData() (note that DidConsume() doesn't free consumed memory).
- // We can tell that to delegate_ by calling OnSentData().
- if (delegate_)
- delegate_->OnSentData(this, bytes_freed);
-}
-
-void SocketStream::OnIOCompleted(int result) {
- DoLoop(result);
-}
-
-void SocketStream::OnReadCompleted(int result) {
- if (result == 0) {
- // 0 indicates end-of-file, so socket was closed.
- // Don't close the socket if it's still writing.
- server_closed_ = true;
- } else if (result > 0 && read_buf_.get()) {
- result = DidReceiveData(result);
- }
- DoLoop(result);
-}
-
-void SocketStream::OnWriteCompleted(int result) {
- waiting_for_write_completion_ = false;
- if (result > 0) {
- DidSendData(result);
- result = OK;
- }
- DoLoop(result);
-}
-
-void SocketStream::DoLoop(int result) {
- if (next_state_ == STATE_NONE)
- return;
-
- // If context was not set, close immediately.
- if (!context_)
- next_state_ = STATE_CLOSE;
-
- do {
- State state = next_state_;
- next_state_ = STATE_NONE;
- switch (state) {
- case STATE_BEFORE_CONNECT:
- DCHECK_EQ(OK, result);
- result = DoBeforeConnect();
- break;
- case STATE_BEFORE_CONNECT_COMPLETE:
- result = DoBeforeConnectComplete(result);
- break;
- case STATE_RESOLVE_PROXY:
- DCHECK_EQ(OK, result);
- result = DoResolveProxy();
- break;
- case STATE_RESOLVE_PROXY_COMPLETE:
- result = DoResolveProxyComplete(result);
- break;
- case STATE_RESOLVE_HOST:
- DCHECK_EQ(OK, result);
- result = DoResolveHost();
- break;
- case STATE_RESOLVE_HOST_COMPLETE:
- result = DoResolveHostComplete(result);
- break;
- case STATE_RESOLVE_PROTOCOL:
- result = DoResolveProtocol(result);
- break;
- case STATE_RESOLVE_PROTOCOL_COMPLETE:
- result = DoResolveProtocolComplete(result);
- break;
- case STATE_TCP_CONNECT:
- result = DoTcpConnect(result);
- break;
- case STATE_TCP_CONNECT_COMPLETE:
- result = DoTcpConnectComplete(result);
- break;
- case STATE_GENERATE_PROXY_AUTH_TOKEN:
- result = DoGenerateProxyAuthToken();
- break;
- case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE:
- result = DoGenerateProxyAuthTokenComplete(result);
- break;
- case STATE_WRITE_TUNNEL_HEADERS:
- DCHECK_EQ(OK, result);
- result = DoWriteTunnelHeaders();
- break;
- case STATE_WRITE_TUNNEL_HEADERS_COMPLETE:
- result = DoWriteTunnelHeadersComplete(result);
- break;
- case STATE_READ_TUNNEL_HEADERS:
- DCHECK_EQ(OK, result);
- result = DoReadTunnelHeaders();
- break;
- case STATE_READ_TUNNEL_HEADERS_COMPLETE:
- result = DoReadTunnelHeadersComplete(result);
- break;
- case STATE_SOCKS_CONNECT:
- DCHECK_EQ(OK, result);
- result = DoSOCKSConnect();
- break;
- case STATE_SOCKS_CONNECT_COMPLETE:
- result = DoSOCKSConnectComplete(result);
- break;
- case STATE_SECURE_PROXY_CONNECT:
- DCHECK_EQ(OK, result);
- result = DoSecureProxyConnect();
- break;
- case STATE_SECURE_PROXY_CONNECT_COMPLETE:
- result = DoSecureProxyConnectComplete(result);
- break;
- case STATE_SECURE_PROXY_HANDLE_CERT_ERROR:
- result = DoSecureProxyHandleCertError(result);
- break;
- case STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE:
- result = DoSecureProxyHandleCertErrorComplete(result);
- break;
- case STATE_SSL_CONNECT:
- DCHECK_EQ(OK, result);
- result = DoSSLConnect();
- break;
- case STATE_SSL_CONNECT_COMPLETE:
- result = DoSSLConnectComplete(result);
- break;
- case STATE_SSL_HANDLE_CERT_ERROR:
- result = DoSSLHandleCertError(result);
- break;
- case STATE_SSL_HANDLE_CERT_ERROR_COMPLETE:
- result = DoSSLHandleCertErrorComplete(result);
- break;
- case STATE_READ_WRITE:
- result = DoReadWrite(result);
- break;
- case STATE_AUTH_REQUIRED:
- // It might be called when DoClose is called while waiting in
- // STATE_AUTH_REQUIRED.
- Finish(result);
- return;
- case STATE_CLOSE:
- DCHECK_LE(result, OK);
- Finish(result);
- return;
- default:
- NOTREACHED() << "bad state " << state;
- Finish(result);
- return;
- }
- if (state == STATE_RESOLVE_PROTOCOL && result == ERR_PROTOCOL_SWITCHED)
- continue;
- // If the connection is not established yet and had actual errors,
- // record the error. In next iteration, it will close the connection.
- if (state != STATE_READ_WRITE && result < ERR_IO_PENDING) {
- net_log_.EndEventWithNetErrorCode(
- NetLog::TYPE_SOCKET_STREAM_CONNECT, result);
- }
- } while (result != ERR_IO_PENDING);
-}
-
-int SocketStream::DoBeforeConnect() {
- next_state_ = STATE_BEFORE_CONNECT_COMPLETE;
- if (!context_ || !context_->network_delegate())
- return OK;
-
- int result = context_->network_delegate()->NotifyBeforeSocketStreamConnect(
- this, io_callback_);
- if (result != OK && result != ERR_IO_PENDING)
- next_state_ = STATE_CLOSE;
-
- return result;
-}
-
-int SocketStream::DoBeforeConnectComplete(int result) {
- DCHECK_NE(ERR_IO_PENDING, result);
-
- if (result == OK)
- next_state_ = STATE_RESOLVE_PROXY;
- else
- next_state_ = STATE_CLOSE;
-
- return result;
-}
-
-int SocketStream::DoResolveProxy() {
- DCHECK(context_);
- DCHECK(!pac_request_);
- next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
-
- if (!proxy_url_.is_valid()) {
- next_state_ = STATE_CLOSE;
- return ERR_INVALID_ARGUMENT;
- }
-
- // TODO(toyoshim): Check server advertisement of SPDY through the HTTP
- // Alternate-Protocol header, then switch to SPDY if SPDY is available.
- // Usually we already have a session to the SPDY server because JavaScript
- // running WebSocket itself would be served by SPDY. But, in some situation
- // (E.g. Used by Chrome Extensions or used for cross origin connection), this
- // connection might be the first one. At that time, we should check
- // Alternate-Protocol header here for ws:// or TLS NPN extension for wss:// .
-
- return context_->proxy_service()->ResolveProxy(
- proxy_url_, net::LOAD_NORMAL, &proxy_info_, io_callback_, &pac_request_,
- NULL, net_log_);
-}
-
-int SocketStream::DoResolveProxyComplete(int result) {
- pac_request_ = NULL;
- if (result != OK) {
- DVLOG(1) << "Failed to resolve proxy: " << result;
- if (delegate_)
- delegate_->OnError(this, result);
- proxy_info_.UseDirect();
- }
- if (proxy_info_.is_direct()) {
- // If proxy was not found for original URL (i.e. websocket URL),
- // try again with https URL, like Safari implementation.
- // Note that we don't want to use http proxy, because we'll use tunnel
- // proxy using CONNECT method, which is used by https proxy.
- if (!proxy_url_.SchemeIs("https")) {
- const std::string scheme = "https";
- GURL::Replacements repl;
- repl.SetSchemeStr(scheme);
- proxy_url_ = url_.ReplaceComponents(repl);
- DVLOG(1) << "Try https proxy: " << proxy_url_;
- next_state_ = STATE_RESOLVE_PROXY;
- return OK;
- }
- }
-
- if (proxy_info_.is_empty()) {
- // No proxies/direct to choose from. This happens when we don't support any
- // of the proxies in the returned list.
- return ERR_NO_SUPPORTED_PROXIES;
- }
-
- next_state_ = STATE_RESOLVE_HOST;
- return OK;
-}
-
-int SocketStream::DoResolveHost() {
- next_state_ = STATE_RESOLVE_HOST_COMPLETE;
-
- DCHECK(!proxy_info_.is_empty());
- if (proxy_info_.is_direct())
- proxy_mode_ = kDirectConnection;
- else if (proxy_info_.proxy_server().is_socks())
- proxy_mode_ = kSOCKSProxy;
- else
- proxy_mode_ = kTunnelProxy;
-
- // Determine the host and port to connect to.
- HostPortPair host_port_pair;
- if (proxy_mode_ != kDirectConnection) {
- host_port_pair = proxy_info_.proxy_server().host_port_pair();
- } else {
- host_port_pair = HostPortPair::FromURL(url_);
- }
-
- HostResolver::RequestInfo resolve_info(host_port_pair);
-
- DCHECK(context_->host_resolver());
- resolver_.reset(new SingleRequestHostResolver(context_->host_resolver()));
- return resolver_->Resolve(resolve_info,
- DEFAULT_PRIORITY,
- &addresses_,
- base::Bind(&SocketStream::OnIOCompleted, this),
- net_log_);
-}
-
-int SocketStream::DoResolveHostComplete(int result) {
- if (result == OK)
- next_state_ = STATE_RESOLVE_PROTOCOL;
- else
- next_state_ = STATE_CLOSE;
- // TODO(ukai): if error occured, reconsider proxy after error.
- return result;
-}
-
-int SocketStream::DoResolveProtocol(int result) {
- DCHECK_EQ(OK, result);
-
- if (!delegate_) {
- next_state_ = STATE_CLOSE;
- return result;
- }
-
- next_state_ = STATE_RESOLVE_PROTOCOL_COMPLETE;
- result = delegate_->OnStartOpenConnection(this, io_callback_);
- if (result == ERR_IO_PENDING)
- metrics_->OnWaitConnection();
- else if (result != OK && result != ERR_PROTOCOL_SWITCHED)
- next_state_ = STATE_CLOSE;
- return result;
-}
-
-int SocketStream::DoResolveProtocolComplete(int result) {
- DCHECK_NE(ERR_IO_PENDING, result);
-
- if (result == ERR_PROTOCOL_SWITCHED) {
- next_state_ = STATE_CLOSE;
- metrics_->OnCountWireProtocolType(
- SocketStreamMetrics::WIRE_PROTOCOL_SPDY);
- } else if (result == OK) {
- next_state_ = STATE_TCP_CONNECT;
- metrics_->OnCountWireProtocolType(
- SocketStreamMetrics::WIRE_PROTOCOL_WEBSOCKET);
- } else {
- next_state_ = STATE_CLOSE;
- }
- return result;
-}
-
-int SocketStream::DoTcpConnect(int result) {
- if (result != OK) {
- next_state_ = STATE_CLOSE;
- return result;
- }
- next_state_ = STATE_TCP_CONNECT_COMPLETE;
- DCHECK(factory_);
- connection_->SetSocket(
- factory_->CreateTransportClientSocket(addresses_,
- net_log_.net_log(),
- net_log_.source()));
- metrics_->OnStartConnection();
- return connection_->socket()->Connect(io_callback_);
-}
-
-int SocketStream::DoTcpConnectComplete(int result) {
- // TODO(ukai): if error occured, reconsider proxy after error.
- if (result != OK) {
- next_state_ = STATE_CLOSE;
- return result;
- }
-
- if (proxy_mode_ == kTunnelProxy) {
- if (proxy_info_.is_https())
- next_state_ = STATE_SECURE_PROXY_CONNECT;
- else
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
- } else if (proxy_mode_ == kSOCKSProxy) {
- next_state_ = STATE_SOCKS_CONNECT;
- } else if (is_secure()) {
- next_state_ = STATE_SSL_CONNECT;
- } else {
- result = DidEstablishConnection();
- }
- return result;
-}
-
-int SocketStream::DoGenerateProxyAuthToken() {
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE;
- if (!proxy_auth_controller_.get()) {
- DCHECK(context_);
- DCHECK(context_->http_transaction_factory());
- DCHECK(context_->http_transaction_factory()->GetSession());
- HttpNetworkSession* session =
- context_->http_transaction_factory()->GetSession();
- const char* scheme = proxy_info_.is_https() ? "https://" : "http://";
- GURL auth_url(scheme +
- proxy_info_.proxy_server().host_port_pair().ToString());
- proxy_auth_controller_ =
- new HttpAuthController(HttpAuth::AUTH_PROXY,
- auth_url,
- session->http_auth_cache(),
- session->http_auth_handler_factory());
- }
- HttpRequestInfo request_info;
- request_info.url = url_;
- request_info.method = "CONNECT";
- return proxy_auth_controller_->MaybeGenerateAuthToken(
- &request_info, io_callback_, net_log_);
-}
-
-int SocketStream::DoGenerateProxyAuthTokenComplete(int result) {
- if (result != OK) {
- next_state_ = STATE_CLOSE;
- return result;
- }
-
- next_state_ = STATE_WRITE_TUNNEL_HEADERS;
- return result;
-}
-
-int SocketStream::DoWriteTunnelHeaders() {
- DCHECK_EQ(kTunnelProxy, proxy_mode_);
-
- next_state_ = STATE_WRITE_TUNNEL_HEADERS_COMPLETE;
-
- if (!tunnel_request_headers_.get()) {
- metrics_->OnCountConnectionType(SocketStreamMetrics::TUNNEL_CONNECTION);
- tunnel_request_headers_ = new RequestHeaders();
- tunnel_request_headers_bytes_sent_ = 0;
- }
- if (tunnel_request_headers_->headers_.empty()) {
- HttpRequestHeaders request_headers;
- request_headers.SetHeader("Host", GetHostAndOptionalPort(url_));
- request_headers.SetHeader("Proxy-Connection", "keep-alive");
- if (proxy_auth_controller_.get() && proxy_auth_controller_->HaveAuth())
- proxy_auth_controller_->AddAuthorizationHeader(&request_headers);
- tunnel_request_headers_->headers_ = base::StringPrintf(
- "CONNECT %s HTTP/1.1\r\n"
- "%s",
- GetHostAndPort(url_).c_str(),
- request_headers.ToString().c_str());
- }
- tunnel_request_headers_->SetDataOffset(tunnel_request_headers_bytes_sent_);
- int buf_len = static_cast<int>(tunnel_request_headers_->headers_.size() -
- tunnel_request_headers_bytes_sent_);
- DCHECK_GT(buf_len, 0);
- return connection_->socket()->Write(
- tunnel_request_headers_.get(), buf_len, io_callback_);
-}
-
-int SocketStream::DoWriteTunnelHeadersComplete(int result) {
- DCHECK_EQ(kTunnelProxy, proxy_mode_);
-
- if (result < 0) {
- next_state_ = STATE_CLOSE;
- return result;
- }
-
- tunnel_request_headers_bytes_sent_ += result;
- if (tunnel_request_headers_bytes_sent_ <
- tunnel_request_headers_->headers_.size()) {
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
- } else {
- // Handling a cert error or a client cert request requires reconnection.
- // DoWriteTunnelHeaders() will be called again.
- // Thus |tunnel_request_headers_bytes_sent_| should be reset to 0 for
- // sending |tunnel_request_headers_| correctly.
- tunnel_request_headers_bytes_sent_ = 0;
- next_state_ = STATE_READ_TUNNEL_HEADERS;
- }
- return OK;
-}
-
-int SocketStream::DoReadTunnelHeaders() {
- DCHECK_EQ(kTunnelProxy, proxy_mode_);
-
- next_state_ = STATE_READ_TUNNEL_HEADERS_COMPLETE;
-
- if (!tunnel_response_headers_.get()) {
- tunnel_response_headers_ = new ResponseHeaders();
- tunnel_response_headers_capacity_ = kMaxTunnelResponseHeadersSize;
- tunnel_response_headers_->Realloc(tunnel_response_headers_capacity_);
- tunnel_response_headers_len_ = 0;
- }
-
- int buf_len = tunnel_response_headers_capacity_ -
- tunnel_response_headers_len_;
- tunnel_response_headers_->SetDataOffset(tunnel_response_headers_len_);
- CHECK(tunnel_response_headers_->data());
-
- return connection_->socket()->Read(
- tunnel_response_headers_.get(), buf_len, io_callback_);
-}
-
-int SocketStream::DoReadTunnelHeadersComplete(int result) {
- DCHECK_EQ(kTunnelProxy, proxy_mode_);
-
- if (result < 0) {
- next_state_ = STATE_CLOSE;
- return result;
- }
-
- if (result == 0) {
- // 0 indicates end-of-file, so socket was closed.
- next_state_ = STATE_CLOSE;
- return ERR_CONNECTION_CLOSED;
- }
-
- tunnel_response_headers_len_ += result;
- DCHECK(tunnel_response_headers_len_ <= tunnel_response_headers_capacity_);
-
- int eoh = HttpUtil::LocateEndOfHeaders(
- tunnel_response_headers_->headers(), tunnel_response_headers_len_, 0);
- if (eoh == -1) {
- if (tunnel_response_headers_len_ >= kMaxTunnelResponseHeadersSize) {
- next_state_ = STATE_CLOSE;
- return ERR_RESPONSE_HEADERS_TOO_BIG;
- }
-
- next_state_ = STATE_READ_TUNNEL_HEADERS;
- return OK;
- }
- // DidReadResponseHeaders
- scoped_refptr<HttpResponseHeaders> headers;
- headers = new HttpResponseHeaders(
- HttpUtil::AssembleRawHeaders(tunnel_response_headers_->headers(), eoh));
- if (headers->GetParsedHttpVersion() < HttpVersion(1, 0)) {
- // Require the "HTTP/1.x" status line.
- next_state_ = STATE_CLOSE;
- return ERR_TUNNEL_CONNECTION_FAILED;
- }
- switch (headers->response_code()) {
- case 200: // OK
- if (is_secure()) {
- DCHECK_EQ(eoh, tunnel_response_headers_len_);
- next_state_ = STATE_SSL_CONNECT;
- } else {
- result = DidEstablishConnection();
- if (result < 0) {
- next_state_ = STATE_CLOSE;
- return result;
- }
- if ((eoh < tunnel_response_headers_len_) && delegate_)
- delegate_->OnReceivedData(
- this, tunnel_response_headers_->headers() + eoh,
- tunnel_response_headers_len_ - eoh);
- }
- return OK;
- case 407: // Proxy Authentication Required.
- if (proxy_mode_ != kTunnelProxy)
- return ERR_UNEXPECTED_PROXY_AUTH;
-
- result = proxy_auth_controller_->HandleAuthChallenge(
- headers, false, true, net_log_);
- if (result != OK)
- return result;
- DCHECK(!proxy_info_.is_empty());
- next_state_ = STATE_AUTH_REQUIRED;
- if (proxy_auth_controller_->HaveAuth()) {
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoRestartWithAuth, this));
- return ERR_IO_PENDING;
- }
- if (delegate_) {
- // Wait until RestartWithAuth or Close is called.
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&SocketStream::DoAuthRequired, this));
- return ERR_IO_PENDING;
- }
- break;
- default:
- break;
- }
- next_state_ = STATE_CLOSE;
- return ERR_TUNNEL_CONNECTION_FAILED;
-}
-
-int SocketStream::DoSOCKSConnect() {
- DCHECK_EQ(kSOCKSProxy, proxy_mode_);
-
- next_state_ = STATE_SOCKS_CONNECT_COMPLETE;
-
- HostResolver::RequestInfo req_info(HostPortPair::FromURL(url_));
-
- DCHECK(!proxy_info_.is_empty());
- scoped_ptr<StreamSocket> s;
- if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) {
- s.reset(new SOCKS5ClientSocket(connection_.Pass(), req_info));
- } else {
- s.reset(new SOCKSClientSocket(connection_.Pass(),
- req_info,
- DEFAULT_PRIORITY,
- context_->host_resolver()));
- }
- connection_.reset(new ClientSocketHandle);
- connection_->SetSocket(s.Pass());
- metrics_->OnCountConnectionType(SocketStreamMetrics::SOCKS_CONNECTION);
- return connection_->socket()->Connect(io_callback_);
-}
-
-int SocketStream::DoSOCKSConnectComplete(int result) {
- DCHECK_EQ(kSOCKSProxy, proxy_mode_);
-
- if (result == OK) {
- if (is_secure())
- next_state_ = STATE_SSL_CONNECT;
- else
- result = DidEstablishConnection();
- } else {
- next_state_ = STATE_CLOSE;
- }
- return result;
-}
-
-int SocketStream::DoSecureProxyConnect() {
- DCHECK(factory_);
- SSLClientSocketContext ssl_context;
- ssl_context.cert_verifier = context_->cert_verifier();
- ssl_context.transport_security_state = context_->transport_security_state();
- ssl_context.channel_id_service = context_->channel_id_service();
- scoped_ptr<StreamSocket> socket(factory_->CreateSSLClientSocket(
- connection_.Pass(),
- proxy_info_.proxy_server().host_port_pair(),
- proxy_ssl_config_,
- ssl_context));
- connection_.reset(new ClientSocketHandle);
- connection_->SetSocket(socket.Pass());
- next_state_ = STATE_SECURE_PROXY_CONNECT_COMPLETE;
- metrics_->OnCountConnectionType(SocketStreamMetrics::SECURE_PROXY_CONNECTION);
- return connection_->socket()->Connect(io_callback_);
-}
-
-int SocketStream::DoSecureProxyConnectComplete(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- // Reconnect with client authentication.
- if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
- return HandleCertificateRequest(result, &proxy_ssl_config_);
-
- if (IsCertificateError(result))
- next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR;
- else if (result == OK)
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
- else
- next_state_ = STATE_CLOSE;
- return result;
-}
-
-int SocketStream::DoSecureProxyHandleCertError(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- DCHECK(IsCertificateError(result));
- result = HandleCertificateError(result);
- if (result == ERR_IO_PENDING)
- next_state_ = STATE_SECURE_PROXY_HANDLE_CERT_ERROR_COMPLETE;
- else
- next_state_ = STATE_CLOSE;
- return result;
-}
-
-int SocketStream::DoSecureProxyHandleCertErrorComplete(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- if (result == OK) {
- if (!connection_->socket()->IsConnectedAndIdle())
- return AllowCertErrorForReconnection(&proxy_ssl_config_);
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
- } else {
- next_state_ = STATE_CLOSE;
- }
- return result;
-}
-
-int SocketStream::DoSSLConnect() {
- DCHECK(factory_);
- SSLClientSocketContext ssl_context;
- ssl_context.cert_verifier = context_->cert_verifier();
- ssl_context.transport_security_state = context_->transport_security_state();
- ssl_context.channel_id_service = context_->channel_id_service();
- scoped_ptr<StreamSocket> socket(
- factory_->CreateSSLClientSocket(connection_.Pass(),
- HostPortPair::FromURL(url_),
- server_ssl_config_,
- ssl_context));
- connection_.reset(new ClientSocketHandle);
- connection_->SetSocket(socket.Pass());
- next_state_ = STATE_SSL_CONNECT_COMPLETE;
- metrics_->OnCountConnectionType(SocketStreamMetrics::SSL_CONNECTION);
- return connection_->socket()->Connect(io_callback_);
-}
-
-int SocketStream::DoSSLConnectComplete(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- // Reconnect with client authentication.
- if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED)
- return HandleCertificateRequest(result, &server_ssl_config_);
-
- if (IsCertificateError(result))
- next_state_ = STATE_SSL_HANDLE_CERT_ERROR;
- else if (result == OK)
- result = DidEstablishConnection();
- else
- next_state_ = STATE_CLOSE;
- return result;
-}
-
-int SocketStream::DoSSLHandleCertError(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- DCHECK(IsCertificateError(result));
- result = HandleCertificateError(result);
- if (result == OK || result == ERR_IO_PENDING)
- next_state_ = STATE_SSL_HANDLE_CERT_ERROR_COMPLETE;
- else
- next_state_ = STATE_CLOSE;
- return result;
-}
-
-int SocketStream::DoSSLHandleCertErrorComplete(int result) {
- DCHECK_EQ(STATE_NONE, next_state_);
- // TODO(toyoshim): Upgrade to SPDY through TLS NPN extension if possible.
- // If we use HTTPS and this is the first connection to the SPDY server,
- // we should take care of TLS NPN extension here.
-
- if (result == OK) {
- if (!connection_->socket()->IsConnectedAndIdle())
- return AllowCertErrorForReconnection(&server_ssl_config_);
- result = DidEstablishConnection();
- } else {
- next_state_ = STATE_CLOSE;
- }
- return result;
-}
-
-int SocketStream::DoReadWrite(int result) {
- if (result < OK) {
- next_state_ = STATE_CLOSE;
- return result;
- }
- if (!connection_->socket() || !connection_->socket()->IsConnected()) {
- next_state_ = STATE_CLOSE;
- return ERR_CONNECTION_CLOSED;
- }
-
- // If client has requested close(), and there's nothing to write, then
- // let's close the socket.
- // We don't care about receiving data after the socket is closed.
- if (closing_ && !current_write_buf_.get() && pending_write_bufs_.empty()) {
- connection_->socket()->Disconnect();
- next_state_ = STATE_CLOSE;
- return OK;
- }
-
- next_state_ = STATE_READ_WRITE;
-
- // If server already closed the socket, we don't try to read.
- if (!server_closed_) {
- if (!read_buf_.get()) {
- // No read pending and server didn't close the socket.
- read_buf_ = new IOBuffer(kReadBufferSize);
- result = connection_->socket()->Read(
- read_buf_.get(),
- kReadBufferSize,
- base::Bind(&SocketStream::OnReadCompleted, base::Unretained(this)));
- if (result > 0) {
- return DidReceiveData(result);
- } else if (result == 0) {
- // 0 indicates end-of-file, so socket was closed.
- next_state_ = STATE_CLOSE;
- server_closed_ = true;
- return ERR_CONNECTION_CLOSED;
- }
- // If read is pending, try write as well.
- // Otherwise, return the result and do next loop (to close the
- // connection).
- if (result != ERR_IO_PENDING) {
- next_state_ = STATE_CLOSE;
- server_closed_ = true;
- return result;
- }
- }
- // Read is pending.
- DCHECK(read_buf_.get());
- }
-
- if (waiting_for_write_completion_)
- return ERR_IO_PENDING;
-
- if (!current_write_buf_.get()) {
- if (pending_write_bufs_.empty()) {
- // Nothing buffered for send.
- return ERR_IO_PENDING;
- }
-
- current_write_buf_ = new DrainableIOBuffer(
- pending_write_bufs_.front().get(), pending_write_bufs_.front()->size());
- pending_write_bufs_.pop_front();
- }
-
- result = connection_->socket()->Write(
- current_write_buf_.get(),
- current_write_buf_->BytesRemaining(),
- base::Bind(&SocketStream::OnWriteCompleted, base::Unretained(this)));
-
- if (result == ERR_IO_PENDING) {
- waiting_for_write_completion_ = true;
- } else if (result < 0) {
- // Shortcut. Enter STATE_CLOSE now by changing next_state_ here than by
- // calling DoReadWrite() again with the error code.
- next_state_ = STATE_CLOSE;
- } else if (result > 0) {
- // Write is not pending. Return OK and do next loop.
- DidSendData(result);
- result = OK;
- }
-
- return result;
-}
-
-GURL SocketStream::ProxyAuthOrigin() const {
- DCHECK(!proxy_info_.is_empty());
- return GURL("http://" +
- proxy_info_.proxy_server().host_port_pair().ToString());
-}
-
-int SocketStream::HandleCertificateRequest(int result, SSLConfig* ssl_config) {
- if (ssl_config->send_client_cert) {
- // We already have performed SSL client authentication once and failed.
- return result;
- }
-
- DCHECK(connection_->socket());
- scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo;
- SSLClientSocket* ssl_socket =
- static_cast<SSLClientSocket*>(connection_->socket());
- ssl_socket->GetSSLCertRequestInfo(cert_request_info.get());
-
- HttpTransactionFactory* factory = context_->http_transaction_factory();
- if (!factory)
- return result;
- scoped_refptr<HttpNetworkSession> session = factory->GetSession();
- if (!session.get())
- return result;
-
- // If the user selected one of the certificates in client_certs or declined
- // to provide one for this server before, use the past decision
- // automatically.
- scoped_refptr<X509Certificate> client_cert;
- if (!session->ssl_client_auth_cache()->Lookup(
- cert_request_info->host_and_port, &client_cert)) {
- return result;
- }
-
- // Note: |client_cert| may be NULL, indicating that the caller
- // wishes to proceed anonymously (eg: continue the handshake
- // without sending a client cert)
- //
- // Check that the certificate selected is still a certificate the server
- // is likely to accept, based on the criteria supplied in the
- // CertificateRequest message.
- const std::vector<std::string>& cert_authorities =
- cert_request_info->cert_authorities;
- if (client_cert.get() && !cert_authorities.empty() &&
- !client_cert->IsIssuedByEncoded(cert_authorities)) {
- return result;
- }
-
- ssl_config->send_client_cert = true;
- ssl_config->client_cert = client_cert;
- next_state_ = STATE_TCP_CONNECT;
- return OK;
-}
-
-int SocketStream::AllowCertErrorForReconnection(SSLConfig* ssl_config) {
- DCHECK(ssl_config);
- // The SSL handshake didn't finish, or the server closed the SSL connection.
- // So, we should restart establishing connection with the certificate in
- // allowed bad certificates in |ssl_config|.
- // See also net/http/http_network_transaction.cc HandleCertificateError() and
- // RestartIgnoringLastError().
- SSLClientSocket* ssl_socket =
- static_cast<SSLClientSocket*>(connection_->socket());
- SSLInfo ssl_info;
- ssl_socket->GetSSLInfo(&ssl_info);
- if (ssl_info.cert.get() == NULL ||
- ssl_config->IsAllowedBadCert(ssl_info.cert.get(), NULL)) {
- // If we already have the certificate in the set of allowed bad
- // certificates, we did try it and failed again, so we should not
- // retry again: the connection should fail at last.
- next_state_ = STATE_CLOSE;
- return ERR_UNEXPECTED;
- }
- // Add the bad certificate to the set of allowed certificates in the
- // SSL config object.
- SSLConfig::CertAndStatus bad_cert;
- if (!X509Certificate::GetDEREncoded(ssl_info.cert->os_cert_handle(),
- &bad_cert.der_cert)) {
- next_state_ = STATE_CLOSE;
- return ERR_UNEXPECTED;
- }
- bad_cert.cert_status = ssl_info.cert_status;
- ssl_config->allowed_bad_certs.push_back(bad_cert);
- // Restart connection ignoring the bad certificate.
- connection_->socket()->Disconnect();
- connection_->SetSocket(scoped_ptr<StreamSocket>());
- next_state_ = STATE_TCP_CONNECT;
- return OK;
-}
-
-void SocketStream::DoAuthRequired() {
- if (delegate_ && proxy_auth_controller_.get())
- delegate_->OnAuthRequired(this, proxy_auth_controller_->auth_info().get());
- else
- DoLoop(ERR_UNEXPECTED);
-}
-
-void SocketStream::DoRestartWithAuth() {
- DCHECK_EQ(next_state_, STATE_AUTH_REQUIRED);
- tunnel_request_headers_ = NULL;
- tunnel_request_headers_bytes_sent_ = 0;
- tunnel_response_headers_ = NULL;
- tunnel_response_headers_capacity_ = 0;
- tunnel_response_headers_len_ = 0;
-
- next_state_ = STATE_TCP_CONNECT;
- DoLoop(OK);
-}
-
-int SocketStream::HandleCertificateError(int result) {
- DCHECK(IsCertificateError(result));
- SSLClientSocket* ssl_socket =
- static_cast<SSLClientSocket*>(connection_->socket());
- DCHECK(ssl_socket);
-
- if (!context_)
- return result;
-
- if (SSLClientSocket::IgnoreCertError(result, LOAD_IGNORE_ALL_CERT_ERRORS)) {
- const HttpNetworkSession::Params* session_params =
- context_->GetNetworkSessionParams();
- if (session_params && session_params->ignore_certificate_errors)
- return OK;
- }
-
- if (!delegate_)
- return result;
-
- SSLInfo ssl_info;
- ssl_socket->GetSSLInfo(&ssl_info);
-
- TransportSecurityState* state = context_->transport_security_state();
- const bool fatal = state && state->ShouldSSLErrorsBeFatal(url_.host());
-
- delegate_->OnSSLCertificateError(this, ssl_info, fatal);
- return ERR_IO_PENDING;
-}
-
-CookieStore* SocketStream::cookie_store() const {
- return cookie_store_.get();
-}
-
-} // namespace net
« no previous file with comments | « net/socket_stream/socket_stream.h ('k') | net/socket_stream/socket_stream_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698