| Index: net/socket/ssl_client_socket_openssl.cc
|
| diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
|
| index 4ff8d438e965b1fdf0b5b7f8b4ecdb75e1d14d66..97742bbeec58158690ff3f89d80f31a1a6bf9500 100644
|
| --- a/net/socket/ssl_client_socket_openssl.cc
|
| +++ b/net/socket/ssl_client_socket_openssl.cc
|
| @@ -87,14 +87,6 @@ int GetNetSSLVersion(SSL* ssl) {
|
| }
|
| }
|
|
|
| -// Compute a unique key string for the SSL session cache. |socket| is an
|
| -// input socket object. Return a string.
|
| -std::string GetSocketSessionCacheKey(const SSLClientSocketOpenSSL& socket) {
|
| - std::string result = socket.host_and_port().ToString();
|
| - result.append("/");
|
| - result.append(socket.ssl_session_cache_shard());
|
| - return result;
|
| -}
|
|
|
| } // namespace
|
|
|
| @@ -139,7 +131,7 @@ class SSLClientSocketOpenSSL::SSLContext {
|
| static std::string GetSessionCacheKey(const SSL* ssl) {
|
| SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl);
|
| DCHECK(socket);
|
| - return GetSocketSessionCacheKey(*socket);
|
| + return socket->GetSessionCacheKey();
|
| }
|
|
|
| static SSLSessionCacheOpenSSL::Config kDefaultSessionCacheConfig;
|
| @@ -340,6 +332,8 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
|
| : transport_send_busy_(false),
|
| transport_recv_busy_(false),
|
| transport_recv_eof_(false),
|
| + has_read_(false),
|
| + has_written_(false),
|
| weak_factory_(this),
|
| pending_read_error_(kNoPendingReadResult),
|
| transport_write_error_(OK),
|
| @@ -349,6 +343,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
|
| client_auth_cert_needed_(false),
|
| cert_verifier_(context.cert_verifier),
|
| server_bound_cert_service_(context.server_bound_cert_service),
|
| + is_leader_(false),
|
| ssl_(NULL),
|
| transport_bio_(NULL),
|
| transport_(transport_socket.Pass()),
|
| @@ -360,12 +355,51 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
|
| npn_status_(kNextProtoUnsupported),
|
| channel_id_request_return_value_(ERR_UNEXPECTED),
|
| channel_id_xtn_negotiated_(false),
|
| - net_log_(transport_->socket()->NetLog()) {}
|
| + net_log_(transport_->socket()->NetLog()) {
|
| +}
|
|
|
| SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
|
| + SSLContext* context = SSLContext::GetInstance();
|
| + context->session_cache()->RemoveFromSSLToCallbackMap(ssl_);
|
| Disconnect();
|
| }
|
|
|
| +// Compute a unique key string for the SSL session cache.
|
| +// Return a string.
|
| +std::string SSLClientSocketOpenSSL::GetSessionCacheKey() const {
|
| + return FormatSessionCacheKey(host_and_port_.ToString(),
|
| + ssl_session_cache_shard_);
|
| +}
|
| +
|
| +bool SSLClientSocketOpenSSL::InSessionCache() const {
|
| + SSLContext* context = SSLContext::GetInstance();
|
| + std::string cache_key = GetSessionCacheKey();
|
| + return context->session_cache()->SSLSessionIsInCache(cache_key);
|
| +}
|
| +
|
| +void SSLClientSocketOpenSSL::WatchSessionForCompletion(
|
| + const base::Closure& callback) {
|
| + SSLContext* context = SSLContext::GetInstance();
|
| + context->session_cache()->RegisterSessionAddedCallback(ssl_, callback);
|
| +}
|
| +
|
| +void SSLClientSocketOpenSSL::SetSocketFailureCallback(
|
| + const base::Closure& callback) {
|
| + error_callback_ = callback;
|
| +}
|
| +
|
| +void SSLClientSocketOpenSSL::SetIsLeader() {
|
| + is_leader_ = true;
|
| +}
|
| +
|
| +void SSLClientSocketOpenSSL::OnSocketFailure() {
|
| + if (is_leader_) {
|
| + error_callback_.Run();
|
| + error_callback_ = base::Closure();
|
| + is_leader_ = false;
|
| + }
|
| +}
|
| +
|
| void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
|
| SSLCertRequestInfo* cert_request_info) {
|
| cert_request_info->host_and_port = host_and_port_;
|
| @@ -658,7 +692,7 @@ int SSLClientSocketOpenSSL::Init() {
|
| return ERR_UNEXPECTED;
|
|
|
| trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey(
|
| - ssl_, GetSocketSessionCacheKey(*this));
|
| + ssl_, GetSessionCacheKey());
|
|
|
| BIO* ssl_bio = NULL;
|
| // 0 => use default buffer sizes.
|
| @@ -1064,6 +1098,11 @@ int SSLClientSocketOpenSSL::DoPayloadRead() {
|
| do {
|
| rv = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read,
|
| user_read_buf_len_ - total_bytes_read);
|
| + // Failure of the first read attempt indicates a failed false start
|
| + // connection.
|
| + if (!has_read_ && rv != OK && SSLClientSocket::GetEnableConnectJobWaiting())
|
| + OnSocketFailure();
|
| + has_read_ = true;
|
| if (rv > 0)
|
| total_bytes_read += rv;
|
| } while (total_bytes_read < user_read_buf_len_ && rv > 0);
|
| @@ -1116,7 +1155,13 @@ int SSLClientSocketOpenSSL::DoPayloadRead() {
|
| int SSLClientSocketOpenSSL::DoPayloadWrite() {
|
| crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
|
| int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
|
| -
|
| + // Failure of the second write attempt indicates a failed false start
|
| + // connection.
|
| + if (has_written_ == 1 && rv != OK &&
|
| + SSLClientSocket::GetEnableConnectJobWaiting()) {
|
| + OnSocketFailure();
|
| + }
|
| + has_written_++;
|
| if (rv >= 0) {
|
| net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv,
|
| user_write_buf_->data());
|
|
|