summaryrefslogtreecommitdiff
path: root/chromium/net/http
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2014-03-18 13:16:26 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-20 15:55:39 +0100
commit3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch)
tree92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/net/http
parente90d7c4b152c56919d963987e2503f9909a666d2 (diff)
downloadqtwebengine-chromium-3f0f86b0caed75241fa71c95a5d73bc0164348c5.tar.gz
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies needed on Windows. Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42 Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu> Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/net/http')
-rw-r--r--chromium/net/http/http_auth_cache.cc3
-rw-r--r--chromium/net/http/http_auth_gssapi_posix.cc12
-rw-r--r--chromium/net/http/http_auth_gssapi_posix.h4
-rw-r--r--chromium/net/http/http_auth_gssapi_posix_unittest.cc6
-rw-r--r--chromium/net/http/http_auth_handler_basic.cc10
-rw-r--r--chromium/net/http/http_auth_handler_digest.cc3
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.cc11
-rw-r--r--chromium/net/http/http_auth_handler_negotiate.h6
-rw-r--r--chromium/net/http/http_auth_handler_negotiate_unittest.cc20
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.cc12
-rw-r--r--chromium/net/http/http_auth_handler_ntlm.h2
-rw-r--r--chromium/net/http/http_auth_sspi_win.cc13
-rw-r--r--chromium/net/http/http_auth_sspi_win.h4
-rw-r--r--chromium/net/http/http_auth_sspi_win_unittest.cc6
-rw-r--r--chromium/net/http/http_basic_state.cc68
-rw-r--r--chromium/net/http/http_basic_state.h72
-rw-r--r--chromium/net/http/http_basic_state_unittest.cc78
-rw-r--r--chromium/net/http/http_basic_stream.cc91
-rw-r--r--chromium/net/http/http_basic_stream.h29
-rw-r--r--chromium/net/http/http_byte_range.cc41
-rw-r--r--chromium/net/http/http_byte_range.h14
-rw-r--r--chromium/net/http/http_byte_range_unittest.cc14
-rw-r--r--chromium/net/http/http_cache_transaction.cc43
-rw-r--r--chromium/net/http/http_cache_transaction.h11
-rw-r--r--chromium/net/http/http_cache_unittest.cc107
-rw-r--r--chromium/net/http/http_chunked_decoder.cc2
-rw-r--r--chromium/net/http/http_network_layer.cc13
-rw-r--r--chromium/net/http/http_network_layer.h6
-rw-r--r--chromium/net/http/http_network_layer_unittest.cc493
-rw-r--r--chromium/net/http/http_network_session.cc11
-rw-r--r--chromium/net/http/http_network_session.h9
-rw-r--r--chromium/net/http/http_network_session_peer.cc14
-rw-r--r--chromium/net/http/http_network_session_peer.h8
-rw-r--r--chromium/net/http/http_network_transaction.cc229
-rw-r--r--chromium/net/http/http_network_transaction.h26
-rw-r--r--chromium/net/http/http_network_transaction_ssl_unittest.cc146
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc526
-rw-r--r--chromium/net/http/http_pipelined_connection_impl.cc7
-rw-r--r--chromium/net/http/http_pipelined_connection_impl.h2
-rw-r--r--chromium/net/http/http_pipelined_host_forced_unittest.cc4
-rw-r--r--chromium/net/http/http_pipelined_host_impl_unittest.cc8
-rw-r--r--chromium/net/http/http_pipelined_stream.cc4
-rw-r--r--chromium/net/http/http_pipelined_stream.h2
-rw-r--r--chromium/net/http/http_proxy_client_socket_pool_unittest.cc9
-rw-r--r--chromium/net/http/http_request_headers.cc21
-rw-r--r--chromium/net/http/http_request_info.cc1
-rw-r--r--chromium/net/http/http_request_info.h4
-rw-r--r--chromium/net/http/http_response_body_drainer.cc4
-rw-r--r--chromium/net/http/http_response_body_drainer.h6
-rw-r--r--chromium/net/http/http_response_body_drainer_unittest.cc1
-rw-r--r--chromium/net/http/http_response_headers.cc71
-rw-r--r--chromium/net/http/http_response_headers.h29
-rw-r--r--chromium/net/http/http_response_headers_unittest.cc153
-rw-r--r--chromium/net/http/http_response_info.cc39
-rw-r--r--chromium/net/http/http_response_info.h2
-rw-r--r--chromium/net/http/http_security_headers.cc13
-rw-r--r--chromium/net/http/http_security_headers_unittest.cc14
-rw-r--r--chromium/net/http/http_server_properties.cc41
-rw-r--r--chromium/net/http/http_server_properties.h21
-rw-r--r--chromium/net/http/http_server_properties_impl.cc6
-rw-r--r--chromium/net/http/http_server_properties_impl.h4
-rw-r--r--chromium/net/http/http_server_properties_impl_unittest.cc18
-rw-r--r--chromium/net/http/http_stream_base.h5
-rw-r--r--chromium/net/http/http_stream_factory.cc82
-rw-r--r--chromium/net/http/http_stream_factory.h47
-rw-r--r--chromium/net/http/http_stream_factory_impl.cc30
-rw-r--r--chromium/net/http/http_stream_factory_impl.h9
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.cc36
-rw-r--r--chromium/net/http/http_stream_factory_impl_job.h4
-rw-r--r--chromium/net/http/http_stream_factory_impl_request.cc21
-rw-r--r--chromium/net/http/http_stream_factory_impl_request.h19
-rw-r--r--chromium/net/http/http_stream_factory_impl_request_unittest.cc7
-rw-r--r--chromium/net/http/http_stream_factory_impl_unittest.cc278
-rw-r--r--chromium/net/http/http_stream_parser.cc6
-rw-r--r--chromium/net/http/http_stream_parser.h6
-rw-r--r--chromium/net/http/http_stream_parser_unittest.cc399
-rw-r--r--chromium/net/http/http_transaction.h7
-rw-r--r--chromium/net/http/http_transaction_unittest.cc6
-rw-r--r--chromium/net/http/http_transaction_unittest.h8
-rw-r--r--chromium/net/http/http_util_icu.cc7
-rw-r--r--chromium/net/http/http_util_unittest.cc22
-rw-r--r--chromium/net/http/partial_data.cc44
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.cc4
-rw-r--r--chromium/net/http/proxy_connect_redirect_http_stream.h2
-rw-r--r--chromium/net/http/transport_security_persister.cc318
-rw-r--r--chromium/net/http/transport_security_persister.h138
-rw-r--r--chromium/net/http/transport_security_persister_unittest.cc201
-rw-r--r--chromium/net/http/transport_security_state.cc13
-rw-r--r--chromium/net/http/transport_security_state.h2
-rw-r--r--chromium/net/http/transport_security_state_static.certs309
-rw-r--r--chromium/net/http/transport_security_state_static.h139
-rw-r--r--chromium/net/http/transport_security_state_static.json82
-rw-r--r--chromium/net/http/transport_security_state_unittest.cc180
93 files changed, 3545 insertions, 1533 deletions
diff --git a/chromium/net/http/http_auth_cache.cc b/chromium/net/http/http_auth_cache.cc
index 1c8c03fbb25..63bad076df1 100644
--- a/chromium/net/http/http_auth_cache.cc
+++ b/chromium/net/http/http_auth_cache.cc
@@ -43,7 +43,8 @@ bool IsEnclosingPath(const std::string& container, const std::string& path) {
void CheckOriginIsValid(const GURL& origin) {
DCHECK(origin.is_valid());
// Note that the scheme may be FTP when we're using a HTTP proxy.
- DCHECK(origin.SchemeIsHTTPOrHTTPS() || origin.SchemeIs("ftp"));
+ DCHECK(origin.SchemeIsHTTPOrHTTPS() || origin.SchemeIs("ftp") ||
+ origin.SchemeIsWSOrWSS());
DCHECK(origin.GetOrigin() == origin);
}
diff --git a/chromium/net/http/http_auth_gssapi_posix.cc b/chromium/net/http/http_auth_gssapi_posix.cc
index 4d7bf074061..41cbcdbcdc0 100644
--- a/chromium/net/http/http_auth_gssapi_posix.cc
+++ b/chromium/net/http/http_auth_gssapi_posix.cc
@@ -715,7 +715,7 @@ HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge(
}
int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials,
- const std::wstring& spn,
+ const std::string& spn,
std::string* auth_token) {
DCHECK(auth_token);
@@ -734,11 +734,7 @@ int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials,
std::string encode_input(static_cast<char*>(output_token.value),
output_token.length);
std::string encode_output;
- bool base64_rv = base::Base64Encode(encode_input, &encode_output);
- if (!base64_rv) {
- LOG(ERROR) << "Base64 encoding of auth token failed.";
- return ERR_ENCODING_CONVERSION_FAILED;
- }
+ base::Base64Encode(encode_input, &encode_output);
*auth_token = scheme_ + " " + encode_output;
return OK;
}
@@ -837,12 +833,12 @@ int MapInitSecContextStatusToError(OM_uint32 major_status) {
}
-int HttpAuthGSSAPI::GetNextSecurityToken(const std::wstring& spn,
+int HttpAuthGSSAPI::GetNextSecurityToken(const std::string& spn,
gss_buffer_t in_token,
gss_buffer_t out_token) {
// Create a name for the principal
// TODO(cbentzel): Just do this on the first pass?
- std::string spn_principal = WideToASCII(spn);
+ std::string spn_principal = spn;
gss_buffer_desc spn_buffer = GSS_C_EMPTY_BUFFER;
spn_buffer.value = const_cast<char*>(spn_principal.c_str());
spn_buffer.length = spn_principal.size() + 1;
diff --git a/chromium/net/http/http_auth_gssapi_posix.h b/chromium/net/http/http_auth_gssapi_posix.h
index afa50a02c9f..db603f65da8 100644
--- a/chromium/net/http/http_auth_gssapi_posix.h
+++ b/chromium/net/http/http_auth_gssapi_posix.h
@@ -251,7 +251,7 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI {
// obtained using |*credentials|. If |credentials| is NULL, the default
// credentials are used instead.
int GenerateAuthToken(const AuthCredentials* credentials,
- const std::wstring& spn,
+ const std::string& spn,
std::string* auth_token);
// Delegation is allowed on the Kerberos ticket. This allows certain servers
@@ -260,7 +260,7 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI {
void Delegate();
private:
- int GetNextSecurityToken(const std::wstring& spn,
+ int GetNextSecurityToken(const std::string& spn,
gss_buffer_t in_token,
gss_buffer_t out_token);
diff --git a/chromium/net/http/http_auth_gssapi_posix_unittest.cc b/chromium/net/http/http_auth_gssapi_posix_unittest.cc
index 1c3d12b6c29..48d17a3ad64 100644
--- a/chromium/net/http/http_auth_gssapi_posix_unittest.cc
+++ b/chromium/net/http/http_auth_gssapi_posix_unittest.cc
@@ -202,7 +202,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) {
// Generate an auth token and create another thing.
EstablishInitialContext(&mock_library);
std::string auth_token;
- EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate Zm9vYmFy";
@@ -239,7 +239,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) {
EstablishInitialContext(&mock_library);
std::string auth_token;
- EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate";
HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
@@ -262,7 +262,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) {
EstablishInitialContext(&mock_library);
std::string auth_token;
- EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate =happyjoy=";
HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
diff --git a/chromium/net/http/http_auth_handler_basic.cc b/chromium/net/http/http_auth_handler_basic.cc
index af5f188b156..e445c93100c 100644
--- a/chromium/net/http/http_auth_handler_basic.cc
+++ b/chromium/net/http/http_auth_handler_basic.cc
@@ -91,13 +91,9 @@ int HttpAuthHandlerBasic::GenerateAuthTokenImpl(
DCHECK(credentials);
// TODO(eroman): is this the right encoding of username/password?
std::string base64_username_password;
- if (!base::Base64Encode(
- UTF16ToUTF8(credentials->username()) + ":" +
- UTF16ToUTF8(credentials->password()),
- &base64_username_password)) {
- LOG(ERROR) << "Unexpected problem Base64 encoding.";
- return ERR_UNEXPECTED;
- }
+ base::Base64Encode(UTF16ToUTF8(credentials->username()) + ":" +
+ UTF16ToUTF8(credentials->password()),
+ &base64_username_password);
*auth_token = "Basic " + base64_username_password;
return OK;
}
diff --git a/chromium/net/http/http_auth_handler_digest.cc b/chromium/net/http/http_auth_handler_digest.cc
index 904430ecb40..a8e301a02e8 100644
--- a/chromium/net/http/http_auth_handler_digest.cc
+++ b/chromium/net/http/http_auth_handler_digest.cc
@@ -18,6 +18,7 @@
#include "net/http/http_auth.h"
#include "net/http/http_request_info.h"
#include "net/http/http_util.h"
+#include "url/gurl.h"
namespace net {
@@ -304,7 +305,7 @@ void HttpAuthHandlerDigest::GetRequestMethodAndPath(
const GURL& url = request->url;
if (target_ == HttpAuth::AUTH_PROXY &&
- (url.SchemeIs("https") || url.SchemeIs("ws") || url.SchemeIs("wss"))) {
+ (url.SchemeIs("https") || url.SchemeIsWSOrWSS())) {
*method = "CONNECT";
*path = GetHostAndPort(url);
} else {
diff --git a/chromium/net/http/http_auth_handler_negotiate.cc b/chromium/net/http/http_auth_handler_negotiate.cc
index 13b106925b7..788b06750b6 100644
--- a/chromium/net/http/http_auth_handler_negotiate.cc
+++ b/chromium/net/http/http_auth_handler_negotiate.cc
@@ -7,9 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
#include "net/base/address_family.h"
#include "net/base/net_errors.h"
#include "net/dns/host_resolver.h"
@@ -114,7 +112,7 @@ HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate(
HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
}
-std::wstring HttpAuthHandlerNegotiate::CreateSPN(
+std::string HttpAuthHandlerNegotiate::CreateSPN(
const AddressList& address_list, const GURL& origin) {
// Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI,
// and in the form HTTP@<host>:<port> through GSSAPI
@@ -155,11 +153,10 @@ std::wstring HttpAuthHandlerNegotiate::CreateSPN(
static const char kSpnSeparator = '@';
#endif
if (port != 80 && port != 443 && use_port_) {
- return ASCIIToWide(base::StringPrintf("HTTP%c%s:%d", kSpnSeparator,
- server.c_str(), port));
+ return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(),
+ port);
} else {
- return ASCIIToWide(base::StringPrintf("HTTP%c%s", kSpnSeparator,
- server.c_str()));
+ return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str());
}
}
diff --git a/chromium/net/http/http_auth_handler_negotiate.h b/chromium/net/http/http_auth_handler_negotiate.h
index 6fd7aa9a068..d028178ed51 100644
--- a/chromium/net/http/http_auth_handler_negotiate.h
+++ b/chromium/net/http/http_auth_handler_negotiate.h
@@ -102,8 +102,8 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
virtual ~HttpAuthHandlerNegotiate();
// These are public for unit tests
- std::wstring CreateSPN(const AddressList& address_list, const GURL& orign);
- const std::wstring& spn() const { return spn_; }
+ std::string CreateSPN(const AddressList& address_list, const GURL& orign);
+ const std::string& spn() const { return spn_; }
// HttpAuthHandler:
virtual HttpAuth::AuthorizationResult HandleAnotherChallenge(
@@ -152,7 +152,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
bool already_called_;
bool has_credentials_;
AuthCredentials credentials_;
- std::wstring spn_;
+ std::string spn_;
// Things which vary each round.
CompletionCallback callback_;
diff --git a/chromium/net/http/http_auth_handler_negotiate_unittest.cc b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
index 809f58e1fcc..64521a6177f 100644
--- a/chromium/net/http/http_auth_handler_negotiate_unittest.cc
+++ b/chromium/net/http/http_auth_handler_negotiate_unittest.cc
@@ -226,9 +226,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, DisableCname) {
EXPECT_EQ(OK, auth_handler->GenerateAuthToken(NULL, &request_info,
callback.callback(), &token));
#if defined(OS_WIN)
- EXPECT_EQ(L"HTTP/alias", auth_handler->spn());
+ EXPECT_EQ("HTTP/alias", auth_handler->spn());
#elif defined(OS_POSIX)
- EXPECT_EQ(L"HTTP@alias", auth_handler->spn());
+ EXPECT_EQ("HTTP@alias", auth_handler->spn());
#endif
}
@@ -244,9 +244,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, DisableCnameStandardPort) {
EXPECT_EQ(OK, auth_handler->GenerateAuthToken(NULL, &request_info,
callback.callback(), &token));
#if defined(OS_WIN)
- EXPECT_EQ(L"HTTP/alias", auth_handler->spn());
+ EXPECT_EQ("HTTP/alias", auth_handler->spn());
#elif defined(OS_POSIX)
- EXPECT_EQ(L"HTTP@alias", auth_handler->spn());
+ EXPECT_EQ("HTTP@alias", auth_handler->spn());
#endif
}
@@ -262,9 +262,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, DisableCnameNonstandardPort) {
EXPECT_EQ(OK, auth_handler->GenerateAuthToken(NULL, &request_info,
callback.callback(), &token));
#if defined(OS_WIN)
- EXPECT_EQ(L"HTTP/alias:500", auth_handler->spn());
+ EXPECT_EQ("HTTP/alias:500", auth_handler->spn());
#elif defined(OS_POSIX)
- EXPECT_EQ(L"HTTP@alias:500", auth_handler->spn());
+ EXPECT_EQ("HTTP@alias:500", auth_handler->spn());
#endif
}
@@ -280,9 +280,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, CnameSync) {
EXPECT_EQ(OK, auth_handler->GenerateAuthToken(NULL, &request_info,
callback.callback(), &token));
#if defined(OS_WIN)
- EXPECT_EQ(L"HTTP/canonical.example.com", auth_handler->spn());
+ EXPECT_EQ("HTTP/canonical.example.com", auth_handler->spn());
#elif defined(OS_POSIX)
- EXPECT_EQ(L"HTTP@canonical.example.com", auth_handler->spn());
+ EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn());
#endif
}
@@ -299,9 +299,9 @@ TEST_F(HttpAuthHandlerNegotiateTest, CnameAsync) {
NULL, &request_info, callback.callback(), &token));
EXPECT_EQ(OK, callback.WaitForResult());
#if defined(OS_WIN)
- EXPECT_EQ(L"HTTP/canonical.example.com", auth_handler->spn());
+ EXPECT_EQ("HTTP/canonical.example.com", auth_handler->spn());
#elif defined(OS_POSIX)
- EXPECT_EQ(L"HTTP@canonical.example.com", auth_handler->spn());
+ EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn());
#endif
}
diff --git a/chromium/net/http/http_auth_handler_ntlm.cc b/chromium/net/http/http_auth_handler_ntlm.cc
index 4c04234e22e..922800c71e1 100644
--- a/chromium/net/http/http_auth_handler_ntlm.cc
+++ b/chromium/net/http/http_auth_handler_ntlm.cc
@@ -89,13 +89,9 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
// Base64 encode data in output buffer and prepend "NTLM ".
std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
std::string encode_output;
- bool base64_rv = base::Base64Encode(encode_input, &encode_output);
+ base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf|
free(out_buf);
- if (!base64_rv) {
- LOG(ERROR) << "Unexpected problem Base64 encoding.";
- return ERR_UNEXPECTED;
- }
*auth_token = std::string("NTLM ") + encode_output;
return OK;
#endif
@@ -136,11 +132,11 @@ HttpAuth::AuthorizationResult HttpAuthHandlerNTLM::ParseChallenge(
}
// static
-std::wstring HttpAuthHandlerNTLM::CreateSPN(const GURL& origin) {
+std::string HttpAuthHandlerNTLM::CreateSPN(const GURL& origin) {
// The service principal name of the destination server. See
// http://msdn.microsoft.com/en-us/library/ms677949%28VS.85%29.aspx
- std::wstring target(L"HTTP/");
- target.append(ASCIIToWide(GetHostAndPort(origin)));
+ std::string target("HTTP/");
+ target.append(GetHostAndPort(origin));
return target;
}
diff --git a/chromium/net/http/http_auth_handler_ntlm.h b/chromium/net/http/http_auth_handler_ntlm.h
index 971dd1fc06f..98bd362d543 100644
--- a/chromium/net/http/http_auth_handler_ntlm.h
+++ b/chromium/net/http/http_auth_handler_ntlm.h
@@ -145,7 +145,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
uint32* out_token_len);
// Create an NTLM SPN to identify the |origin| server.
- static std::wstring CreateSPN(const GURL& origin);
+ static std::string CreateSPN(const GURL& origin);
#if defined(NTLM_SSPI)
HttpAuthSSPI auth_sspi_;
diff --git a/chromium/net/http/http_auth_sspi_win.cc b/chromium/net/http/http_auth_sspi_win.cc
index abc80508bd8..5718f9ef753 100644
--- a/chromium/net/http/http_auth_sspi_win.cc
+++ b/chromium/net/http/http_auth_sspi_win.cc
@@ -255,7 +255,7 @@ HttpAuth::AuthorizationResult HttpAuthSSPI::ParseChallenge(
}
int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials,
- const std::wstring& spn,
+ const std::string& spn,
std::string* auth_token) {
// Initial challenge.
if (!SecIsValidHandle(&cred_)) {
@@ -280,13 +280,9 @@ int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials,
// Base64 encode data in output buffer and prepend the scheme.
std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
std::string encode_output;
- bool base64_rv = base::Base64Encode(encode_input, &encode_output);
+ base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf|
free(out_buf);
- if (!base64_rv) {
- LOG(ERROR) << "Base64 encoding of auth token failed.";
- return ERR_ENCODING_CONVERSION_FAILED;
- }
*auth_token = scheme_ + " " + encode_output;
return OK;
}
@@ -312,7 +308,7 @@ int HttpAuthSSPI::OnFirstRound(const AuthCredentials* credentials) {
}
int HttpAuthSSPI::GetNextSecurityToken(
- const std::wstring& spn,
+ const std::string& spn,
const void* in_token,
int in_token_len,
void** out_token,
@@ -362,10 +358,11 @@ int HttpAuthSSPI::GetNextSecurityToken(
// This returns a token that is passed to the remote server.
DWORD context_attribute;
+ std::wstring spn_wide = base::ASCIIToWide(spn);
SECURITY_STATUS status = library_->InitializeSecurityContext(
&cred_, // phCredential
ctxt_ptr, // phContext
- const_cast<wchar_t *>(spn.c_str()), // pszTargetName
+ const_cast<wchar_t *>(spn_wide.c_str()), // pszTargetName
context_flags, // fContextReq
0, // Reserved1 (must be 0)
SECURITY_NATIVE_DREP, // TargetDataRep
diff --git a/chromium/net/http/http_auth_sspi_win.h b/chromium/net/http/http_auth_sspi_win.h
index 57a3daacfc5..bc7da46c312 100644
--- a/chromium/net/http/http_auth_sspi_win.h
+++ b/chromium/net/http/http_auth_sspi_win.h
@@ -144,7 +144,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI {
// obtained using |*credentials|. If |credentials| is NULL, the credentials
// for the currently logged in user are used instead.
int GenerateAuthToken(const AuthCredentials* credentials,
- const std::wstring& spn,
+ const std::string& spn,
std::string* auth_token);
// Delegation is allowed on the Kerberos ticket. This allows certain servers
@@ -156,7 +156,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI {
int OnFirstRound(const AuthCredentials* credentials);
int GetNextSecurityToken(
- const std::wstring& spn,
+ const std::string& spn,
const void* in_token,
int in_token_len,
void** out_token,
diff --git a/chromium/net/http/http_auth_sspi_win_unittest.cc b/chromium/net/http/http_auth_sspi_win_unittest.cc
index d8521375900..09fe6fa25ef 100644
--- a/chromium/net/http/http_auth_sspi_win_unittest.cc
+++ b/chromium/net/http/http_auth_sspi_win_unittest.cc
@@ -82,7 +82,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_TwoRounds) {
// Generate an auth token and create another thing.
std::string auth_token;
- EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate Zm9vYmFy";
@@ -118,7 +118,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_MissingTokenSecondRound) {
auth_sspi.ParseChallenge(&first_challenge));
std::string auth_token;
- EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate";
HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
@@ -140,7 +140,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) {
auth_sspi.ParseChallenge(&first_challenge));
std::string auth_token;
- EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
+ EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
&auth_token));
std::string second_challenge_text = "Negotiate =happyjoy=";
HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
diff --git a/chromium/net/http/http_basic_state.cc b/chromium/net/http/http_basic_state.cc
new file mode 100644
index 00000000000..2b173b0897b
--- /dev/null
+++ b/chromium/net/http/http_basic_state.cc
@@ -0,0 +1,68 @@
+// Copyright 2013 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.
+
+#include "net/http/http_basic_state.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "net/base/io_buffer.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_body_drainer.h"
+#include "net/http/http_stream_parser.h"
+#include "net/http/http_util.h"
+#include "net/socket/client_socket_handle.h"
+#include "url/gurl.h"
+
+namespace net {
+
+HttpBasicState::HttpBasicState(ClientSocketHandle* connection, bool using_proxy)
+ : read_buf_(new GrowableIOBuffer()),
+ connection_(connection),
+ using_proxy_(using_proxy),
+ request_info_(NULL) {}
+
+HttpBasicState::~HttpBasicState() {}
+
+int HttpBasicState::Initialize(const HttpRequestInfo* request_info,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback) {
+ DCHECK(!parser_.get());
+ request_info_ = request_info;
+ parser_.reset(new HttpStreamParser(
+ connection_.get(), request_info, read_buf_.get(), net_log));
+ return OK;
+}
+
+scoped_ptr<ClientSocketHandle> HttpBasicState::ReleaseConnection() {
+ return connection_.Pass();
+}
+
+scoped_refptr<GrowableIOBuffer> HttpBasicState::read_buf() const {
+ return read_buf_;
+}
+
+void HttpBasicState::DeleteParser() { parser_.reset(); }
+
+std::string HttpBasicState::GenerateRequestLine() const {
+ static const char kSuffix[] = " HTTP/1.1\r\n";
+ const size_t kSuffixLen = arraysize(kSuffix) - 1;
+ DCHECK(request_info_);
+ const GURL& url = request_info_->url;
+ const std::string path = using_proxy_ ? HttpUtil::SpecForRequest(url)
+ : HttpUtil::PathForRequest(url);
+ // Don't use StringPrintf for concatenation because it is very inefficient.
+ std::string request_line;
+ const size_t expected_size = request_info_->method.size() + 1 + path.size() +
+ kSuffixLen;
+ request_line.reserve(expected_size);
+ request_line.append(request_info_->method);
+ request_line.append(1, ' ');
+ request_line.append(path);
+ request_line.append(kSuffix, kSuffixLen);
+ DCHECK_EQ(expected_size, request_line.size());
+ return request_line;
+}
+
+} // namespace net
diff --git a/chromium/net/http/http_basic_state.h b/chromium/net/http/http_basic_state.h
new file mode 100644
index 00000000000..259c5022252
--- /dev/null
+++ b/chromium/net/http/http_basic_state.h
@@ -0,0 +1,72 @@
+// Copyright 2013 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.
+//
+// A class that stores the common state between HttpBasicStream and
+// WebSocketBasicHandshakeStream.
+
+#ifndef NET_HTTP_HTTP_BASIC_STATE_H_
+#define NET_HTTP_HTTP_BASIC_STATE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/base/request_priority.h"
+
+namespace net {
+
+class BoundNetLog;
+class ClientSocketHandle;
+class GrowableIOBuffer;
+class HttpStreamParser;
+struct HttpRequestInfo;
+
+class NET_EXPORT_PRIVATE HttpBasicState {
+ public:
+ HttpBasicState(ClientSocketHandle* connection, bool using_proxy);
+ ~HttpBasicState();
+
+ // Initialize() must be called before using any of the other methods.
+ int Initialize(const HttpRequestInfo* request_info,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback);
+
+ HttpStreamParser* parser() const { return parser_.get(); }
+
+ bool using_proxy() const { return using_proxy_; }
+
+ // Deletes |parser_| and sets it to NULL.
+ void DeleteParser();
+
+ ClientSocketHandle* connection() const { return connection_.get(); }
+
+ scoped_ptr<ClientSocketHandle> ReleaseConnection();
+
+ scoped_refptr<GrowableIOBuffer> read_buf() const;
+
+ // Generates a string of the form "METHOD PATH HTTP/1.1\r\n", based on the
+ // values of request_info_ and using_proxy_.
+ std::string GenerateRequestLine() const;
+
+ private:
+ scoped_refptr<GrowableIOBuffer> read_buf_;
+
+ scoped_ptr<HttpStreamParser> parser_;
+
+ scoped_ptr<ClientSocketHandle> connection_;
+
+ const bool using_proxy_;
+
+ const HttpRequestInfo* request_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(HttpBasicState);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_HTTP_BASIC_STATE_H_
diff --git a/chromium/net/http/http_basic_state_unittest.cc b/chromium/net/http/http_basic_state_unittest.cc
new file mode 100644
index 00000000000..e95cfd26b59
--- /dev/null
+++ b/chromium/net/http/http_basic_state_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 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.
+
+#include "net/http/http_basic_state.h"
+
+#include "net/base/completion_callback.h"
+#include "net/base/request_priority.h"
+#include "net/http/http_request_info.h"
+#include "net/socket/client_socket_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+TEST(HttpBasicStateTest, ConstructsProperly) {
+ ClientSocketHandle* const handle = new ClientSocketHandle;
+ // Ownership of handle is passed to |state|.
+ const HttpBasicState state(handle, true);
+ EXPECT_EQ(handle, state.connection());
+ EXPECT_TRUE(state.using_proxy());
+}
+
+TEST(HttpBasicStateTest, UsingProxyCanBeFalse) {
+ const HttpBasicState state(new ClientSocketHandle(), false);
+ EXPECT_FALSE(state.using_proxy());
+}
+
+TEST(HttpBasicStateTest, ReleaseConnectionWorks) {
+ ClientSocketHandle* const handle = new ClientSocketHandle;
+ HttpBasicState state(handle, false);
+ const scoped_ptr<ClientSocketHandle> released_connection(
+ state.ReleaseConnection());
+ EXPECT_EQ(NULL, state.connection());
+ EXPECT_EQ(handle, released_connection.get());
+}
+
+TEST(HttpBasicStateTest, InitializeWorks) {
+ HttpBasicState state(new ClientSocketHandle(), false);
+ const HttpRequestInfo request_info;
+ EXPECT_EQ(OK,
+ state.Initialize(
+ &request_info, LOW, BoundNetLog(), CompletionCallback()));
+ EXPECT_TRUE(state.parser());
+}
+
+TEST(HttpBasicStateTest, DeleteParser) {
+ HttpBasicState state(new ClientSocketHandle(), false);
+ const HttpRequestInfo request_info;
+ state.Initialize(&request_info, LOW, BoundNetLog(), CompletionCallback());
+ EXPECT_TRUE(state.parser());
+ state.DeleteParser();
+ EXPECT_EQ(NULL, state.parser());
+}
+
+TEST(HttpBasicStateTest, GenerateRequestLineNoProxy) {
+ const bool use_proxy = false;
+ HttpBasicState state(new ClientSocketHandle(), use_proxy);
+ HttpRequestInfo request_info;
+ request_info.url = GURL("http://www.example.com/path?foo=bar#hoge");
+ request_info.method = "PUT";
+ state.Initialize(&request_info, LOW, BoundNetLog(), CompletionCallback());
+ EXPECT_EQ("PUT /path?foo=bar HTTP/1.1\r\n", state.GenerateRequestLine());
+}
+
+TEST(HttpBasicStateTest, GenerateRequestLineWithProxy) {
+ const bool use_proxy = true;
+ HttpBasicState state(new ClientSocketHandle(), use_proxy);
+ HttpRequestInfo request_info;
+ request_info.url = GURL("http://www.example.com/path?foo=bar#hoge");
+ request_info.method = "PUT";
+ state.Initialize(&request_info, LOW, BoundNetLog(), CompletionCallback());
+ EXPECT_EQ("PUT http://www.example.com/path?foo=bar HTTP/1.1\r\n",
+ state.GenerateRequestLine());
+}
+
+} // namespace
+} // namespace net
diff --git a/chromium/net/http/http_basic_stream.cc b/chromium/net/http/http_basic_stream.cc
index c30e17d6203..87f6469ad61 100644
--- a/chromium/net/http/http_basic_stream.cc
+++ b/chromium/net/http/http_basic_stream.cc
@@ -4,122 +4,107 @@
#include "net/http/http_basic_stream.h"
-#include "base/strings/stringprintf.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_request_headers.h"
+#include "base/memory/scoped_ptr.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_body_drainer.h"
#include "net/http/http_stream_parser.h"
-#include "net/http/http_util.h"
#include "net/socket/client_socket_handle.h"
namespace net {
HttpBasicStream::HttpBasicStream(ClientSocketHandle* connection,
- HttpStreamParser* parser,
bool using_proxy)
- : read_buf_(new GrowableIOBuffer()),
- parser_(parser),
- connection_(connection),
- using_proxy_(using_proxy),
- request_info_(NULL) {
-}
+ : state_(connection, using_proxy) {}
HttpBasicStream::~HttpBasicStream() {}
-int HttpBasicStream::InitializeStream(
- const HttpRequestInfo* request_info,
- RequestPriority priority,
- const BoundNetLog& net_log,
- const CompletionCallback& callback) {
- DCHECK(!parser_.get());
- request_info_ = request_info;
- parser_.reset(new HttpStreamParser(
- connection_.get(), request_info, read_buf_.get(), net_log));
+int HttpBasicStream::InitializeStream(const HttpRequestInfo* request_info,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback) {
+ state_.Initialize(request_info, priority, net_log, callback);
return OK;
}
-
int HttpBasicStream::SendRequest(const HttpRequestHeaders& headers,
HttpResponseInfo* response,
const CompletionCallback& callback) {
- DCHECK(parser_.get());
- DCHECK(request_info_);
- const std::string path = using_proxy_ ?
- HttpUtil::SpecForRequest(request_info_->url) :
- HttpUtil::PathForRequest(request_info_->url);
- request_line_ = base::StringPrintf("%s %s HTTP/1.1\r\n",
- request_info_->method.c_str(),
- path.c_str());
- return parser_->SendRequest(request_line_, headers, response, callback);
+ DCHECK(parser());
+ return parser()->SendRequest(
+ state_.GenerateRequestLine(), headers, response, callback);
}
UploadProgress HttpBasicStream::GetUploadProgress() const {
- return parser_->GetUploadProgress();
+ return parser()->GetUploadProgress();
}
int HttpBasicStream::ReadResponseHeaders(const CompletionCallback& callback) {
- return parser_->ReadResponseHeaders(callback);
+ return parser()->ReadResponseHeaders(callback);
}
const HttpResponseInfo* HttpBasicStream::GetResponseInfo() const {
- return parser_->GetResponseInfo();
+ return parser()->GetResponseInfo();
}
-int HttpBasicStream::ReadResponseBody(IOBuffer* buf, int buf_len,
+int HttpBasicStream::ReadResponseBody(IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) {
- return parser_->ReadResponseBody(buf, buf_len, callback);
+ return parser()->ReadResponseBody(buf, buf_len, callback);
}
void HttpBasicStream::Close(bool not_reusable) {
- parser_->Close(not_reusable);
+ parser()->Close(not_reusable);
}
HttpStream* HttpBasicStream::RenewStreamForAuth() {
DCHECK(IsResponseBodyComplete());
- DCHECK(!parser_->IsMoreDataBuffered());
- parser_.reset();
- return new HttpBasicStream(connection_.release(), NULL, using_proxy_);
+ DCHECK(!parser()->IsMoreDataBuffered());
+ // The HttpStreamParser object still has a pointer to the connection. Just to
+ // be extra-sure it doesn't touch the connection again, delete it here rather
+ // than leaving it until the destructor is called.
+ state_.DeleteParser();
+ return new HttpBasicStream(state_.ReleaseConnection().release(),
+ state_.using_proxy());
}
bool HttpBasicStream::IsResponseBodyComplete() const {
- return parser_->IsResponseBodyComplete();
+ return parser()->IsResponseBodyComplete();
}
bool HttpBasicStream::CanFindEndOfResponse() const {
- return parser_->CanFindEndOfResponse();
+ return parser()->CanFindEndOfResponse();
}
bool HttpBasicStream::IsConnectionReused() const {
- return parser_->IsConnectionReused();
+ return parser()->IsConnectionReused();
}
-void HttpBasicStream::SetConnectionReused() {
- parser_->SetConnectionReused();
-}
+void HttpBasicStream::SetConnectionReused() { parser()->SetConnectionReused(); }
bool HttpBasicStream::IsConnectionReusable() const {
- return parser_->IsConnectionReusable();
+ return parser()->IsConnectionReusable();
+}
+
+int64 HttpBasicStream::GetTotalReceivedBytes() const {
+ return parser()->received_bytes();
}
bool HttpBasicStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
- return connection_->GetLoadTimingInfo(IsConnectionReused(), load_timing_info);
+ return state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
+ load_timing_info);
}
void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) {
- parser_->GetSSLInfo(ssl_info);
+ parser()->GetSSLInfo(ssl_info);
}
void HttpBasicStream::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
- parser_->GetSSLCertRequestInfo(cert_request_info);
+ parser()->GetSSLCertRequestInfo(cert_request_info);
}
-bool HttpBasicStream::IsSpdyHttpStream() const {
- return false;
-}
+bool HttpBasicStream::IsSpdyHttpStream() const { return false; }
void HttpBasicStream::Drain(HttpNetworkSession* session) {
HttpResponseBodyDrainer* drainer = new HttpResponseBodyDrainer(this);
diff --git a/chromium/net/http/http_basic_stream.h b/chromium/net/http/http_basic_stream.h
index 2057837e9a9..4a67ccaac00 100644
--- a/chromium/net/http/http_basic_stream.h
+++ b/chromium/net/http/http_basic_stream.h
@@ -12,13 +12,13 @@
#include <string>
#include "base/basictypes.h"
+#include "net/http/http_basic_state.h"
#include "net/http/http_stream.h"
namespace net {
class BoundNetLog;
class ClientSocketHandle;
-class GrowableIOBuffer;
class HttpResponseInfo;
struct HttpRequestInfo;
class HttpRequestHeaders;
@@ -27,13 +27,9 @@ class IOBuffer;
class HttpBasicStream : public HttpStream {
public:
- // Constructs a new HttpBasicStream. If |parser| is NULL, then
- // InitializeStream should be called to initialize it correctly. If
- // |parser| is non-null, then InitializeStream should not be called,
- // as the stream is already initialized.
- HttpBasicStream(ClientSocketHandle* connection,
- HttpStreamParser* parser,
- bool using_proxy);
+ // Constructs a new HttpBasicStream. InitializeStream must be called to
+ // initialize it correctly.
+ HttpBasicStream(ClientSocketHandle* connection, bool using_proxy);
virtual ~HttpBasicStream();
// HttpStream methods:
@@ -52,7 +48,8 @@ class HttpBasicStream : public HttpStream {
virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE;
- virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
+ virtual int ReadResponseBody(IOBuffer* buf,
+ int buf_len,
const CompletionCallback& callback) OVERRIDE;
virtual void Close(bool not_reusable) OVERRIDE;
@@ -69,6 +66,8 @@ class HttpBasicStream : public HttpStream {
virtual bool IsConnectionReusable() const OVERRIDE;
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE;
+
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
@@ -84,17 +83,9 @@ class HttpBasicStream : public HttpStream {
virtual void SetPriority(RequestPriority priority) OVERRIDE;
private:
- scoped_refptr<GrowableIOBuffer> read_buf_;
-
- scoped_ptr<HttpStreamParser> parser_;
-
- scoped_ptr<ClientSocketHandle> connection_;
-
- bool using_proxy_;
-
- std::string request_line_;
+ HttpStreamParser* parser() const { return state_.parser(); }
- const HttpRequestInfo* request_info_;
+ HttpBasicState state_;
DISALLOW_COPY_AND_ASSIGN(HttpBasicStream);
};
diff --git a/chromium/net/http/http_byte_range.cc b/chromium/net/http/http_byte_range.cc
index 60683c5584f..b43cb2e8008 100644
--- a/chromium/net/http/http_byte_range.cc
+++ b/chromium/net/http/http_byte_range.cc
@@ -4,6 +4,9 @@
#include <algorithm>
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "net/http/http_byte_range.h"
namespace {
@@ -21,6 +24,29 @@ HttpByteRange::HttpByteRange()
has_computed_bounds_(false) {
}
+// static
+HttpByteRange HttpByteRange::Bounded(int64 first_byte_position,
+ int64 last_byte_position) {
+ HttpByteRange range;
+ range.set_first_byte_position(first_byte_position);
+ range.set_last_byte_position(last_byte_position);
+ return range;
+}
+
+// static
+HttpByteRange HttpByteRange::RightUnbounded(int64 first_byte_position) {
+ HttpByteRange range;
+ range.set_first_byte_position(first_byte_position);
+ return range;
+}
+
+// static
+HttpByteRange HttpByteRange::Suffix(int64 suffix_length) {
+ HttpByteRange range;
+ range.set_suffix_length(suffix_length);
+ return range;
+}
+
bool HttpByteRange::IsSuffixByteRange() const {
return suffix_length_ != kPositionNotSpecified;
}
@@ -41,6 +67,21 @@ bool HttpByteRange::IsValid() const {
last_byte_position_ >= first_byte_position_));
}
+std::string HttpByteRange::GetHeaderValue() const {
+ DCHECK(IsValid());
+
+ if (IsSuffixByteRange())
+ return base::StringPrintf("bytes=-%" PRId64, suffix_length());
+
+ DCHECK(HasFirstBytePosition());
+
+ if (!HasLastBytePosition())
+ return base::StringPrintf("bytes=%" PRId64 "-", first_byte_position());
+
+ return base::StringPrintf("bytes=%" PRId64 "-%" PRId64,
+ first_byte_position(), last_byte_position());
+}
+
bool HttpByteRange::ComputeBounds(int64 size) {
if (size < 0)
return false;
diff --git a/chromium/net/http/http_byte_range.h b/chromium/net/http/http_byte_range.h
index 2c06434439d..98708721a4f 100644
--- a/chromium/net/http/http_byte_range.h
+++ b/chromium/net/http/http_byte_range.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_BYTE_RANGE_H_
#define NET_HTTP_HTTP_BYTE_RANGE_H_
+#include <string>
+
#include "base/basictypes.h"
#include "net/base/net_export.h"
@@ -17,10 +19,16 @@ class NET_EXPORT HttpByteRange {
public:
HttpByteRange();
+ // Convenience constructors.
+ static HttpByteRange Bounded(int64 first_byte_position,
+ int64 last_byte_position);
+ static HttpByteRange RightUnbounded(int64 first_byte_position);
+ static HttpByteRange Suffix(int64 suffix_length);
+
// Since this class is POD, we use constructor, assignment operator
// and destructor provided by compiler.
int64 first_byte_position() const { return first_byte_position_; }
- void set_first_byte_position(int64 value) { first_byte_position_ = value; }
+ void set_first_byte_position(int64 value) { first_byte_position_ = value; }
int64 last_byte_position() const { return last_byte_position_; }
void set_last_byte_position(int64 value) { last_byte_position_ = value; }
@@ -38,6 +46,10 @@ class NET_EXPORT HttpByteRange {
// Returns true if this range is valid.
bool IsValid() const;
+ // Gets the header string, e.g. "bytes=0-100", "bytes=100-", "bytes=-100".
+ // Assumes range is valid.
+ std::string GetHeaderValue() const;
+
// A method that when given the size in bytes of a file, adjust the internal
// |first_byte_position_| and |last_byte_position_| values according to the
// range specified by this object. If the range specified is invalid with
diff --git a/chromium/net/http/http_byte_range_unittest.cc b/chromium/net/http/http_byte_range_unittest.cc
index 6629a7c3c59..5dc6e5237f3 100644
--- a/chromium/net/http/http_byte_range_unittest.cc
+++ b/chromium/net/http/http_byte_range_unittest.cc
@@ -76,3 +76,17 @@ TEST(HttpByteRangeTest, SetInstanceSize) {
}
}
}
+
+TEST(HttpByteRangeTest, GetHeaderValue) {
+ static const struct {
+ net::HttpByteRange range;
+ const char* expected;
+ } tests[] = {{net::HttpByteRange::Bounded(0, 0), "bytes=0-0"},
+ {net::HttpByteRange::Bounded(0, 100), "bytes=0-100"},
+ {net::HttpByteRange::Bounded(0, -1), "bytes=0-"},
+ {net::HttpByteRange::RightUnbounded(100), "bytes=100-"},
+ {net::HttpByteRange::Suffix(100), "bytes=-100"}, };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ EXPECT_EQ(tests[i].expected, tests[i].range.GetHeaderValue());
+ }
+}
diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc
index 83efcb135cd..88fb53a69c4 100644
--- a/chromium/net/http/http_cache_transaction.cc
+++ b/chromium/net/http/http_cache_transaction.cc
@@ -101,6 +101,23 @@ void RecordOfflineStatus(int load_flags, RequestOfflineStatus status) {
}
}
+// TODO(rvargas): Remove once we get the data.
+void RecordVaryHeaderHistogram(const net::HttpResponseInfo* response) {
+ enum VaryType {
+ VARY_NOT_PRESENT,
+ VARY_UA,
+ VARY_OTHER,
+ VARY_MAX
+ };
+ VaryType vary = VARY_NOT_PRESENT;
+ if (response->vary_data.is_valid()) {
+ vary = VARY_OTHER;
+ if (response->headers->HasHeaderValue("vary", "user-agent"))
+ vary = VARY_UA;
+ }
+ UMA_HISTOGRAM_ENUMERATION("HttpCache.Vary", vary, VARY_MAX);
+}
+
} // namespace
namespace net {
@@ -196,7 +213,8 @@ HttpCache::Transaction::Transaction(
io_callback_(base::Bind(&Transaction::OnIOComplete,
weak_factory_.GetWeakPtr())),
transaction_pattern_(PATTERN_UNDEFINED),
- transaction_delegate_(transaction_delegate) {
+ transaction_delegate_(transaction_delegate),
+ websocket_handshake_stream_base_create_helper_(NULL) {
COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders ==
arraysize(kValidationHeaders),
Invalid_number_of_validation_headers);
@@ -516,6 +534,13 @@ void HttpCache::Transaction::SetPriority(RequestPriority priority) {
network_trans_->SetPriority(priority_);
}
+void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper(
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
+ websocket_handshake_stream_base_create_helper_ = create_helper;
+ if (network_trans_)
+ network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper);
+}
+
//-----------------------------------------------------------------------------
void HttpCache::Transaction::DoCallback(int rv) {
@@ -843,6 +868,10 @@ int HttpCache::Transaction::DoSendRequest() {
// Old load timing information, if any, is now obsolete.
old_network_trans_load_timing_.reset();
+ if (websocket_handshake_stream_base_create_helper_)
+ network_trans_->SetWebSocketHandshakeStreamCreateHelper(
+ websocket_handshake_stream_base_create_helper_);
+
ReportNetworkActionStart();
next_state_ = STATE_SEND_REQUEST_COMPLETE;
rv = network_trans_->Start(request_, io_callback_, net_log_);
@@ -963,6 +992,8 @@ int HttpCache::Transaction::DoSuccessfulSendRequest() {
cache_->DoomMainEntryForUrl(request_->url);
}
+ RecordVaryHeaderHistogram(new_response);
+
// Are we expecting a response to a conditional query?
if (mode_ == READ_WRITE || mode_ == UPDATE) {
if (new_response->headers->response_code() == 304 || handling_206_) {
@@ -1499,20 +1530,12 @@ int HttpCache::Transaction::DoCacheQueryData() {
}
int HttpCache::Transaction::DoCacheQueryDataComplete(int result) {
-#if defined(OS_ANDROID)
if (result == ERR_NOT_IMPLEMENTED) {
// Restart the request overwriting the cache entry.
- //
- // Note: this would have fixed range requests for debug builds on all OSes,
- // not just Android, but karen@ prefers to limit the effect based on OS for
- // cherry-picked fixes.
- // TODO(pasko): remove the OS_ANDROID limitation as soon as the fix proves
- // useful after the cherry-pick.
// TODO(pasko): remove this workaround as soon as the SimpleBackendImpl
// supports Sparse IO.
return DoRestartPartialRequest();
}
-#endif
DCHECK_EQ(OK, result);
if (!cache_.get())
return ERR_UNEXPECTED;
@@ -2388,6 +2411,8 @@ bool HttpCache::Transaction::CanResume(bool has_data) {
if (request_->method != "GET")
return false;
+ // Note that if this is a 206, content-length was already fixed after calling
+ // PartialData::ResponseHeadersOK().
if (response_.headers->GetContentLength() <= 0 ||
response_.headers->HasHeaderValue("Accept-Ranges", "none") ||
!response_.headers->HasStrongValidators()) {
diff --git a/chromium/net/http/http_cache_transaction.h b/chromium/net/http/http_cache_transaction.h
index b1f32bd820d..90c4db5a39c 100644
--- a/chromium/net/http/http_cache_transaction.h
+++ b/chromium/net/http/http_cache_transaction.h
@@ -130,6 +130,8 @@ class HttpCache::Transaction : public HttpTransaction {
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
virtual void SetPriority(RequestPriority priority) OVERRIDE;
+ virtual void SetWebSocketHandshakeStreamCreateHelper(
+ net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE;
private:
static const size_t kNumValidationHeaders = 2;
@@ -433,6 +435,15 @@ class HttpCache::Transaction : public HttpTransaction {
// 304 and 206 response cases, as the network transaction may be destroyed
// before the caller requests load timing information.
scoped_ptr<LoadTimingInfo> old_network_trans_load_timing_;
+
+ // The helper object to use to create WebSocketHandshakeStreamBase
+ // objects. Only relevant when establishing a WebSocket connection.
+ // This is passed to the underlying network transaction. It is stored here in
+ // case the transaction does not exist yet.
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_base_create_helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(Transaction);
};
} // namespace net
diff --git a/chromium/net/http/http_cache_unittest.cc b/chromium/net/http/http_cache_unittest.cc
index e47852c01ac..aa6056a4177 100644
--- a/chromium/net/http/http_cache_unittest.cc
+++ b/chromium/net/http/http_cache_unittest.cc
@@ -31,7 +31,9 @@
#include "net/http/http_transaction_unittest.h"
#include "net/http/http_util.h"
#include "net/http/mock_http_cache.h"
+#include "net/socket/client_socket_handle.h"
#include "net/ssl/ssl_cert_request_info.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
@@ -574,6 +576,21 @@ struct Context {
scoped_ptr<net::HttpTransaction> trans;
};
+class FakeWebSocketHandshakeStreamCreateHelper
+ : public net::WebSocketHandshakeStreamBase::CreateHelper {
+ public:
+ virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
+ virtual net::WebSocketHandshakeStreamBase* CreateBasicStream(
+ scoped_ptr<net::ClientSocketHandle> connect, bool using_proxy) OVERRIDE {
+ return NULL;
+ }
+ virtual net::WebSocketHandshakeStreamBase* CreateSpdyStream(
+ const base::WeakPtr<net::SpdySession>& session,
+ bool use_relative_url) OVERRIDE {
+ return NULL;
+ }
+};
+
} // namespace
@@ -2785,7 +2802,7 @@ TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -2816,7 +2833,7 @@ TEST(HttpCache, SimplePOST_WithRanges) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, kUploadId);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -2835,7 +2852,7 @@ TEST(HttpCache, SimplePOST_SeparateCache) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 1);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
MockTransaction transaction(kSimplePOST_Transaction);
MockHttpRequest req1(transaction);
@@ -2874,7 +2891,7 @@ TEST(HttpCache, SimplePOST_Invalidate_205) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 1);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
transaction.method = "POST";
transaction.status = "HTTP/1.1 205 No Content";
@@ -2913,7 +2930,7 @@ TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
transaction.method = "POST";
transaction.status = "HTTP/1.1 205 No Content";
@@ -2944,7 +2961,7 @@ TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
MockTransaction transaction(kSimplePOST_Transaction);
AddMockTransaction(&transaction);
@@ -2973,7 +2990,7 @@ TEST(HttpCache, SimplePOST_DontInvalidate_100) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 1);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
transaction.method = "POST";
transaction.status = "HTTP/1.1 100 Continue";
@@ -3003,7 +3020,7 @@ TEST(HttpCache, SimplePUT_Miss) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -3032,7 +3049,7 @@ TEST(HttpCache, SimplePUT_Invalidate) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
transaction.method = "PUT";
MockHttpRequest req2(transaction);
@@ -3068,7 +3085,7 @@ TEST(HttpCache, SimplePUT_Invalidate_305) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
transaction.method = "PUT";
transaction.status = "HTTP/1.1 305 Use Proxy";
@@ -3106,7 +3123,7 @@ TEST(HttpCache, SimplePUT_DontInvalidate_404) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
transaction.method = "PUT";
transaction.status = "HTTP/1.1 404 Not Found";
@@ -3136,7 +3153,7 @@ TEST(HttpCache, SimpleDELETE_Miss) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
MockHttpRequest request(transaction);
request.upload_data_stream = &upload_data_stream;
@@ -3165,7 +3182,7 @@ TEST(HttpCache, SimpleDELETE_Invalidate) {
ScopedVector<net::UploadElementReader> element_readers;
element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
- net::UploadDataStream upload_data_stream(&element_readers, 0);
+ net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
transaction.method = "DELETE";
MockHttpRequest req2(transaction);
@@ -3395,6 +3412,37 @@ TEST(HttpCache, RangeGET_NoStrongValidators) {
RemoveMockTransaction(&transaction);
}
+// Tests that we cache partial responses that lack content-length.
+TEST(HttpCache, RangeGET_NoContentLength) {
+ MockHttpCache cache;
+ std::string headers;
+
+ // Attempt to write to the cache (40-49).
+ MockTransaction transaction(kRangeGET_TransactionOK);
+ AddMockTransaction(&transaction);
+ transaction.response_headers = "ETag: \"foo\"\n"
+ "Accept-Ranges: bytes\n"
+ "Content-Range: bytes 40-49/80\n";
+ transaction.handler = NULL;
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ // Now verify that there's no cached data.
+ transaction.handler = &RangeTransactionServer::RangeHandler;
+ RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
+ &headers);
+
+ Verify206Response(headers, 40, 49);
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ RemoveMockTransaction(&transaction);
+}
+
// Tests that we can cache range requests and fetch random blocks from the
// cache and the network.
TEST(HttpCache, RangeGET_OK) {
@@ -3455,8 +3503,6 @@ TEST(HttpCache, RangeGET_OK) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
-#if defined(OS_ANDROID)
-
// Checks that with a cache backend having Sparse IO unimplementes the cache
// entry would be doomed after a range request.
// TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
@@ -3529,8 +3575,6 @@ TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
RemoveMockTransaction(&transaction);
}
-#endif // OS_ANDROID
-
// Tests that we can cache range requests and fetch random blocks from the
// cache and the network, with synchronous responses.
TEST(HttpCache, RangeGET_SyncOK) {
@@ -6271,6 +6315,35 @@ TEST(HttpCache, SetPriority) {
EXPECT_EQ(net::OK, callback.WaitForResult());
}
+// Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
+// transaction passes on its argument to the underlying network transaction.
+TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
+ MockHttpCache cache;
+
+ FakeWebSocketHandshakeStreamCreateHelper create_helper;
+ scoped_ptr<net::HttpTransaction> trans;
+ EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(
+ net::IDLE, &trans, NULL));
+ ASSERT_TRUE(trans.get());
+
+ EXPECT_FALSE(cache.network_layer()->last_transaction());
+
+ net::HttpRequestInfo info;
+ info.url = GURL(kSimpleGET_Transaction.url);
+ net::TestCompletionCallback callback;
+ EXPECT_EQ(net::ERR_IO_PENDING,
+ trans->Start(&info, callback.callback(), net::BoundNetLog()));
+
+ ASSERT_TRUE(cache.network_layer()->last_transaction());
+ EXPECT_FALSE(cache.network_layer()->last_transaction()->
+ websocket_handshake_stream_create_helper());
+ trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
+ EXPECT_EQ(&create_helper,
+ cache.network_layer()->last_transaction()->
+ websocket_handshake_stream_create_helper());
+ EXPECT_EQ(net::OK, callback.WaitForResult());
+}
+
// Make sure that a cache transaction passes on its priority to
// newly-created network transactions.
TEST(HttpCache, SetPriorityNewTransaction) {
diff --git a/chromium/net/http/http_chunked_decoder.cc b/chromium/net/http/http_chunked_decoder.cc
index ca07f24de06..0d8be9f7cd2 100644
--- a/chromium/net/http/http_chunked_decoder.cc
+++ b/chromium/net/http/http_chunked_decoder.cc
@@ -44,6 +44,8 @@
#include "net/http/http_chunked_decoder.h"
+#include <algorithm>
+
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
diff --git a/chromium/net/http/http_network_layer.cc b/chromium/net/http/http_network_layer.cc
index e4d082eb0fd..7d3f1588006 100644
--- a/chromium/net/http/http_network_layer.cc
+++ b/chromium/net/http/http_network_layer.cc
@@ -5,6 +5,7 @@
#include "net/http/http_network_layer.h"
#include "base/logging.h"
+#include "base/power_monitor/power_monitor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -23,9 +24,19 @@ HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session)
: session_(session),
suspended_(false) {
DCHECK(session_.get());
+#if defined(OS_WIN)
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->AddObserver(this);
+#endif
}
HttpNetworkLayer::~HttpNetworkLayer() {
+#if defined(OS_WIN)
+ base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
+ if (power_monitor)
+ power_monitor->RemoveObserver(this);
+#endif
}
//-----------------------------------------------------------------------------
@@ -42,7 +53,7 @@ HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
void HttpNetworkLayer::ForceAlternateProtocol() {
PortAlternateProtocolPair pair;
pair.port = 443;
- pair.protocol = NPN_SPDY_2;
+ pair.protocol = NPN_SPDY_3;
HttpServerPropertiesImpl::ForceAlternateProtocol(pair);
}
diff --git a/chromium/net/http/http_network_layer.h b/chromium/net/http/http_network_layer.h
index 4b41b7190e8..c4c41aec43e 100644
--- a/chromium/net/http/http_network_layer.h
+++ b/chromium/net/http/http_network_layer.h
@@ -7,6 +7,8 @@
#include <string>
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/power_monitor/power_observer.h"
@@ -36,7 +38,7 @@ class NET_EXPORT HttpNetworkLayer
// when network session is shared.
static HttpTransactionFactory* CreateFactory(HttpNetworkSession* session);
- // Forces an alternate protocol of SPDY/2 on port 443.
+ // Forces an alternate protocol of SPDY/3 on port 443.
// TODO(rch): eliminate this method.
static void ForceAlternateProtocol();
@@ -54,6 +56,8 @@ class NET_EXPORT HttpNetworkLayer
private:
const scoped_refptr<HttpNetworkSession> session_;
bool suspended_;
+
+ DISALLOW_COPY_AND_ASSIGN(HttpNetworkLayer);
};
} // namespace net
diff --git a/chromium/net/http/http_network_layer_unittest.cc b/chromium/net/http/http_network_layer_unittest.cc
index 6d2ea358071..98b8d4eaf44 100644
--- a/chromium/net/http/http_network_layer_unittest.cc
+++ b/chromium/net/http/http_network_layer_unittest.cc
@@ -4,6 +4,7 @@
#include "net/http/http_network_layer.h"
+#include "base/basictypes.h"
#include "base/strings/stringprintf.h"
#include "net/base/net_log.h"
#include "net/cert/mock_cert_verifier.h"
@@ -48,14 +49,27 @@ class HttpNetworkLayerTest : public PlatformTest {
factory_.reset(new HttpNetworkLayer(network_session_.get()));
}
- void ExecuteRequestExpectingContentAndHeader(const std::string& content,
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ std::string GetChromeProxy() {
+ return HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString();
+ }
+#endif
+
+#if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(DATA_REDUCTION_FALLBACK_HOST)
+ std::string GetChromeFallbackProxy() {
+ return HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
+ }
+#endif
+
+ void ExecuteRequestExpectingContentAndHeader(const std::string& method,
+ const std::string& content,
const std::string& header,
const std::string& value) {
TestCompletionCallback callback;
HttpRequestInfo request_info;
request_info.url = GURL("http://www.google.com/");
- request_info.method = "GET";
+ request_info.method = method;
request_info.load_flags = LOAD_NORMAL;
scoped_ptr<HttpTransaction> trans;
@@ -80,68 +94,105 @@ class HttpNetworkLayerTest : public PlatformTest {
}
// Check that |proxy_count| proxies are in the retry list.
- // These will be, in order, "bad:8080" and "alsobad:8080".
- void TestBadProxies(unsigned int proxy_count) {
+ // These will be, in order, |bad_proxy| and |bad_proxy2|".
+ void TestBadProxies(unsigned int proxy_count, const std::string& bad_proxy,
+ const std::string& bad_proxy2) {
const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info();
ASSERT_EQ(proxy_count, retry_info.size());
- ASSERT_TRUE(retry_info.find("bad:8080") != retry_info.end());
+ if (proxy_count > 0)
+ ASSERT_TRUE(retry_info.find(bad_proxy) != retry_info.end());
if (proxy_count > 1)
- ASSERT_TRUE(retry_info.find("alsobad:8080") != retry_info.end());
+ ASSERT_TRUE(retry_info.find(bad_proxy2) != retry_info.end());
}
// Simulates a request through a proxy which returns a bypass, which is then
// retried through a second proxy that doesn't bypass.
// Checks that the expected requests were issued, the expected content was
- // recieved, and the first proxy ("bad:8080") was marked as bad.
- void TestProxyFallback() {
+ // recieved, and the first proxy |bad_proxy| was marked as bad.
+ void TestProxyFallback(const std::string& bad_proxy) {
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"
- "Connection: proxy-bypass\r\n\r\n"),
+ "Chrome-Proxy: bypass=0\r\n\r\n"),
MockRead("Bypass message"),
MockRead(SYNCHRONOUS, OK),
};
+ TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
+ arraysize(data_reads), 1u);
+ }
+
+ void TestProxyFallbackWithMockReads(const std::string& bad_proxy,
+ const std::string& bad_proxy2,
+ MockRead data_reads[],
+ int data_reads_size,
+ unsigned int expected_retry_info_size) {
+ TestProxyFallbackByMethodWithMockReads(bad_proxy, bad_proxy2, data_reads,
+ data_reads_size, "GET", "content",
+ true, expected_retry_info_size);
+ }
+
+ void TestProxyFallbackByMethodWithMockReads(
+ const std::string& bad_proxy,
+ const std::string& bad_proxy2,
+ MockRead data_reads[],
+ int data_reads_size,
+ std::string method,
+ std::string content,
+ bool retry_expected,
+ unsigned int expected_retry_info_size) {
+ std::string trailer =
+ (method == "HEAD" || method == "PUT" || method == "POST") ?
+ "Content-Length: 0\r\n\r\n" : "\r\n";
+ std::string request =
+ base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "%s", method.c_str(), trailer.c_str());
+
MockWrite data_writes[] = {
- MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(request.c_str()),
};
- StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
+ StaticSocketDataProvider data1(data_reads, data_reads_size,
data_writes, arraysize(data_writes));
mock_socket_factory_.AddSocketDataProvider(&data1);
// Second data provider returns the expected content.
- MockRead data_reads2[] = {
- MockRead("HTTP/1.0 200 OK\r\n"
- "Server: not-proxy\r\n\r\n"),
- MockRead("content"),
- MockRead(SYNCHRONOUS, OK),
- };
+ MockRead data_reads2[3];
+ size_t data_reads2_index = 0;
+ data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n"
+ "Server: not-proxy\r\n\r\n");
+ if (!content.empty())
+ data_reads2[data_reads2_index++] = MockRead(content.c_str());
+ data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK);
+
MockWrite data_writes2[] = {
- MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(request.c_str()),
};
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ StaticSocketDataProvider data2(data_reads2, data_reads2_index,
data_writes2, arraysize(data_writes2));
mock_socket_factory_.AddSocketDataProvider(&data2);
// Expect that we get "content" and not "Bypass message", and that there's
// a "not-proxy" "Server:" header in the final response.
- ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy");
+ if (retry_expected) {
+ ExecuteRequestExpectingContentAndHeader(method, content,
+ "server", "not-proxy");
+ } else {
+ ExecuteRequestExpectingContentAndHeader(method, content, "", "");
+ }
// We should also observe the bad proxy in the retry list.
- TestBadProxies(1u);
+ TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2);
}
// Simulates a request through a proxy which returns a bypass, which is then
// retried through a direct connection to the origin site.
// Checks that the expected requests were issued, the expected content was
- // received, and the proxy ("bad:8080") was marked as bad.
- void TestProxyFallbackToDirect() {
+ // received, and the proxy |bad_proxy| was marked as bad.
+ void TestProxyFallbackToDirect(const std::string& bad_proxy) {
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"
- "Connection: proxy-bypass\r\n\r\n"),
+ "Chrome-Proxy: bypass=0\r\n\r\n"),
MockRead("Bypass message"),
MockRead(SYNCHRONOUS, OK),
};
@@ -172,10 +223,11 @@ class HttpNetworkLayerTest : public PlatformTest {
// Expect that we get "content" and not "Bypass message", and that there's
// a "not-proxy" "Server:" header in the final response.
- ExecuteRequestExpectingContentAndHeader("content", "server", "not-proxy");
+ ExecuteRequestExpectingContentAndHeader("GET", "content",
+ "server", "not-proxy");
// We should also observe the bad proxy in the retry list.
- TestBadProxies(1u);
+ TestBadProxies(1u, bad_proxy, "");
}
// Simulates a request through a proxy which returns a bypass, under a
@@ -183,10 +235,12 @@ class HttpNetworkLayerTest : public PlatformTest {
// are expected to be configured.
// Checks that the expected requests were issued, the bypass message was the
// final received content, and all proxies were marked as bad.
- void TestProxyFallbackFail(unsigned int proxy_count) {
+ void TestProxyFallbackFail(unsigned int proxy_count,
+ const std::string& bad_proxy,
+ const std::string& bad_proxy2) {
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"
- "Connection: proxy-bypass\r\n\r\n"),
+ "Chrome-Proxy: bypass=0\r\n\r\n"),
MockRead("Bypass message"),
MockRead(SYNCHRONOUS, OK),
};
@@ -205,10 +259,10 @@ class HttpNetworkLayerTest : public PlatformTest {
mock_socket_factory_.AddSocketDataProvider(&data2);
// Expect that we get "Bypass message", and not "content"..
- ExecuteRequestExpectingContentAndHeader("Bypass message", "", "");
+ ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", "");
// We should also observe the bad proxy or proxies in the retry list.
- TestBadProxies(proxy_count);
+ TestBadProxies(proxy_count, bad_proxy, bad_proxy2);
}
MockClientSocketFactory mock_socket_factory_;
@@ -289,7 +343,7 @@ TEST_F(HttpNetworkLayerTest, GET) {
}
// Proxy bypass tests. These tests run through various server-induced
-// proxy-bypass scenarios using both PAC file and fixed proxy params.
+// proxy bypass scenarios using both PAC file and fixed proxy params.
// The test scenarios are:
// - bypass with two proxies configured and the first but not the second
// is bypassed.
@@ -299,55 +353,133 @@ TEST_F(HttpNetworkLayerTest, GET) {
// - bypass with one proxy configured which is bypassed with no defined
// fallback
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassPac) {
+ std::string bad_proxy = GetChromeProxy();
ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
- "PROXY bad:8080; PROXY good:8080"));
- TestProxyFallback();
+ "PROXY " + bad_proxy + "; PROXY good:8080"));
+ TestProxyFallback(bad_proxy);
}
TEST_F(HttpNetworkLayerTest, ServerTwoProxyBypassFixed) {
- ConfigureTestDependencies(ProxyService::CreateFixed("bad:8080, good:8080"));
- TestProxyFallback();
+ std::string bad_proxy = GetChromeProxy();
+ ConfigureTestDependencies(
+ ProxyService::CreateFixed(bad_proxy +", good:8080"));
+ TestProxyFallback(bad_proxy);
+}
+
+TEST_F(HttpNetworkLayerTest, BypassAndRetryIdempotentMethods) {
+ std::string bad_proxy = GetChromeProxy();
+ const struct {
+ std::string method;
+ std::string content;
+ bool expected_to_retry;
+ } tests[] = {
+ {
+ "GET",
+ "content",
+ true,
+ },
+ {
+ "OPTIONS",
+ "content",
+ true,
+ },
+ {
+ "HEAD",
+ "",
+ true,
+ },
+ {
+ "PUT",
+ "",
+ true,
+ },
+ {
+ "DELETE",
+ "content",
+ true,
+ },
+ {
+ "TRACE",
+ "content",
+ true,
+ },
+ {
+ "POST",
+ "Bypass message",
+ false,
+ },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ ConfigureTestDependencies(
+ ProxyService::CreateFixed(bad_proxy +", good:8080"));
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Chrome-Proxy: bypass=0\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ TestProxyFallbackByMethodWithMockReads(bad_proxy, "", data_reads,
+ arraysize(data_reads),
+ tests[i].method,
+ tests[i].content,
+ tests[i].expected_to_retry, 1u);
+ }
}
TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassPac) {
+ std::string bad_proxy = GetChromeProxy();
ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
- "PROXY bad:8080; DIRECT"));
- TestProxyFallbackToDirect();
+ "PROXY " + bad_proxy + "; DIRECT"));
+ TestProxyFallbackToDirect(bad_proxy);
}
TEST_F(HttpNetworkLayerTest, ServerOneProxyWithDirectBypassFixed) {
- ConfigureTestDependencies(ProxyService::CreateFixed( "bad:8080, direct://"));
- TestProxyFallbackToDirect();
+ std::string bad_proxy = GetChromeProxy();
+ ConfigureTestDependencies(
+ ProxyService::CreateFixed(bad_proxy + ", direct://"));
+ TestProxyFallbackToDirect(bad_proxy);
}
+#if defined(DATA_REDUCTION_FALLBACK_HOST)
TEST_F(HttpNetworkLayerTest, ServerTwoProxyDoubleBypassPac) {
+ std::string bad_proxy = GetChromeProxy();
+ std::string bad_proxy2 =
+ HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
- "PROXY bad:8080; PROXY alsobad:8080"));
- TestProxyFallbackFail(2u);
+ "PROXY " + bad_proxy + "; PROXY " + bad_proxy2));
+ TestProxyFallbackFail(2u, bad_proxy, bad_proxy2);
}
TEST_F(HttpNetworkLayerTest, ServerTwoProxyDoubleBypassFixed) {
+ std::string bad_proxy = GetChromeProxy();
+ std::string bad_proxy2 =
+ HostPortPair::FromURL(GURL(DATA_REDUCTION_FALLBACK_HOST)).ToString();
ConfigureTestDependencies(ProxyService::CreateFixed(
- "bad:8080, alsobad:8080"));
- TestProxyFallbackFail(2u);
+ bad_proxy + ", " + bad_proxy2));
+ TestProxyFallbackFail(2u, bad_proxy, bad_proxy2);
}
+#endif
TEST_F(HttpNetworkLayerTest, ServerOneProxyNoDirectBypassPac) {
+ std::string bad_proxy = GetChromeProxy();
ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
- "PROXY bad:8080"));
- TestProxyFallbackFail(1u);
+ "PROXY " + bad_proxy));
+ TestProxyFallbackFail(1u, bad_proxy, "");
}
TEST_F(HttpNetworkLayerTest, ServerOneProxyNoDirectBypassFixed) {
- ConfigureTestDependencies(ProxyService::CreateFixed("bad:8080"));
- TestProxyFallbackFail(1u);
+ std::string bad_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixed(bad_proxy));
+ TestProxyFallbackFail(1u, bad_proxy, "");
}
-#if defined(SPDY_PROXY_AUTH_ORIGIN)
-TEST_F(HttpNetworkLayerTest, ServerFallbackOnInternalServerError) {
- // Verify that "500 Internal Server Error" via the data reduction proxy
- // induces proxy fallback to a second proxy, if configured.
+TEST_F(HttpNetworkLayerTest, ServerFallbackOn5xxError) {
+ // Verify that "500 Internal Server Error", "502 Bad Gateway", and
+ // "503 Service Unavailable" via the data reduction proxy induce proxy
+ // fallback to a second proxy, if configured.
// To configure this test, we need to wire up a custom proxy service to use
// a pair of proxies. We'll induce fallback via the first and return
@@ -356,79 +488,92 @@ TEST_F(HttpNetworkLayerTest, ServerFallbackOnInternalServerError) {
HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)).ToString());
std::string pac_string = base::StringPrintf(
"PROXY %s; PROXY good:8080", data_reduction_proxy.data());
- ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(pac_string));
- MockRead data_reads[] = {
- MockRead("HTTP/1.1 500 Internal Server Error\r\n\r\n"),
- MockRead("Bypass message"),
- MockRead(SYNCHRONOUS, OK),
- };
- MockWrite data_writes[] = {
- MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
+ std::string headers[] = {
+ "HTTP/1.1 500 Internal Server Error\r\n\r\n",
+ "HTTP/1.1 502 Bad Gateway\r\n\r\n",
+ "HTTP/1.1 503 Service Unavailable\r\n\r\n"
};
- StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
- data_writes, arraysize(data_writes));
- mock_socket_factory_.AddSocketDataProvider(&data1);
- // Second data provider returns the expected content.
- MockRead data_reads2[] = {
- MockRead("HTTP/1.0 200 OK\r\n"
- "Server: not-proxy\r\n\r\n"),
- MockRead("content"),
- MockRead(SYNCHRONOUS, OK),
- };
- MockWrite data_writes2[] = {
- MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n\r\n"),
- };
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
- data_writes2, arraysize(data_writes2));
- mock_socket_factory_.AddSocketDataProvider(&data2);
+ for (size_t i = 0; i < arraysize(headers); ++i) {
+ ConfigureTestDependencies(
+ ProxyService::CreateFixedFromPacResult(pac_string));
- TestCompletionCallback callback;
+ MockRead data_reads[] = {
+ MockRead(headers[i].c_str()),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
- HttpRequestInfo request_info;
- request_info.url = GURL("http://www.google.com/");
- request_info.method = "GET";
- request_info.load_flags = LOAD_NORMAL;
+ MockWrite data_writes[] = {
+ MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
- scoped_ptr<HttpTransaction> trans;
- int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL);
- EXPECT_EQ(OK, rv);
+ StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
+ data_writes, arraysize(data_writes));
+ mock_socket_factory_.AddSocketDataProvider(&data1);
- rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
- if (rv == ERR_IO_PENDING)
- rv = callback.WaitForResult();
- ASSERT_EQ(OK, rv);
+ // Second data provider returns the expected content.
+ MockRead data_reads2[] = {
+ MockRead("HTTP/1.0 200 OK\r\n"
+ "Server: not-proxy\r\n\r\n"),
+ MockRead("content"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+ MockWrite data_writes2[] = {
+ MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ };
- std::string contents;
- rv = ReadTransaction(trans.get(), &contents);
- EXPECT_EQ(OK, rv);
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ mock_socket_factory_.AddSocketDataProvider(&data2);
+
+ TestCompletionCallback callback;
+
+ HttpRequestInfo request_info;
+ request_info.url = GURL("http://www.google.com/");
+ request_info.method = "GET";
+ request_info.load_flags = LOAD_NORMAL;
+
+ scoped_ptr<HttpTransaction> trans;
+ int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans, NULL);
+ EXPECT_EQ(OK, rv);
+
+ rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
+ if (rv == ERR_IO_PENDING)
+ rv = callback.WaitForResult();
+ ASSERT_EQ(OK, rv);
- // We should obtain content from the second socket provider write
- // corresponding to the fallback proxy.
- EXPECT_EQ("content", contents);
- // We also have a server header here that isn't set by the proxy.
- EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue(
- "server", "not-proxy"));
- // We should also observe the data reduction proxy in the retry list.
- ASSERT_TRUE(1u == proxy_service_->proxy_retry_info().size());
- EXPECT_EQ(data_reduction_proxy,
- (*proxy_service_->proxy_retry_info().begin()).first);
+ std::string contents;
+ rv = ReadTransaction(trans.get(), &contents);
+ EXPECT_EQ(OK, rv);
+
+ // We should obtain content from the second socket provider write
+ // corresponding to the fallback proxy.
+ EXPECT_EQ("content", contents);
+ // We also have a server header here that isn't set by the proxy.
+ EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue(
+ "server", "not-proxy"));
+ // We should also observe the data reduction proxy in the retry list.
+ ASSERT_EQ(1u, proxy_service_->proxy_retry_info().size());
+ EXPECT_EQ(data_reduction_proxy,
+ (*proxy_service_->proxy_retry_info().begin()).first);
+ }
}
#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
TEST_F(HttpNetworkLayerTest, ProxyBypassIgnoredOnDirectConnectionPac) {
- // Verify that a Connection: proxy-bypass header is ignored when returned
- // from a directly connected origin server.
+ // Verify that a Chrome-Proxy header is ignored when returned from a directly
+ // connected origin server.
ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult("DIRECT"));
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"
- "Connection: proxy-bypass\r\n\r\n"),
+ "Chrome-Proxy: bypass=0\r\n\r\n"),
MockRead("Bypass message"),
MockRead(SYNCHRONOUS, OK),
};
@@ -466,6 +611,132 @@ TEST_F(HttpNetworkLayerTest, ProxyBypassIgnoredOnDirectConnectionPac) {
ASSERT_EQ(0u, proxy_service_->proxy_retry_info().size());
}
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+TEST_F(HttpNetworkLayerTest, ServerFallbackWithProxyTimedBypass) {
+ // Verify that a Chrome-Proxy: bypass=<seconds> header induces proxy
+ // fallback to a second proxy, if configured.
+ std::string bad_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + bad_proxy + "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Chrome-Proxy: bypass=86400\r\n"
+ "Via: 1.1 Chrome Compression Proxy\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
+ arraysize(data_reads), 1u);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(86400),
+ (*proxy_service_->proxy_retry_info().begin()).second.current_delay);
+}
+
+TEST_F(HttpNetworkLayerTest, ServerFallbackWithWrongViaHeader) {
+ // Verify that a Via header that lacks the Chrome-Proxy induces proxy fallback
+ // to a second proxy, if configured.
+ std::string chrome_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + chrome_proxy + "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Via: 1.0 some-other-proxy\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackWithMockReads(chrome_proxy, std::string(), data_reads,
+ arraysize(data_reads), 1u);
+}
+
+TEST_F(HttpNetworkLayerTest, ServerFallbackWithNoViaHeader) {
+ // Verify that the lack of a Via header induces proxy fallback to a second
+ // proxy, if configured.
+ std::string chrome_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + chrome_proxy + "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackWithMockReads(chrome_proxy, std::string(), data_reads,
+ arraysize(data_reads), 1u);
+}
+
+TEST_F(HttpNetworkLayerTest, NoServerFallbackWith304Response) {
+ // Verify that Chrome will not be induced to bypass the Chrome proxy when
+ // the Chrome Proxy via header is absent on a 304.
+ std::string chrome_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + chrome_proxy + "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 304 Not Modified\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackByMethodWithMockReads(chrome_proxy, std::string(),
+ data_reads, arraysize(data_reads),
+ "GET", std::string(), false, 0);
+}
+
+TEST_F(HttpNetworkLayerTest, NoServerFallbackWithChainedViaHeader) {
+ // Verify that Chrome will not be induced to bypass the Chrome proxy when
+ // the Chrome Proxy via header is present, even if that header is chained.
+ std::string chrome_proxy = GetChromeProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + chrome_proxy + "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Via: 1.1 Chrome Compression Proxy, 1.0 some-other-proxy\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackByMethodWithMockReads(chrome_proxy, std::string(),
+ data_reads, arraysize(data_reads),
+ "GET", "Bypass message", false, 0);
+}
+
+#if defined(DATA_REDUCTION_FALLBACK_HOST)
+TEST_F(HttpNetworkLayerTest, ServerFallbackWithProxyTimedBypassAll) {
+ // Verify that a Chrome-Proxy: block=<seconds> header bypasses a
+ // a configured Chrome-Proxy and fallback and induces proxy fallback to a
+ // third proxy, if configured.
+ std::string bad_proxy = GetChromeProxy();
+ std::string fallback_proxy = GetChromeFallbackProxy();
+ ConfigureTestDependencies(ProxyService::CreateFixedFromPacResult(
+ "PROXY " + bad_proxy + "; PROXY " + fallback_proxy +
+ "; PROXY good:8080"));
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Connection: keep-alive\r\n"
+ "Chrome-Proxy: block=86400\r\n"
+ "Via: 1.1 Chrome Compression Proxy\r\n\r\n"),
+ MockRead("Bypass message"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ TestProxyFallbackWithMockReads(bad_proxy, fallback_proxy, data_reads,
+ arraysize(data_reads), 2u);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(86400),
+ (*proxy_service_->proxy_retry_info().begin()).second.current_delay);
+}
+#endif // defined(DATA_REDUCTION_FALLBACK_HOST)
+#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
+
TEST_F(HttpNetworkLayerTest, NetworkVerified) {
MockRead data_reads[] = {
MockRead("HTTP/1.0 200 OK\r\n\r\n"),
diff --git a/chromium/net/http/http_network_session.cc b/chromium/net/http/http_network_session.cc
index 346cbbc8941..1be93fe5c3f 100644
--- a/chromium/net/http/http_network_session.cc
+++ b/chromium/net/http/http_network_session.cc
@@ -42,6 +42,7 @@ net::ClientSocketPoolManager* CreateSocketPoolManager(
params.cert_verifier,
params.server_bound_cert_service,
params.transport_security_state,
+ params.cert_transparency_verifier,
params.ssl_session_cache_shard,
params.proxy_service,
params.ssl_config_service,
@@ -58,6 +59,7 @@ HttpNetworkSession::Params::Params()
cert_verifier(NULL),
server_bound_cert_service(NULL),
transport_security_state(NULL),
+ cert_transparency_verifier(NULL),
proxy_service(NULL),
ssl_config_service(NULL),
http_auth_handler_factory(NULL),
@@ -71,7 +73,6 @@ HttpNetworkSession::Params::Params()
testing_fixed_https_port(0),
force_spdy_single_domain(false),
enable_spdy_ip_pooling(true),
- enable_spdy_credential_frames(false),
enable_spdy_compression(true),
enable_spdy_ping_based_connection_checking(true),
spdy_default_protocol(kProtoUnknown),
@@ -83,6 +84,7 @@ HttpNetworkSession::Params::Params()
enable_quic_https(false),
quic_clock(NULL),
quic_random(NULL),
+ quic_max_packet_length(kDefaultMaxPacketSize),
enable_user_alternate_protocol_ports(false),
quic_crypto_client_stream_factory(NULL) {
}
@@ -112,13 +114,13 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.quic_random ? params.quic_random :
QuicRandom::GetInstance(),
params.quic_clock ? params. quic_clock :
- new QuicClock()),
+ new QuicClock(),
+ params.quic_max_packet_length),
spdy_session_pool_(params.host_resolver,
params.ssl_config_service,
params.http_server_properties,
params.force_spdy_single_domain,
params.enable_spdy_ip_pooling,
- params.enable_spdy_credential_frames,
params.enable_spdy_compression,
params.enable_spdy_ping_based_connection_checking,
params.spdy_default_protocol,
@@ -128,7 +130,8 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.time_func,
params.trusted_spdy_proxy),
http_stream_factory_(new HttpStreamFactoryImpl(this, false)),
- websocket_stream_factory_(new HttpStreamFactoryImpl(this, true)),
+ http_stream_factory_for_websocket_(
+ new HttpStreamFactoryImpl(this, true)),
params_(params) {
DCHECK(proxy_service_);
DCHECK(ssl_config_service_.get());
diff --git a/chromium/net/http/http_network_session.h b/chromium/net/http/http_network_session.h
index c10bb1446f4..471041220ec 100644
--- a/chromium/net/http/http_network_session.h
+++ b/chromium/net/http/http_network_session.h
@@ -62,6 +62,7 @@ class NET_EXPORT HttpNetworkSession
CertVerifier* cert_verifier;
ServerBoundCertService* server_bound_cert_service;
TransportSecurityState* transport_security_state;
+ CTVerifier* cert_transparency_verifier;
ProxyService* proxy_service;
std::string ssl_session_cache_shard;
SSLConfigService* ssl_config_service;
@@ -77,7 +78,6 @@ class NET_EXPORT HttpNetworkSession
uint16 testing_fixed_https_port;
bool force_spdy_single_domain;
bool enable_spdy_ip_pooling;
- bool enable_spdy_credential_frames;
bool enable_spdy_compression;
bool enable_spdy_ping_based_connection_checking;
NextProto spdy_default_protocol;
@@ -91,6 +91,7 @@ class NET_EXPORT HttpNetworkSession
HostPortPair origin_to_force_quic_on;
QuicClock* quic_clock; // Will be owned by QuicStreamFactory.
QuicRandom* quic_random;
+ size_t quic_max_packet_length;
bool enable_user_alternate_protocol_ports;
QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory;
};
@@ -141,8 +142,8 @@ class NET_EXPORT HttpNetworkSession
HttpStreamFactory* http_stream_factory() {
return http_stream_factory_.get();
}
- HttpStreamFactory* websocket_stream_factory() {
- return websocket_stream_factory_.get();
+ HttpStreamFactory* http_stream_factory_for_websocket() {
+ return http_stream_factory_for_websocket_.get();
}
NetLog* net_log() {
return net_log_;
@@ -198,7 +199,7 @@ class NET_EXPORT HttpNetworkSession
QuicStreamFactory quic_stream_factory_;
SpdySessionPool spdy_session_pool_;
scoped_ptr<HttpStreamFactory> http_stream_factory_;
- scoped_ptr<HttpStreamFactory> websocket_stream_factory_;
+ scoped_ptr<HttpStreamFactory> http_stream_factory_for_websocket_;
std::set<HttpResponseBodyDrainer*> response_drainers_;
Params params_;
diff --git a/chromium/net/http/http_network_session_peer.cc b/chromium/net/http/http_network_session_peer.cc
index 74b0d415310..a32e48b9ebb 100644
--- a/chromium/net/http/http_network_session_peer.cc
+++ b/chromium/net/http/http_network_session_peer.cc
@@ -21,8 +21,8 @@ HttpNetworkSessionPeer::HttpNetworkSessionPeer(
HttpNetworkSessionPeer::~HttpNetworkSessionPeer() {}
void HttpNetworkSessionPeer::SetClientSocketPoolManager(
- ClientSocketPoolManager* socket_pool_manager) {
- session_->normal_socket_pool_manager_.reset(socket_pool_manager);
+ scoped_ptr<ClientSocketPoolManager> socket_pool_manager) {
+ session_->normal_socket_pool_manager_.swap(socket_pool_manager);
}
void HttpNetworkSessionPeer::SetProxyService(ProxyService* proxy_service) {
@@ -30,13 +30,13 @@ void HttpNetworkSessionPeer::SetProxyService(ProxyService* proxy_service) {
}
void HttpNetworkSessionPeer::SetHttpStreamFactory(
- HttpStreamFactory* http_stream_factory) {
- session_->http_stream_factory_.reset(http_stream_factory);
+ scoped_ptr<HttpStreamFactory> http_stream_factory) {
+ session_->http_stream_factory_.swap(http_stream_factory);
}
-void HttpNetworkSessionPeer::SetWebSocketStreamFactory(
- HttpStreamFactory* http_stream_factory) {
- session_->websocket_stream_factory_.reset(http_stream_factory);
+void HttpNetworkSessionPeer::SetHttpStreamFactoryForWebSocket(
+ scoped_ptr<HttpStreamFactory> http_stream_factory) {
+ session_->http_stream_factory_for_websocket_.swap(http_stream_factory);
}
} // namespace net
diff --git a/chromium/net/http/http_network_session_peer.h b/chromium/net/http/http_network_session_peer.h
index eeccfefafd4..755e539cebb 100644
--- a/chromium/net/http/http_network_session_peer.h
+++ b/chromium/net/http/http_network_session_peer.h
@@ -6,6 +6,7 @@
#define NET_HTTP_HTTP_NETWORK_SESSION_PEER_H_
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/net_export.h"
namespace net {
@@ -22,12 +23,13 @@ class NET_EXPORT_PRIVATE HttpNetworkSessionPeer {
~HttpNetworkSessionPeer();
void SetClientSocketPoolManager(
- ClientSocketPoolManager* socket_pool_manager);
+ scoped_ptr<ClientSocketPoolManager> socket_pool_manager);
void SetProxyService(ProxyService* proxy_service);
- void SetHttpStreamFactory(HttpStreamFactory* http_stream_factory);
- void SetWebSocketStreamFactory(HttpStreamFactory* websocket_stream_factory);
+ void SetHttpStreamFactory(scoped_ptr<HttpStreamFactory> http_stream_factory);
+ void SetHttpStreamFactoryForWebSocket(
+ scoped_ptr<HttpStreamFactory> http_stream_factory_for_websocket);
private:
const scoped_refptr<HttpNetworkSession> session_;
diff --git a/chromium/net/http/http_network_transaction.cc b/chromium/net/http/http_network_transaction.cc
index ff158a84e77..d7b3f41ff76 100644
--- a/chromium/net/http/http_network_transaction.cc
+++ b/chromium/net/http/http_network_transaction.cc
@@ -19,6 +19,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "net/base/auth.h"
@@ -60,7 +61,14 @@
#include "net/ssl/ssl_connection_status_flags.h"
#include "url/gurl.h"
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+#include <algorithm>
+#include "net/proxy/proxy_server.h"
+#endif
+
+
using base::Time;
+using base::TimeDelta;
namespace net {
@@ -111,6 +119,30 @@ base::Value* NetLogSSLVersionFallbackCallback(
return dict;
}
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+// Returns true if |response_headers| contains the data reduction proxy Via
+// header value.
+bool IsChromeProxyResponse(const net::HttpResponseHeaders* response_headers) {
+ if (!response_headers) {
+ return false;
+ }
+ const char kDataReductionProxyViaValue[] = "1.1 Chrome Compression Proxy";
+ size_t value_len = strlen(kDataReductionProxyViaValue);
+ void* iter = NULL;
+ std::string temp;
+ while (response_headers->EnumerateHeader(&iter, "Via", &temp)) {
+ std::string::const_iterator it =
+ std::search(temp.begin(), temp.end(),
+ kDataReductionProxyViaValue,
+ kDataReductionProxyViaValue + value_len,
+ base::CaseInsensitiveCompareASCII<char>());
+ if (it != temp.end())
+ return true;
+ }
+ return false;
+}
+#endif
+
} // namespace
//-----------------------------------------------------------------------------
@@ -125,10 +157,12 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority,
priority_(priority),
headers_valid_(false),
logged_response_time_(false),
+ fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK),
request_headers_(),
read_buf_len_(0),
next_state_(STATE_NONE),
- establishing_tunnel_(false) {
+ establishing_tunnel_(false),
+ websocket_handshake_stream_base_create_helper_(NULL) {
session->ssl_config_service()->GetSSLConfig(&server_ssl_config_);
if (session->http_stream_factory()->has_next_protos()) {
server_ssl_config_.next_protos =
@@ -159,10 +193,13 @@ HttpNetworkTransaction::~HttpNetworkTransaction() {
} else {
// Otherwise, we try to drain the response body.
HttpStreamBase* stream = stream_.release();
- stream->Drain(session_.get());
+ stream->Drain(session_);
}
}
}
+
+ if (request_ && request_->upload_data_stream)
+ request_->upload_data_stream->Reset(); // Invalidate pending callbacks.
}
int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
@@ -425,6 +462,11 @@ void HttpNetworkTransaction::SetPriority(RequestPriority priority) {
stream_->SetPriority(priority);
}
+void HttpNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
+ websocket_handshake_stream_base_create_helper_ = create_helper;
+}
+
void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStreamBase* stream) {
@@ -443,11 +485,11 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
OnIOComplete(OK);
}
-void HttpNetworkTransaction::OnWebSocketStreamReady(
+void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) {
- NOTREACHED() << "This function should never be called.";
+ WebSocketHandshakeStreamBase* stream) {
+ OnStreamReady(used_ssl_config, used_proxy_info, stream);
}
void HttpNetworkTransaction::OnStreamFailed(int result,
@@ -653,14 +695,27 @@ int HttpNetworkTransaction::DoLoop(int result) {
int HttpNetworkTransaction::DoCreateStream() {
next_state_ = STATE_CREATE_STREAM_COMPLETE;
- stream_request_.reset(
- session_->http_stream_factory()->RequestStream(
- *request_,
- priority_,
- server_ssl_config_,
- proxy_ssl_config_,
- this,
- net_log_));
+ if (ForWebSocketHandshake()) {
+ stream_request_.reset(
+ session_->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(
+ *request_,
+ priority_,
+ server_ssl_config_,
+ proxy_ssl_config_,
+ this,
+ websocket_handshake_stream_base_create_helper_,
+ net_log_));
+ } else {
+ stream_request_.reset(
+ session_->http_stream_factory()->RequestStream(
+ *request_,
+ priority_,
+ server_ssl_config_,
+ proxy_ssl_config_,
+ this,
+ net_log_));
+ }
DCHECK(stream_request_.get());
return ERR_IO_PENDING;
}
@@ -894,6 +949,11 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
return result;
}
+ if (result == ERR_QUIC_HANDSHAKE_FAILED) {
+ ResetConnectionAndRequestForResend();
+ return OK;
+ }
+
if (result < 0 && result != ERR_CONNECTION_CLOSED)
return HandleIOError(result);
@@ -917,33 +977,85 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
}
DCHECK(response_.headers.get());
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
// Server-induced fallback; see: http://crbug.com/143712
if (response_.was_fetched_via_proxy && response_.headers.get() != NULL) {
- bool should_fallback =
- response_.headers->HasHeaderValue("connection", "proxy-bypass");
- // Additionally, fallback if a 500 is returned via the data reduction proxy.
- // This is conservative, as the 500 might have been generated by the origin,
- // and not the proxy.
-#if defined(SPDY_PROXY_AUTH_ORIGIN)
- if (!should_fallback) {
- should_fallback =
- response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR &&
- proxy_info_.proxy_server().host_port_pair().Equals(
- HostPortPair::FromURL(GURL(SPDY_PROXY_AUTH_ORIGIN)));
+ ProxyService::DataReductionProxyBypassEventType proxy_bypass_event =
+ ProxyService::BYPASS_EVENT_TYPE_MAX;
+ net::HttpResponseHeaders::ChromeProxyInfo chrome_proxy_info;
+ bool chrome_proxy_used =
+ proxy_info_.proxy_server().isDataReductionProxy();
+ bool chrome_fallback_proxy_used = false;
+#if defined(DATA_REDUCTION_FALLBACK_HOST)
+ if (!chrome_proxy_used) {
+ chrome_fallback_proxy_used =
+ proxy_info_.proxy_server().isDataReductionProxyFallback();
}
#endif
- if (should_fallback) {
- ProxyService* proxy_service = session_->proxy_service();
- if (proxy_service->MarkProxyAsBad(proxy_info_, net_log_)) {
- // Only retry in the case of GETs. We don't want to resubmit a POST
- // if the proxy took some action.
- if (request_->method == "GET") {
- ResetConnectionAndRequestForResend();
- return OK;
+
+ if (chrome_proxy_used || chrome_fallback_proxy_used) {
+ // A Via header might not be present in a 304. Since the goal of a 304
+ // response is to minimize information transfer, a sender in general
+ // should not generate representation metadata other than Cache-Control,
+ // Content-Location, Date, ETag, Expires, and Vary.
+ if (!IsChromeProxyResponse(response_.headers.get()) &&
+ (response_.headers->response_code() != HTTP_NOT_MODIFIED)) {
+ proxy_bypass_event = ProxyService::MISSING_VIA_HEADER;
+ } else if (response_.headers->GetChromeProxyInfo(&chrome_proxy_info)) {
+ if (chrome_proxy_info.bypass_duration < TimeDelta::FromMinutes(30))
+ proxy_bypass_event = ProxyService::SHORT_BYPASS;
+ else
+ proxy_bypass_event = ProxyService::LONG_BYPASS;
+ } else {
+ // Additionally, fallback if a 500, 502 or 503 is returned via the data
+ // reduction proxy. This is conservative, as the 500, 502 or 503 might
+ // have been generated by the origin, and not the proxy.
+ if (response_.headers->response_code() == HTTP_INTERNAL_SERVER_ERROR ||
+ response_.headers->response_code() == HTTP_BAD_GATEWAY ||
+ response_.headers->response_code() == HTTP_SERVICE_UNAVAILABLE) {
+ proxy_bypass_event = ProxyService::INTERNAL_SERVER_ERROR_BYPASS;
+ }
+ }
+
+ if (proxy_bypass_event < ProxyService::BYPASS_EVENT_TYPE_MAX) {
+ ProxyService* proxy_service = session_->proxy_service();
+
+ proxy_service->RecordDataReductionProxyBypassInfo(
+ chrome_proxy_used, proxy_info_.proxy_server(), proxy_bypass_event);
+
+ ProxyServer proxy_server;
+#if defined(DATA_REDUCTION_FALLBACK_HOST)
+ if (chrome_proxy_used && chrome_proxy_info.bypass_all) {
+ // TODO(bengr): Rename as DATA_REDUCTION_FALLBACK_ORIGIN.
+ GURL proxy_url(DATA_REDUCTION_FALLBACK_HOST);
+ if (proxy_url.SchemeIsHTTPOrHTTPS()) {
+ proxy_server = ProxyServer(proxy_url.SchemeIs("http") ?
+ ProxyServer::SCHEME_HTTP :
+ ProxyServer::SCHEME_HTTPS,
+ HostPortPair::FromURL(proxy_url));
+ }
+ }
+#endif
+ if (proxy_service->MarkProxiesAsBad(proxy_info_,
+ chrome_proxy_info.bypass_duration,
+ proxy_server,
+ net_log_)) {
+ // Only retry idempotent methods. We don't want to resubmit a POST
+ // if the proxy took some action.
+ if (request_->method == "GET" ||
+ request_->method == "OPTIONS" ||
+ request_->method == "HEAD" ||
+ request_->method == "PUT" ||
+ request_->method == "DELETE" ||
+ request_->method == "TRACE") {
+ ResetConnectionAndRequestForResend();
+ return OK;
+ }
}
}
}
}
+#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
// Like Net.HttpResponseCode, but only for MAIN_FRAME loads.
if (request_->load_flags & LOAD_MAIN_FRAME) {
@@ -969,7 +1081,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
// need to skip over it.
// We treat any other 1xx in this same way (although in practice getting
// a 1xx that isn't a 100 is rare).
- if (response_.headers->response_code() / 100 == 1) {
+ // Unless this is a WebSocket request, in which case we pass it on up.
+ if (response_.headers->response_code() / 100 == 1 &&
+ !ForWebSocketHandshake()) {
response_.headers = new HttpResponseHeaders(std::string());
next_state_ = STATE_READ_HEADERS;
return OK;
@@ -1210,17 +1324,21 @@ int HttpNetworkTransaction::HandleCertificateRequest(int error) {
return OK;
}
+void HttpNetworkTransaction::HandleClientAuthError(int error) {
+ if (server_ssl_config_.send_client_cert &&
+ (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) {
+ session_->ssl_client_auth_cache()->Remove(
+ GetHostAndPort(request_->url));
+ }
+}
+
// TODO(rch): This does not correctly handle errors when an SSL proxy is
// being used, as all of the errors are handled as if they were generated
// by the endpoint host, request_->url, rather than considering if they were
// generated by the SSL proxy. http://crbug.com/69329
int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
DCHECK(request_);
- if (server_ssl_config_.send_client_cert &&
- (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) {
- session_->ssl_client_auth_cache()->Remove(
- GetHostAndPort(request_->url));
- }
+ HandleClientAuthError(error);
bool should_fallback = false;
uint16 version_max = server_ssl_config_.version_max;
@@ -1246,16 +1364,7 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
// While SSL 3.0 fallback should be eliminated because of security
// reasons, there is a high risk of breaking the servers if this is
// done in general.
- // For now SSL 3.0 fallback is disabled for Google servers first,
- // and will be expanded to other servers after enough experiences
- // have been gained showing that this experiment works well with
- // today's Internet.
- if (version_max > SSL_PROTOCOL_VERSION_SSL3 ||
- (server_ssl_config_.unrestricted_ssl3_fallback_enabled ||
- !TransportSecurityState::IsGooglePinnedProperty(
- request_->url.host(), true /* include SNI */))) {
- should_fallback = true;
- }
+ should_fallback = true;
}
break;
case ERR_SSL_BAD_RECORD_MAC_ALERT:
@@ -1269,6 +1378,13 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
should_fallback = true;
}
break;
+ case ERR_SSL_INAPPROPRIATE_FALLBACK:
+ // The server told us that we should not have fallen back. A buggy server
+ // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial
+ // connection. |fallback_error_code_| is initialised to
+ // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case.
+ error = fallback_error_code_;
+ break;
}
if (should_fallback) {
@@ -1277,6 +1393,7 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
base::Bind(&NetLogSSLVersionFallbackCallback,
&request_->url, error, server_ssl_config_.version_max,
version_max));
+ fallback_error_code_ = error;
server_ssl_config_.version_max = version_max;
server_ssl_config_.version_fallback = true;
ResetConnectionAndRequestForResend();
@@ -1291,13 +1408,9 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
// write errors or response header read errors. It should not be used in
// other cases, such as a Connect error.
int HttpNetworkTransaction::HandleIOError(int error) {
- // SSL errors may happen at any time during the stream and indicate issues
- // with the underlying connection. Because the peer may request
- // renegotiation at any time, check and handle any possible SSL handshake
- // related errors. In addition to renegotiation, TLS False Start may cause
- // SSL handshake errors (specifically servers with buggy DEFLATE support)
- // to be delayed until the first Read on the underlying connection.
- error = HandleSSLHandshakeError(error);
+ // Because the peer may request renegotiation with client authentication at
+ // any time, check and handle client authentication errors.
+ HandleClientAuthError(error);
switch (error) {
// If we try to reuse a connection that the server is in the process of
@@ -1332,6 +1445,7 @@ int HttpNetworkTransaction::HandleIOError(int error) {
break;
case ERR_SPDY_PING_FAILED:
case ERR_SPDY_SERVER_REFUSED_STREAM:
+ case ERR_QUIC_HANDSHAKE_FAILED:
net_log_.AddEventWithNetErrorCode(
NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error);
ResetConnectionAndRequestForResend();
@@ -1453,6 +1567,11 @@ GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const {
}
}
+bool HttpNetworkTransaction::ForWebSocketHandshake() const {
+ return websocket_handshake_stream_base_create_helper_ &&
+ request_->url.SchemeIsWSOrWSS();
+}
+
#define STATE_CASE(s) \
case s: \
description = base::StringPrintf("%s (0x%08X)", #s, s); \
diff --git a/chromium/net/http/http_network_transaction.h b/chromium/net/http/http_network_transaction.h
index 6228487e615..3ae1725d1de 100644
--- a/chromium/net/http/http_network_transaction.h
+++ b/chromium/net/http/http_network_transaction.h
@@ -21,6 +21,7 @@
#include "net/http/http_transaction.h"
#include "net/proxy/proxy_service.h"
#include "net/ssl/ssl_config_service.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
namespace net {
@@ -68,15 +69,17 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
virtual void SetPriority(RequestPriority priority) OVERRIDE;
+ virtual void SetWebSocketHandshakeStreamCreateHelper(
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE;
// HttpStreamRequest::Delegate methods:
virtual void OnStreamReady(const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStreamBase* stream) OVERRIDE;
- virtual void OnWebSocketStreamReady(
+ virtual void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) OVERRIDE;
+ WebSocketHandshakeStreamBase* stream) OVERRIDE;
virtual void OnStreamFailed(int status,
const SSLConfig& used_ssl_config) OVERRIDE;
virtual void OnCertificateError(int status,
@@ -184,6 +187,9 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// Called to handle a client certificate request.
int HandleCertificateRequest(int error);
+ // Called to possibly handle a client authentication error.
+ void HandleClientAuthError(int error);
+
// Called to possibly recover from an SSL handshake error. Sets next_state_
// and returns OK if recovering from the error. Otherwise, the same error
// code is returned.
@@ -242,6 +248,9 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// Get the {scheme, host, path, port} for the authentication target
GURL AuthURL(HttpAuth::Target target) const;
+ // Returns true if this transaction is for a WebSocket handshake
+ bool ForWebSocketHandshake() const;
+
// Debug helper.
static std::string DescribeState(State state);
@@ -256,7 +265,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
CompletionCallback io_callback_;
CompletionCallback callback_;
- scoped_refptr<HttpNetworkSession> session_;
+ HttpNetworkSession* session_;
BoundNetLog net_log_;
const HttpRequestInfo* request_;
@@ -279,6 +288,12 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
SSLConfig server_ssl_config_;
SSLConfig proxy_ssl_config_;
+ // fallback_error_code contains the error code that caused the last TLS
+ // fallback. If the fallback connection results in
+ // ERR_SSL_INAPPROPRIATE_FALLBACK (i.e. the server indicated that the
+ // fallback should not have been needed) then we use this value to return the
+ // original error that triggered the fallback.
+ int fallback_error_code_;
HttpRequestHeaders request_headers_;
@@ -306,6 +321,11 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction
// read from the socket until the tunnel is done.
bool establishing_tunnel_;
+ // The helper object to use to create WebSocketHandshakeStreamBase
+ // objects. Only relevant when establishing a WebSocket connection.
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_base_create_helper_;
+
DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction);
};
diff --git a/chromium/net/http/http_network_transaction_ssl_unittest.cc b/chromium/net/http/http_network_transaction_ssl_unittest.cc
index bb218498961..ab7eadf8928 100644
--- a/chromium/net/http/http_network_transaction_ssl_unittest.cc
+++ b/chromium/net/http/http_network_transaction_ssl_unittest.cc
@@ -103,148 +103,6 @@ class HttpNetworkTransactionSSLTest : public testing::Test {
ScopedVector<HttpRequestInfo> request_info_vector_;
};
-// Tests that HttpNetworkTransaction does not attempt to
-// fallback to SSL 3.0 when a TLS 1.0 handshake fails and:
-// * the site is pinned to the Google pin list (indicating that
-// it is a Google site);
-// * unrestricted SSL 3.0 fallback is disabled.
-TEST_F(HttpNetworkTransactionSSLTest, SSL3FallbackDisabled_Google) {
- // |ssl_data1| is for the first handshake (TLS 1.0), which will fail for
- // protocol reasons (e.g., simulating a version rollback attack).
- // Because unrestricted SSL 3.0 fallback is disabled, only this simulated
- // SSL handshake is consumed.
- SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data1);
- StaticSocketDataProvider data1(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data1);
-
- // This extra handshake, which should be unconsumed, is provided to ensure
- // that even if the behaviour being tested here ever breaks (and Google
- // properties begin SSL 3.0 fallbacks), this test will not crash (and bring
- // down all of net_unittests), but it will fail gracefully.
- SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
- StaticSocketDataProvider data2(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data2);
-
- scoped_refptr<HttpNetworkSession> session(
- new HttpNetworkSession(session_params_));
- scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
-
- SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
- ssl_config.unrestricted_ssl3_fallback_enabled = false;
-
- TestCompletionCallback callback;
- // This will consume only |ssl_data1|. |ssl_data2| will not be consumed.
- int rv = callback.GetResult(
- trans->Start(GetRequestInfo("https://www.google.com/"),
- callback.callback(), BoundNetLog()));
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
-
- SocketDataProviderArray<SocketDataProvider>& mock_data =
- mock_socket_factory_.mock_data();
- // Confirms that only |ssl_data1| is consumed.
- EXPECT_EQ(1u, mock_data.next_index());
-
- // |version_max| never fallbacks to SSLv3 for Google properties.
- EXPECT_EQ(SSL_PROTOCOL_VERSION_TLS1, ssl_config.version_max);
- EXPECT_FALSE(ssl_config.version_fallback);
-}
-
-// Tests that HttpNetworkTransaction attempts to fallback to SSL 3.0
-// when a TLS 1.0 handshake fails and:
-// * the site is pinned to the Google pin list (indicating that
-// it is a Google site);
-// * unrestricted SSL 3.0 fallback is enabled.
-TEST_F(HttpNetworkTransactionSSLTest, SSL3FallbackEnabled_Google) {
- // |ssl_data1| is for the first handshake (TLS 1.0), which will fail
- // for protocol reasons (e.g., simulating a version rollback attack).
- SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data1);
- StaticSocketDataProvider data1(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data1);
-
- // |ssl_data2| contains the handshake result for a SSL 3.0
- // handshake which will be attempted after the TLS 1.0
- // handshake fails.
- SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
- StaticSocketDataProvider data2(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data2);
-
- scoped_refptr<HttpNetworkSession> session(
- new HttpNetworkSession(session_params_));
- scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
-
- SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
- ssl_config.unrestricted_ssl3_fallback_enabled = true;
-
- TestCompletionCallback callback;
- // This will consume |ssl_data1| and |ssl_data2|.
- int rv = callback.GetResult(
- trans->Start(GetRequestInfo("https://www.google.com/"),
- callback.callback(), BoundNetLog()));
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
-
- SocketDataProviderArray<SocketDataProvider>& mock_data =
- mock_socket_factory_.mock_data();
- // Confirms that both |ssl_data1| and |ssl_data2| are consumed.
- EXPECT_EQ(2u, mock_data.next_index());
-
- // |version_max| fallbacks to SSL 3.0 for Google properties when
- // |unrestricted_ssl3_fallback_enabled| is true.
- EXPECT_EQ(SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_max);
- EXPECT_TRUE(ssl_config.version_fallback);
-}
-
-// Tests that HttpNetworkTransaction attempts to fallback to SSL 3.0
-// when a TLS 1.0 handshake fails and the site is not a Google domain,
-// even if unrestricted SSL 3.0 fallback is disabled.
-// TODO(thaidn): revise the above comment and this test when the
-// SSL 3.0 fallback experiment is applied for non-Google domains.
-TEST_F(HttpNetworkTransactionSSLTest, SSL3FallbackDisabled_Paypal) {
- // |ssl_data1| is for the first handshake (TLS 1.0), which will fail
- // for protocol reasons (e.g., simulating a version rollback attack).
- SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data1);
- StaticSocketDataProvider data1(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data1);
-
- // |ssl_data2| contains the handshake result for a SSL 3.0
- // handshake which will be attempted after the TLS 1.0
- // handshake fails.
- SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
- StaticSocketDataProvider data2(NULL, 0, NULL, 0);
- mock_socket_factory_.AddSocketDataProvider(&data2);
-
- scoped_refptr<HttpNetworkSession> session(
- new HttpNetworkSession(session_params_));
- scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
-
- SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
- ssl_config.unrestricted_ssl3_fallback_enabled = false;
-
- TestCompletionCallback callback;
- // This will consume |ssl_data1| and |ssl_data2|.
- int rv = callback.GetResult(
- trans->Start(GetRequestInfo("https://www.paypal.com/"),
- callback.callback(), BoundNetLog()));
- EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
-
- SocketDataProviderArray<SocketDataProvider>& mock_data =
- mock_socket_factory_.mock_data();
- // Confirms that both |ssl_data1| and |ssl_data2| are consumed.
- EXPECT_EQ(2u, mock_data.next_index());
-
- // |version_max| fallbacks to SSL 3.0.
- EXPECT_EQ(SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_max);
- EXPECT_TRUE(ssl_config.version_fallback);
-}
-
// Tests that HttpNetworkTransaction attempts to fallback from
// TLS 1.1 to TLS 1.0, then from TLS 1.0 to SSL 3.0.
TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) {
@@ -278,9 +136,6 @@ TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) {
scoped_ptr<HttpNetworkTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
- SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
- ssl_config.unrestricted_ssl3_fallback_enabled = true;
-
TestCompletionCallback callback;
// This will consume |ssl_data1|, |ssl_data2| and |ssl_data3|.
int rv = callback.GetResult(
@@ -293,6 +148,7 @@ TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) {
// Confirms that |ssl_data1|, |ssl_data2| and |ssl_data3| are consumed.
EXPECT_EQ(3u, mock_data.next_index());
+ SSLConfig& ssl_config = GetServerSSLConfig(trans.get());
// |version_max| fallbacks to SSL 3.0.
EXPECT_EQ(SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_max);
EXPECT_TRUE(ssl_config.version_fallback);
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index a2165776c08..dd9eefecf37 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -64,6 +64,7 @@
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "url/gurl.h"
@@ -111,7 +112,7 @@ bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
return false;
std::string double_quote_headers;
base::JSONWriter::Write(header_list, &double_quote_headers);
- ReplaceChars(double_quote_headers, "\"", "'", headers);
+ base::ReplaceChars(double_quote_headers, "\"", "'", headers);
return true;
}
@@ -289,9 +290,9 @@ class HttpNetworkTransactionTest
CapturingBoundNetLog log;
session_deps_.net_log = log.bound().net_log();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
for (size_t i = 0; i < data_count; ++i) {
session_deps_.socket_factory->AddSocketDataProvider(data[i]);
@@ -386,7 +387,8 @@ class HttpNetworkTransactionTest
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpNetworkTransactionTest,
- testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
+ testing::Values(kProtoDeprecatedSPDY2,
+ kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
kProtoHTTP2Draft04));
namespace {
@@ -510,6 +512,7 @@ CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
cert_verifier,
NULL,
NULL,
+ NULL,
std::string(),
NULL,
NULL,
@@ -565,9 +568,9 @@ bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
} // namespace
TEST_P(HttpNetworkTransactionTest, Basic) {
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
}
TEST_P(HttpNetworkTransactionTest, SimpleGET) {
@@ -860,9 +863,9 @@ TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
request.url = GURL("http://redirect.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
@@ -904,9 +907,9 @@ TEST_P(HttpNetworkTransactionTest, Head) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("HEAD / HTTP/1.1\r\n"
@@ -1008,7 +1011,7 @@ TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
TEST_P(HttpNetworkTransactionTest, Ignores100) {
ScopedVector<UploadElementReader> element_readers;
element_readers.push_back(new UploadBytesElementReader("foo", 3));
- UploadDataStream upload_data_stream(&element_readers, 0);
+ UploadDataStream upload_data_stream(element_readers.Pass(), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -1016,9 +1019,9 @@ TEST_P(HttpNetworkTransactionTest, Ignores100) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
@@ -1058,9 +1061,9 @@ TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
@@ -1097,9 +1100,9 @@ TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
@@ -1128,9 +1131,10 @@ TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
request.url = GURL("http://www.foo.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
+
MockRead data_reads[] = {
MockRead(ASYNC, 0),
@@ -1258,9 +1262,9 @@ TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead(ASYNC, ERR_CONNECTION_RESET),
@@ -1506,9 +1510,9 @@ TEST_P(HttpNetworkTransactionTest, BasicAuth) {
CapturingNetLog log;
session_deps_.net_log = &log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -1599,9 +1603,9 @@ TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
request.url = GURL("http://www.google.com/");
request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -2262,9 +2266,9 @@ TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
request.load_flags = 0;
// We are using a DIRECT connection (i.e. no proxy) for this session.
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -3528,7 +3532,6 @@ void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
// Configure against proxy server "myproxy:70".
session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
-
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Since we have proxy, should try to establish tunnel.
@@ -3740,11 +3743,12 @@ TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ // Configure against proxy server "myproxy:70".
session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- // Configure against proxy server "myproxy:70".
- scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
@@ -4203,9 +4207,9 @@ TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
// Respond with 300 kb of headers (we should fail after 256 kb).
std::string large_headers_string;
@@ -4563,7 +4567,7 @@ TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
ScopedVector<UploadElementReader> element_readers;
element_readers.push_back(new UploadBytesElementReader("foo", 3));
- UploadDataStream upload_data_stream(&element_readers, 0);
+ UploadDataStream upload_data_stream(element_readers.Pass(), 0);
HttpRequestInfo request[2];
// Transaction 1: a GET request that succeeds. The socket is recycled
@@ -4658,9 +4662,9 @@ TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
request.url = GURL("http://foo:b@r@www.google.com/");
request.load_flags = LOAD_NORMAL;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
// The password contains an escaped character -- for this test to pass it
// will need to be unescaped by HttpNetworkTransaction.
@@ -4739,9 +4743,9 @@ TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
request.load_flags = LOAD_NORMAL;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -4847,9 +4851,9 @@ TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
request.url = GURL("http://foo:bar@www.google.com/");
request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes1[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -5438,9 +5442,9 @@ TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
// Test the ResetStateForRestart() private method.
TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
// Create a transaction (the dependencies aren't important).
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpNetworkTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
// Setup some state (which we expect ResetStateForRestart() will clear).
trans->read_buf_ = new IOBuffer(15);
@@ -5485,9 +5489,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
request.url = GURL("https://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -5589,9 +5593,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
for (int i = 0; i < 2; i++) {
session_deps_.socket_factory->ResetNextMockIndexes();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -5653,9 +5657,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -5711,9 +5715,9 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -5796,9 +5800,9 @@ TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -5848,9 +5852,9 @@ TEST_P(HttpNetworkTransactionTest,
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -5909,9 +5913,9 @@ TEST_P(HttpNetworkTransactionTest,
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -6334,9 +6338,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
TestCompletionCallback callback;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -6363,9 +6367,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
"Chromium Ultra Awesome X Edition");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6403,9 +6407,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
"Chromium Ultra Awesome X Edition");
session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
@@ -6442,9 +6446,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
"http://the.previous.site.com/");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6479,9 +6483,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
request.method = "POST";
request.url = GURL("http://www.google.com/");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("POST / HTTP/1.1\r\n"
@@ -6516,9 +6520,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
request.method = "PUT";
request.url = GURL("http://www.google.com/");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("PUT / HTTP/1.1\r\n"
@@ -6553,9 +6557,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
request.method = "HEAD";
request.url = GURL("http://www.google.com/");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("HEAD / HTTP/1.1\r\n"
@@ -6591,9 +6595,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
request.url = GURL("http://www.google.com/");
request.load_flags = LOAD_BYPASS_CACHE;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6631,9 +6635,9 @@ TEST_P(HttpNetworkTransactionTest,
request.url = GURL("http://www.google.com/");
request.load_flags = LOAD_VALIDATE_CACHE;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6669,9 +6673,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
request.url = GURL("http://www.google.com/");
request.extra_headers.SetHeader("FooHeader", "Bar");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6709,9 +6713,9 @@ TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
request.extra_headers.SetHeader("hEllo", "Kitty");
request.extra_headers.SetHeader("FoO", "bar");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -6754,9 +6758,9 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
CapturingNetLog net_log;
session_deps_.net_log = &net_log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
@@ -6813,9 +6817,9 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
CapturingNetLog net_log;
session_deps_.net_log = &net_log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
@@ -6877,9 +6881,9 @@ TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
CapturingNetLog net_log;
session_deps_.net_log = &net_log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
@@ -6936,9 +6940,9 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
CapturingNetLog net_log;
session_deps_.net_log = &net_log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
@@ -7009,9 +7013,9 @@ TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
CapturingNetLog net_log;
session_deps_.net_log = &net_log;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
@@ -7169,11 +7173,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
new CaptureGroupNameTransportSocketPool(NULL, NULL);
CaptureGroupNameSSLSocketPool* ssl_conn_pool =
new CaptureGroupNameSSLSocketPool(NULL, NULL);
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
EXPECT_EQ(ERR_IO_PENDING,
GroupNameTransactionHelper(tests[i].url, session));
@@ -7235,11 +7240,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
CaptureGroupNameSSLSocketPool* ssl_conn_pool =
new CaptureGroupNameSSLSocketPool(NULL, NULL);
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
EXPECT_EQ(ERR_IO_PENDING,
GroupNameTransactionHelper(tests[i].url, session));
@@ -7305,11 +7311,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
CaptureGroupNameSSLSocketPool* ssl_conn_pool =
new CaptureGroupNameSSLSocketPool(NULL, NULL);
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -7337,9 +7344,9 @@ TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
// connecting to both proxies (myproxy:70 and foobar:80).
session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
TestCompletionCallback callback;
@@ -7363,8 +7370,9 @@ void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
// Select a host resolver that does caching.
session_deps_.host_resolver.reset(new MockCachingHostResolver);
- scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ scoped_ptr<HttpTransaction> trans(
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
// Warm up the host cache so it has an entry for "www.google.com".
AddressList addrlist;
@@ -7428,8 +7436,6 @@ TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
// Make sure we can handle an error when writing the request.
TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.foo.com/");
@@ -7441,12 +7447,12 @@ TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
StaticSocketDataProvider data(NULL, 0,
write_failure, arraysize(write_failure));
session_deps_.socket_factory->AddSocketDataProvider(&data);
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback;
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -7457,8 +7463,6 @@ TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
// Check that a connection closed after the start of the headers finishes ok.
TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.foo.com/");
@@ -7471,12 +7475,12 @@ TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback;
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -7499,8 +7503,6 @@ TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
// Make sure that a dropped connection while draining the body for auth
// restart does the right thing.
TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
-
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("http://www.google.com/");
@@ -7545,6 +7547,7 @@ TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
data_writes2, arraysize(data_writes2));
session_deps_.socket_factory->AddSocketDataProvider(&data2);
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
TestCompletionCallback callback1;
@@ -7600,9 +7603,9 @@ TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
session_deps_.socket_factory->ResetNextMockIndexes();
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -7617,9 +7620,9 @@ TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
@@ -7649,7 +7652,7 @@ TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
base::FilePath temp_file_path;
- ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
+ ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
const uint64 kFakeSize = 100000; // file is actually blank
UploadFileElementReader::ScopedOverridingContentLengthForTests
overriding_content_length(kFakeSize);
@@ -7661,7 +7664,7 @@ TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
0,
kuint64max,
base::Time()));
- UploadDataStream upload_data_stream(&element_readers, 0);
+ UploadDataStream upload_data_stream(element_readers.Pass(), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -7669,9 +7672,9 @@ TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockRead data_reads[] = {
MockRead("HTTP/1.0 200 OK\r\n\r\n"),
@@ -7705,7 +7708,7 @@ TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
base::FilePath temp_file;
- ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
+ ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
std::string temp_file_content("Unreadable file.");
ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
temp_file_content.length()));
@@ -7718,7 +7721,7 @@ TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
0,
kuint64max,
base::Time()));
- UploadDataStream upload_data_stream(&element_readers, 0);
+ UploadDataStream upload_data_stream(element_readers.Pass(), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -7726,25 +7729,12 @@ TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
- // If we try to upload an unreadable file, the network stack should report
- // the file size as zero and upload zero bytes for that file.
+ // If we try to upload an unreadable file, the transaction should fail.
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
- MockRead data_reads[] = {
- MockRead("HTTP/1.0 200 OK\r\n\r\n"),
- MockRead(SYNCHRONOUS, OK),
- };
- MockWrite data_writes[] = {
- MockWrite("POST /upload HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n\r\n"),
- MockWrite(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
+ StaticSocketDataProvider data(NULL, 0, NULL, 0);
session_deps_.socket_factory->AddSocketDataProvider(&data);
TestCompletionCallback callback;
@@ -7753,32 +7743,43 @@ TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
EXPECT_EQ(ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
- EXPECT_EQ(OK, rv);
+ EXPECT_EQ(ERR_ACCESS_DENIED, rv);
const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response);
base::DeleteFile(temp_file, false);
}
-TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
- base::FilePath temp_file;
- ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
- std::string temp_file_contents("Unreadable file.");
- std::string unreadable_contents(temp_file_contents.length(), '\0');
- ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
- temp_file_contents.length()));
+TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
+ class FakeUploadElementReader : public UploadElementReader {
+ public:
+ FakeUploadElementReader() {}
+ virtual ~FakeUploadElementReader() {}
+
+ const CompletionCallback& callback() const { return callback_; }
+ // UploadElementReader overrides:
+ virtual int Init(const CompletionCallback& callback) OVERRIDE {
+ callback_ = callback;
+ return ERR_IO_PENDING;
+ }
+ virtual uint64 GetContentLength() const OVERRIDE { return 0; }
+ virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
+ virtual int Read(IOBuffer* buf,
+ int buf_length,
+ const CompletionCallback& callback) OVERRIDE {
+ return ERR_FAILED;
+ }
+
+ private:
+ CompletionCallback callback_;
+ };
+
+ FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
ScopedVector<UploadElementReader> element_readers;
- element_readers.push_back(
- new UploadFileElementReader(base::MessageLoopProxy::current().get(),
- temp_file,
- 0,
- kuint64max,
- base::Time()));
- UploadDataStream upload_data_stream(&element_readers, 0);
+ element_readers.push_back(fake_reader);
+ UploadDataStream upload_data_stream(element_readers.Pass(), 0);
HttpRequestInfo request;
request.method = "POST";
@@ -7786,72 +7787,24 @@ TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
request.upload_data_stream = &upload_data_stream;
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
-
- MockRead data_reads[] = {
- MockRead("HTTP/1.1 401 Unauthorized\r\n"),
- MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
- MockRead("Content-Length: 0\r\n\r\n"), // No response body.
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
- MockRead("HTTP/1.1 200 OK\r\n"),
- MockRead("Content-Length: 0\r\n\r\n"),
- MockRead(SYNCHRONOUS, OK),
- };
- MockWrite data_writes[] = {
- MockWrite("POST /upload HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 16\r\n\r\n"),
- MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
-
- MockWrite("POST /upload HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Connection: keep-alive\r\n"
- "Content-Length: 0\r\n"
- "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
- MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
- temp_file_contents.length()),
- MockWrite(SYNCHRONOUS, OK),
- };
- StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
- arraysize(data_writes));
+ StaticSocketDataProvider data;
session_deps_.socket_factory->AddSocketDataProvider(&data);
- TestCompletionCallback callback1;
-
- int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
-
- rv = callback1.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- const HttpResponseInfo* response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- ASSERT_TRUE(response->headers.get() != NULL);
- EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
- EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
-
- // Now make the file unreadable and try again.
- ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
-
- TestCompletionCallback callback2;
-
- rv = trans->RestartWithAuth(
- AuthCredentials(kFoo, kBar), callback2.callback());
+ TestCompletionCallback callback;
+ int rv = trans->Start(&request, callback.callback(), BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
+ base::MessageLoop::current()->RunUntilIdle();
- rv = callback2.WaitForResult();
- EXPECT_EQ(OK, rv);
-
- response = trans->GetResponseInfo();
- ASSERT_TRUE(response != NULL);
- EXPECT_TRUE(response->headers.get() != NULL);
- EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ // Transaction is pending on request body initialization.
+ ASSERT_FALSE(fake_reader->callback().is_null());
- base::DeleteFile(temp_file, false);
+ // Return Init()'s result after the transaction gets destroyed.
+ trans.reset();
+ fake_reader->callback().Run(OK); // Should not crash.
}
// Tests that changes to Auth realms are treated like auth rejections.
@@ -7938,9 +7891,9 @@ TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
TestCompletionCallback callback1;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
// Issue the first request with Authorize headers. There should be a
// password prompt for first_realm waiting to be filled in after the
@@ -9313,8 +9266,7 @@ TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
request.load_flags = 0;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
- HttpNetworkTransaction trans(
- DEFAULT_PRIORITY, CreateSession(&session_deps_));
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
for (int round = 0; round < test_config.num_auth_rounds; ++round) {
const TestRound& read_write_round = test_config.rounds[round];
@@ -9416,10 +9368,11 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
session_deps_.host_resolver.get(),
session_deps_.socket_factory.get(),
session_deps_.net_log);
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_pool);
- session_peer.SetClientSocketPoolManager(mock_pool_manager);
+ session_peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
scoped_ptr<HttpTransaction> trans(
new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
@@ -9869,9 +9822,9 @@ TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
request.load_flags = 0;
session_deps_.host_resolver->set_synchronous_mode(true);
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
data.set_connect_data(mock_connect);
@@ -11551,9 +11504,9 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
StaticSocketDataProvider data;
@@ -11581,9 +11534,9 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
StaticSocketDataProvider data;
@@ -11611,9 +11564,9 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
@@ -11647,9 +11600,9 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite(ASYNC, ERR_CONNECTION_RESET),
@@ -11683,9 +11636,9 @@ TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -11721,9 +11674,9 @@ TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -11760,9 +11713,9 @@ TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
request.load_flags = 0;
request.extra_headers.SetHeader("X-Foo", "bar");
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
scoped_ptr<HttpTransaction> trans(
- new HttpNetworkTransaction(DEFAULT_PRIORITY,
- CreateSession(&session_deps_)));
+ new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
MockWrite data_writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
@@ -11862,6 +11815,11 @@ class FakeStream : public HttpStreamBase,
return false;
}
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE {
+ ADD_FAILURE();
+ return 0;
+ }
+
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE {
ADD_FAILURE();
@@ -11904,12 +11862,25 @@ class FakeStreamRequest : public HttpStreamRequest,
FakeStreamRequest(RequestPriority priority,
HttpStreamRequest::Delegate* delegate)
: priority_(priority),
- delegate_(delegate) {}
+ delegate_(delegate),
+ websocket_stream_create_helper_(NULL) {}
+
+ FakeStreamRequest(RequestPriority priority,
+ HttpStreamRequest::Delegate* delegate,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper)
+ : priority_(priority),
+ delegate_(delegate),
+ websocket_stream_create_helper_(create_helper) {}
virtual ~FakeStreamRequest() {}
RequestPriority priority() const { return priority_; }
+ const WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_stream_create_helper() const {
+ return websocket_stream_create_helper_;
+ }
+
// Create a new FakeStream and pass it to the request's
// delegate. Returns a weak pointer to the FakeStream.
base::WeakPtr<FakeStream> FinishStreamRequest() {
@@ -11951,6 +11922,7 @@ class FakeStreamRequest : public HttpStreamRequest,
private:
RequestPriority priority_;
HttpStreamRequest::Delegate* const delegate_;
+ WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
};
@@ -11979,16 +11951,18 @@ class FakeStreamFactory : public HttpStreamFactory {
return fake_request;
}
- virtual HttpStreamRequest* RequestWebSocketStream(
+ virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
const HttpRequestInfo& info,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* factory,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) OVERRIDE {
- ADD_FAILURE();
- return NULL;
+ FakeStreamRequest* fake_request =
+ new FakeStreamRequest(priority, delegate, create_helper);
+ last_stream_request_ = fake_request->AsWeakPtr();
+ return fake_request;
}
virtual void PreconnectStreams(int num_streams,
@@ -12015,6 +11989,33 @@ class FakeStreamFactory : public HttpStreamFactory {
DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
};
+// TODO(yhirano): Split this class out into a net/websockets file, if it is
+// worth doing.
+class FakeWebSocketStreamCreateHelper :
+ public WebSocketHandshakeStreamBase::CreateHelper {
+ public:
+ virtual WebSocketHandshakeStreamBase* CreateBasicStream(
+ scoped_ptr<ClientSocketHandle> connection,
+ bool using_proxy) OVERRIDE {
+ NOTREACHED();
+ return NULL;
+ }
+
+ virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
+ const base::WeakPtr<SpdySession>& session,
+ bool use_relative_url) OVERRIDE {
+ NOTREACHED();
+ return NULL;
+ };
+
+ virtual ~FakeWebSocketStreamCreateHelper() {}
+
+ virtual scoped_ptr<WebSocketStream> Upgrade() {
+ NOTREACHED();
+ return scoped_ptr<WebSocketStream>();
+ }
+};
+
} // namespace
// Make sure that HttpNetworkTransaction passes on its priority to its
@@ -12023,7 +12024,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkSessionPeer peer(session);
FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(fake_factory);
+ peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
HttpNetworkTransaction trans(LOW, session);
@@ -12046,7 +12047,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkSessionPeer peer(session);
FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(fake_factory);
+ peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
HttpNetworkTransaction trans(LOW, session);
@@ -12071,7 +12072,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkSessionPeer peer(session);
FakeStreamFactory* fake_factory = new FakeStreamFactory();
- peer.SetHttpStreamFactory(fake_factory);
+ peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
HttpNetworkTransaction trans(LOW, session);
@@ -12091,6 +12092,39 @@ TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
EXPECT_EQ(LOWEST, fake_stream->priority());
}
+TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
+ // The same logic needs to be tested for both ws: and wss: schemes, but this
+ // test is already parameterised on NextProto, so it uses a loop to verify
+ // that the different schemes work.
+ std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
+ for (size_t i = 0; i < arraysize(test_cases); ++i) {
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+ HttpNetworkSessionPeer peer(session);
+ FakeStreamFactory* fake_factory = new FakeStreamFactory();
+ FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
+ peer.SetHttpStreamFactoryForWebSocket(
+ scoped_ptr<HttpStreamFactory>(fake_factory));
+
+ HttpNetworkTransaction trans(LOW, session);
+ trans.SetWebSocketHandshakeStreamCreateHelper(
+ &websocket_stream_create_helper);
+
+ HttpRequestInfo request;
+ TestCompletionCallback callback;
+ request.method = "GET";
+ request.url = GURL(test_cases[i]);
+
+ EXPECT_EQ(ERR_IO_PENDING,
+ trans.Start(&request, callback.callback(), BoundNetLog()));
+
+ base::WeakPtr<FakeStreamRequest> fake_request =
+ fake_factory->last_stream_request();
+ ASSERT_TRUE(fake_request != NULL);
+ EXPECT_EQ(&websocket_stream_create_helper,
+ fake_request->websocket_stream_create_helper());
+ }
+}
+
// Tests that when a used socket is returned to the SSL socket pool, it's closed
// if the transport socket pool is stalled on the global socket limit.
TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
diff --git a/chromium/net/http/http_pipelined_connection_impl.cc b/chromium/net/http/http_pipelined_connection_impl.cc
index e2e53de47ba..284b25406d8 100644
--- a/chromium/net/http/http_pipelined_connection_impl.cc
+++ b/chromium/net/http/http_pipelined_connection_impl.cc
@@ -653,6 +653,13 @@ void HttpPipelinedConnectionImpl::SetConnectionReused(int pipeline_id) {
connection_->set_is_reused(true);
}
+int64 HttpPipelinedConnectionImpl::GetTotalReceivedBytes(
+ int pipeline_id) const {
+ CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ CHECK(stream_info_map_.find(pipeline_id)->second.parser.get());
+ return stream_info_map_.find(pipeline_id)->second.parser->received_bytes();
+}
+
bool HttpPipelinedConnectionImpl::GetLoadTimingInfo(
int pipeline_id, LoadTimingInfo* load_timing_info) const {
return connection_->GetLoadTimingInfo(IsConnectionReused(pipeline_id),
diff --git a/chromium/net/http/http_pipelined_connection_impl.h b/chromium/net/http/http_pipelined_connection_impl.h
index f8246a06f9b..d558e47eb0b 100644
--- a/chromium/net/http/http_pipelined_connection_impl.h
+++ b/chromium/net/http/http_pipelined_connection_impl.h
@@ -125,6 +125,8 @@ class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl
void SetConnectionReused(int pipeline_id);
+ int64 GetTotalReceivedBytes(int pipeline_id) const;
+
bool GetLoadTimingInfo(int pipeline_id,
LoadTimingInfo* load_timing_info) const;
diff --git a/chromium/net/http/http_pipelined_host_forced_unittest.cc b/chromium/net/http/http_pipelined_host_forced_unittest.cc
index 37732aa800f..b86dd96d50a 100644
--- a/chromium/net/http/http_pipelined_host_forced_unittest.cc
+++ b/chromium/net/http/http_pipelined_host_forced_unittest.cc
@@ -37,7 +37,7 @@ class HttpPipelinedHostForcedTest : public testing::Test {
MatchesOrigin(key_.origin()),
Ref(ssl_config_), Ref(proxy_info_),
Ref(net_log_), true,
- kProtoSPDY2))
+ kProtoSPDY3))
.Times(1)
.WillOnce(Return(pipeline));
EXPECT_CALL(*pipeline, CreateNewStream())
@@ -45,7 +45,7 @@ class HttpPipelinedHostForcedTest : public testing::Test {
.WillOnce(Return(kDummyStream));
EXPECT_EQ(kDummyStream, host_->CreateStreamOnNewPipeline(
&connection_, ssl_config_, proxy_info_, net_log_, true,
- kProtoSPDY2));
+ kProtoSPDY3));
return pipeline;
}
diff --git a/chromium/net/http/http_pipelined_host_impl_unittest.cc b/chromium/net/http/http_pipelined_host_impl_unittest.cc
index ea49e12c105..2658472138d 100644
--- a/chromium/net/http/http_pipelined_host_impl_unittest.cc
+++ b/chromium/net/http/http_pipelined_host_impl_unittest.cc
@@ -48,7 +48,7 @@ class HttpPipelinedHostImplTest : public testing::Test {
MatchesOrigin(key_.origin()),
Ref(ssl_config_), Ref(proxy_info_),
Ref(net_log_), true,
- kProtoSPDY2))
+ kProtoSPDY3))
.Times(1)
.WillOnce(Return(pipeline));
EXPECT_CALL(*pipeline, CreateNewStream())
@@ -56,7 +56,7 @@ class HttpPipelinedHostImplTest : public testing::Test {
.WillOnce(Return(kDummyStream));
EXPECT_EQ(kDummyStream, host_->CreateStreamOnNewPipeline(
kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
- kProtoSPDY2));
+ kProtoSPDY3));
return pipeline;
}
@@ -208,7 +208,7 @@ TEST_F(HttpPipelinedHostImplTest, ShutsDownOnOldVersion) {
ClearTestPipeline(pipeline);
EXPECT_EQ(NULL, host_->CreateStreamOnNewPipeline(
kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
- kProtoSPDY2));
+ kProtoSPDY3));
}
TEST_F(HttpPipelinedHostImplTest, ShutsDownOnAuthenticationRequired) {
@@ -227,7 +227,7 @@ TEST_F(HttpPipelinedHostImplTest, ShutsDownOnAuthenticationRequired) {
ClearTestPipeline(pipeline);
EXPECT_EQ(NULL, host_->CreateStreamOnNewPipeline(
kDummyConnection, ssl_config_, proxy_info_, net_log_, true,
- kProtoSPDY2));
+ kProtoSPDY3));
}
TEST_F(HttpPipelinedHostImplTest, ConnectionCloseHasNoEffect) {
diff --git a/chromium/net/http/http_pipelined_stream.cc b/chromium/net/http/http_pipelined_stream.cc
index df5743556d1..cc267e2510e 100644
--- a/chromium/net/http/http_pipelined_stream.cc
+++ b/chromium/net/http/http_pipelined_stream.cc
@@ -99,6 +99,10 @@ bool HttpPipelinedStream::IsConnectionReusable() const {
return pipeline_->usable();
}
+int64 HttpPipelinedStream::GetTotalReceivedBytes() const {
+ return pipeline_->GetTotalReceivedBytes(pipeline_id_);
+}
+
bool HttpPipelinedStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
return pipeline_->GetLoadTimingInfo(pipeline_id_, load_timing_info);
diff --git a/chromium/net/http/http_pipelined_stream.h b/chromium/net/http/http_pipelined_stream.h
index d3a7991e5ca..7a853abc1a7 100644
--- a/chromium/net/http/http_pipelined_stream.h
+++ b/chromium/net/http/http_pipelined_stream.h
@@ -69,6 +69,8 @@ class HttpPipelinedStream : public HttpStream {
virtual bool IsConnectionReusable() const OVERRIDE;
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE;
+
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
diff --git a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
index 808305240ad..a70fe6ab067 100644
--- a/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/chromium/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -41,7 +41,7 @@ enum HttpProxyType {
struct HttpProxyClientSocketPoolTestParams {
HttpProxyClientSocketPoolTestParams()
: proxy_type(HTTP),
- protocol(kProtoSPDY2) {}
+ protocol(kProtoSPDY3) {}
HttpProxyClientSocketPoolTestParams(
HttpProxyType proxy_type,
@@ -77,6 +77,7 @@ class HttpProxyClientSocketPoolTest
session_deps_.cert_verifier.get(),
NULL /* server_bound_cert_store */,
NULL /* transport_security_state */,
+ NULL /* cert_transparency_verifier */,
std::string() /* ssl_session_cache_shard */,
session_deps_.deterministic_socket_factory.get(),
&transport_socket_pool_,
@@ -238,9 +239,9 @@ INSTANTIATE_TEST_CASE_P(
HttpProxyClientSocketPoolTests,
HttpProxyClientSocketPoolTest,
::testing::Values(
- HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY2),
- HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY2),
- HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY2),
+ HttpProxyClientSocketPoolTestParams(HTTP, kProtoDeprecatedSPDY2),
+ HttpProxyClientSocketPoolTestParams(HTTPS, kProtoDeprecatedSPDY2),
+ HttpProxyClientSocketPoolTestParams(SPDY, kProtoDeprecatedSPDY2),
HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY3),
HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY3),
HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY3),
diff --git a/chromium/net/http/http_request_headers.cc b/chromium/net/http/http_request_headers.cc
index bf557df37b8..8c9c4289336 100644
--- a/chromium/net/http/http_request_headers.cc
+++ b/chromium/net/http/http_request_headers.cc
@@ -11,6 +11,18 @@
#include "base/values.h"
#include "net/http/http_util.h"
+namespace {
+
+bool ShouldShowHttpHeaderValue(const std::string& header_name) {
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ if (header_name == "Proxy-Authorization")
+ return false;
+#endif
+ return true;
+}
+
+} // namespace
+
namespace net {
const char HttpRequestHeaders::kGetMethod[] = "GET";
@@ -191,10 +203,11 @@ base::Value* HttpRequestHeaders::NetLogCallback(
base::ListValue* headers = new base::ListValue();
for (HeaderVector::const_iterator it = headers_.begin();
it != headers_.end(); ++it) {
- headers->Append(
- new base::StringValue(base::StringPrintf("%s: %s",
- it->key.c_str(),
- it->value.c_str())));
+ headers->Append(new base::StringValue(
+ base::StringPrintf("%s: %s",
+ it->key.c_str(),
+ (ShouldShowHttpHeaderValue(it->key) ?
+ it->value.c_str() : "[elided]"))));
}
dict->Set("headers", headers);
return dict;
diff --git a/chromium/net/http/http_request_info.cc b/chromium/net/http/http_request_info.cc
index 7feb4ac3d7f..bffc96ccfae 100644
--- a/chromium/net/http/http_request_info.cc
+++ b/chromium/net/http/http_request_info.cc
@@ -10,7 +10,6 @@ HttpRequestInfo::HttpRequestInfo()
: upload_data_stream(NULL),
load_flags(0),
motivation(NORMAL_MOTIVATION),
- request_id(0),
privacy_mode(kPrivacyModeDisabled) {
}
diff --git a/chromium/net/http/http_request_info.h b/chromium/net/http/http_request_info.h
index 607bba5806d..a587a421b58 100644
--- a/chromium/net/http/http_request_info.h
+++ b/chromium/net/http/http_request_info.h
@@ -49,10 +49,6 @@ struct NET_EXPORT HttpRequestInfo {
// The motivation behind this request.
RequestMotivation motivation;
- // An optional globally unique identifier for this request for use by the
- // consumer. 0 is invalid.
- uint64 request_id;
-
// If enabled, then request must be sent over connection that cannot be
// tracked by the server (e.g. without channel id).
PrivacyMode privacy_mode;
diff --git a/chromium/net/http/http_response_body_drainer.cc b/chromium/net/http/http_response_body_drainer.cc
index d8f00853509..a1ba35ad31e 100644
--- a/chromium/net/http/http_response_body_drainer.cc
+++ b/chromium/net/http/http_response_body_drainer.cc
@@ -9,11 +9,11 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_network_session.h"
-#include "net/http/http_stream.h"
+#include "net/http/http_stream_base.h"
namespace net {
-HttpResponseBodyDrainer::HttpResponseBodyDrainer(HttpStream* stream)
+HttpResponseBodyDrainer::HttpResponseBodyDrainer(HttpStreamBase* stream)
: read_size_(0),
stream_(stream),
next_state_(STATE_NONE),
diff --git a/chromium/net/http/http_response_body_drainer.h b/chromium/net/http/http_response_body_drainer.h
index 915305cda46..284d08a99cd 100644
--- a/chromium/net/http/http_response_body_drainer.h
+++ b/chromium/net/http/http_response_body_drainer.h
@@ -15,7 +15,7 @@
namespace net {
-class HttpStream;
+class HttpStreamBase;
class IOBuffer;
class NET_EXPORT_PRIVATE HttpResponseBodyDrainer {
@@ -27,7 +27,7 @@ class NET_EXPORT_PRIVATE HttpResponseBodyDrainer {
static const int kDrainBodyBufferSize = 16384;
static const int kTimeoutInSeconds = 5;
- explicit HttpResponseBodyDrainer(HttpStream* stream);
+ explicit HttpResponseBodyDrainer(HttpStreamBase* stream);
~HttpResponseBodyDrainer();
// Starts reading the body until completion, or we hit the buffer limit, or we
@@ -56,7 +56,7 @@ class NET_EXPORT_PRIVATE HttpResponseBodyDrainer {
int read_size_;
scoped_refptr<IOBuffer> read_buf_;
- const scoped_ptr<HttpStream> stream_;
+ const scoped_ptr<HttpStreamBase> stream_;
State next_state_;
int total_read_;
CompletionCallback user_callback_;
diff --git a/chromium/net/http/http_response_body_drainer_unittest.cc b/chromium/net/http/http_response_body_drainer_unittest.cc
index 70134cce1ea..f587b908529 100644
--- a/chromium/net/http/http_response_body_drainer_unittest.cc
+++ b/chromium/net/http/http_response_body_drainer_unittest.cc
@@ -101,6 +101,7 @@ class MockHttpStream : public HttpStream {
virtual bool IsConnectionReused() const OVERRIDE { return false; }
virtual void SetConnectionReused() OVERRIDE {}
virtual bool IsConnectionReusable() const OVERRIDE { return false; }
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; }
virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
virtual void GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) OVERRIDE {}
diff --git a/chromium/net/http/http_response_headers.cc b/chromium/net/http/http_response_headers.cc
index 6047aa12ac8..289facd4f9e 100644
--- a/chromium/net/http/http_response_headers.cc
+++ b/chromium/net/http/http_response_headers.cc
@@ -113,6 +113,14 @@ void CheckDoesNotHaveEmbededNulls(const std::string& str) {
CHECK(str.find('\0') == std::string::npos);
}
+bool ShouldShowHttpHeaderValue(const std::string& header_name) {
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ if (header_name == "Proxy-Authenticate")
+ return false;
+#endif
+ return true;
+}
+
} // namespace
struct HttpResponseHeaders::ParsedHeader {
@@ -1309,9 +1317,11 @@ base::Value* HttpResponseHeaders::NetLogCallback(
std::string value;
while (EnumerateHeaderLines(&iterator, &name, &value)) {
headers->Append(
- new base::StringValue(base::StringPrintf("%s: %s",
- name.c_str(),
- value.c_str())));
+ new base::StringValue(
+ base::StringPrintf("%s: %s",
+ name.c_str(),
+ (ShouldShowHttpHeaderValue(name) ?
+ value.c_str() : "[elided]"))));
}
dict->Set("headers", headers);
return dict;
@@ -1354,4 +1364,59 @@ bool HttpResponseHeaders::IsChunkEncoded() const {
HasHeaderValue("Transfer-Encoding", "chunked");
}
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+bool HttpResponseHeaders::GetChromeProxyBypassDuration(
+ const std::string& action_prefix,
+ base::TimeDelta* duration) const {
+ void* iter = NULL;
+ std::string value;
+ std::string name = "chrome-proxy";
+
+ while (EnumerateHeader(&iter, name, &value)) {
+ if (value.size() > action_prefix.size()) {
+ if (LowerCaseEqualsASCII(value.begin(),
+ value.begin() + action_prefix.size(),
+ action_prefix.c_str())) {
+ int64 seconds;
+ if (!base::StringToInt64(
+ StringPiece(value.begin() + action_prefix.size(), value.end()),
+ &seconds) || seconds < 0) {
+ continue; // In case there is a well formed instruction.
+ }
+ *duration = TimeDelta::FromSeconds(seconds);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool HttpResponseHeaders::GetChromeProxyInfo(
+ ChromeProxyInfo* proxy_info) const {
+ DCHECK(proxy_info);
+ proxy_info->bypass_all = false;
+ proxy_info->bypass_duration = base::TimeDelta();
+
+ // Support header of the form Chrome-Proxy: bypass|block=<duration>, where
+ // <duration> is the number of seconds to wait before retrying
+ // the proxy. If the duration is 0, then the default proxy retry delay
+ // (specified in |ProxyList::UpdateRetryInfoOnFallback|) will be used.
+ // 'bypass' instructs Chrome to bypass the currently connected Chrome proxy,
+ // whereas 'block' instructs Chrome to bypass all available Chrome proxies.
+
+ // 'block' takes precedence over 'bypass', so look for it first.
+ // TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop.
+ if (GetChromeProxyBypassDuration("block=", &proxy_info->bypass_duration)) {
+ proxy_info->bypass_all = true;
+ return true;
+ }
+
+ // Next, look for 'bypass'.
+ if (GetChromeProxyBypassDuration("bypass=", &proxy_info->bypass_duration))
+ return true;
+
+ return false;
+}
+#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
+
} // namespace net
diff --git a/chromium/net/http/http_response_headers.h b/chromium/net/http/http_response_headers.h
index 61075979535..e54ac5df669 100644
--- a/chromium/net/http/http_response_headers.h
+++ b/chromium/net/http/http_response_headers.h
@@ -250,6 +250,28 @@ class NET_EXPORT HttpResponseHeaders
// Returns true if the response is chunk-encoded.
bool IsChunkEncoded() const;
+#if defined (SPDY_PROXY_AUTH_ORIGIN)
+ // Contains instructions contained in the Chrome-Proxy header.
+ struct ChromeProxyInfo {
+ ChromeProxyInfo() : bypass_all(false) {}
+
+ // True if Chrome should bypass all available Chrome proxies. False if only
+ // the currently connected Chrome proxy should be bypassed.
+ bool bypass_all;
+
+ // Amount of time to bypass the Chrome proxy or proxies.
+ base::TimeDelta bypass_duration;
+ };
+
+ // Returns true if the Chrome-Proxy header is present and contains a bypass
+ // delay. Sets |proxy_info->bypass_duration| to the specified delay if greater
+ // than 0, and to 0 otherwise to indicate that the default proxy delay
+ // (as specified in |ProxyList::UpdateRetryInfoOnFallback|) should be used.
+ // If all available Chrome proxies should by bypassed, |bypass_all| is set to
+ // true. |proxy_info| must be non-NULL.
+ bool GetChromeProxyInfo(ChromeProxyInfo* proxy_info) const;
+#endif
+
// Creates a Value for use with the NetLog containing the response headers.
base::Value* NetLogCallback(NetLog::LogLevel log_level) const;
@@ -348,6 +370,13 @@ class NET_EXPORT HttpResponseHeaders
// Adds the set of transport security state headers.
static void AddSecurityStateHeaders(HeaderSet* header_names);
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ // Searches for the specified Chrome-Proxy action, and if present interprets
+ // its value as a duration in seconds.
+ bool GetChromeProxyBypassDuration(const std::string& action_prefix,
+ base::TimeDelta* duration) const;
+#endif
+
// We keep a list of ParsedHeader objects. These tell us where to locate the
// header-value pairs within raw_headers_.
HeaderList parsed_;
diff --git a/chromium/net/http/http_response_headers_unittest.cc b/chromium/net/http/http_response_headers_unittest.cc
index 8bde289ed84..4be74783b74 100644
--- a/chromium/net/http/http_response_headers_unittest.cc
+++ b/chromium/net/http/http_response_headers_unittest.cc
@@ -1877,3 +1877,156 @@ TEST(HttpResponseHeadersTest, ToNetLogParamAndBackAgain) {
parsed->GetNormalizedHeaders(&normalized_recreated);
EXPECT_EQ(normalized_parsed, normalized_recreated);
}
+
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+TEST(HttpResponseHeadersTest, GetProxyBypassInfo) {
+ const struct {
+ const char* headers;
+ bool expected_result;
+ int64 expected_retry_delay;
+ bool expected_bypass_all;
+ } tests[] = {
+ { "HTTP/1.1 200 OK\n"
+ "Content-Length: 999\n",
+ false,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Content-Length: 999\n",
+ false,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=0\n"
+ "Content-Length: 999\n",
+ true,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=-1\n"
+ "Content-Length: 999\n",
+ false,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=xyz\n"
+ "Content-Length: 999\n",
+ false,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass\n"
+ "Content-Length: 999\n",
+ false,
+ 0,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: foo=abc, bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=86400, bar=abc\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=3600\n"
+ "Chrome-Proxy: bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 3600,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=3600, bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 3600,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=, bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass\n"
+ "Chrome-Proxy: bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: block=, block=3600\n"
+ "Content-Length: 999\n",
+ true,
+ 3600,
+ true,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: keep-alive\n"
+ "Chrome-Proxy: bypass=86400, block=3600\n"
+ "Content-Length: 999\n",
+ true,
+ 3600,
+ true,
+ },
+ { "HTTP/1.1 200 OK\n"
+ "connection: proxy-bypass\n"
+ "Chrome-Proxy: block=, bypass=86400\n"
+ "Content-Length: 999\n",
+ true,
+ 86400,
+ false,
+ },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ std::string headers(tests[i].headers);
+ HeadersToRaw(&headers);
+ scoped_refptr<net::HttpResponseHeaders> parsed(
+ new net::HttpResponseHeaders(headers));
+
+ net::HttpResponseHeaders::ChromeProxyInfo chrome_proxy_info;
+ EXPECT_EQ(tests[i].expected_result,
+ parsed->GetChromeProxyInfo(&chrome_proxy_info));
+ EXPECT_EQ(tests[i].expected_retry_delay,
+ chrome_proxy_info.bypass_duration.InSeconds());
+ EXPECT_EQ(tests[i].expected_bypass_all,
+ chrome_proxy_info.bypass_all);
+ }
+}
+#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
diff --git a/chromium/net/http/http_response_info.cc b/chromium/net/http/http_response_info.cc
index 0b57a4e774b..4f9e014cfb2 100644
--- a/chromium/net/http/http_response_info.cc
+++ b/chromium/net/http/http_response_info.cc
@@ -10,6 +10,7 @@
#include "net/base/auth.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/cert/signed_certificate_timestamp.h"
#include "net/cert/x509_certificate.h"
#include "net/http/http_response_headers.h"
#include "net/ssl/ssl_cert_request_info.h"
@@ -87,6 +88,9 @@ enum {
// This bit is set if the request has http authentication.
RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19,
+ // This bit is set if ssl_info has SCTs.
+ RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20,
+
// TODO(darin): Add other bits to indicate alternate request methods.
// For now, we don't support storing those.
};
@@ -207,6 +211,22 @@ bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
ssl_info.connection_status = connection_status;
}
+ if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
+ int num_scts;
+ if (!pickle.ReadInt(&iter, &num_scts))
+ return false;
+ for (int i = 0; i < num_scts; ++i) {
+ scoped_refptr<ct::SignedCertificateTimestamp> sct(
+ ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
+ uint16 status;
+ if (!sct.get() || !pickle.ReadUInt16(&iter, &status))
+ return false;
+ ssl_info.signed_certificate_timestamps.push_back(
+ SignedCertificateTimestampAndStatus(
+ sct, static_cast<ct::SCTVerifyStatus>(status)));
+ }
+ }
+
// Read vary-data
if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
if (!vary_data.InitFromPickle(pickle, &iter))
@@ -286,6 +306,8 @@ void HttpResponseInfo::Persist(Pickle* pickle,
flags |= RESPONSE_INFO_HAS_CONNECTION_INFO;
if (did_use_http_auth)
flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
+ if (!ssl_info.signed_certificate_timestamps.empty())
+ flags |= RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS;
pickle->WriteInt(flags);
pickle->WriteInt64(request_time.ToInternalValue());
@@ -313,6 +335,15 @@ void HttpResponseInfo::Persist(Pickle* pickle,
pickle->WriteInt(ssl_info.security_bits);
if (ssl_info.connection_status != 0)
pickle->WriteInt(ssl_info.connection_status);
+ if (!ssl_info.signed_certificate_timestamps.empty()) {
+ pickle->WriteInt(ssl_info.signed_certificate_timestamps.size());
+ for (SignedCertificateTimestampAndStatusList::const_iterator it =
+ ssl_info.signed_certificate_timestamps.begin(); it !=
+ ssl_info.signed_certificate_timestamps.end(); ++it) {
+ it->sct_->Persist(pickle);
+ pickle->WriteUInt16(it->status_);
+ }
+ }
}
if (vary_data.is_valid())
@@ -331,8 +362,8 @@ void HttpResponseInfo::Persist(Pickle* pickle,
HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
NextProto next_proto) {
switch (next_proto) {
- case kProtoSPDY2:
- return CONNECTION_INFO_SPDY2;
+ case kProtoDeprecatedSPDY2:
+ return CONNECTION_INFO_DEPRECATED_SPDY2;
case kProtoSPDY3:
case kProtoSPDY31:
return CONNECTION_INFO_SPDY3;
@@ -345,8 +376,6 @@ HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto(
case kProtoUnknown:
case kProtoHTTP11:
- case kProtoSPDY1:
- case kProtoSPDY21:
break;
}
@@ -362,7 +391,7 @@ std::string HttpResponseInfo::ConnectionInfoToString(
return "unknown";
case CONNECTION_INFO_HTTP1:
return "http/1";
- case CONNECTION_INFO_SPDY2:
+ case CONNECTION_INFO_DEPRECATED_SPDY2:
return "spdy/2";
case CONNECTION_INFO_SPDY3:
return "spdy/3";
diff --git a/chromium/net/http/http_response_info.h b/chromium/net/http/http_response_info.h
index 907ec96a570..f0908b0ab46 100644
--- a/chromium/net/http/http_response_info.h
+++ b/chromium/net/http/http_response_info.h
@@ -35,7 +35,7 @@ class NET_EXPORT HttpResponseInfo {
enum ConnectionInfo {
CONNECTION_INFO_UNKNOWN = 0,
CONNECTION_INFO_HTTP1 = 1,
- CONNECTION_INFO_SPDY2 = 2,
+ CONNECTION_INFO_DEPRECATED_SPDY2 = 2,
CONNECTION_INFO_SPDY3 = 3,
CONNECTION_INFO_SPDY4A2 = 4,
CONNECTION_INFO_QUIC1_SPDY3 = 5,
diff --git a/chromium/net/http/http_security_headers.cc b/chromium/net/http/http_security_headers.cc
index 9fc7627cc5e..0c3305f6e42 100644
--- a/chromium/net/http/http_security_headers.cc
+++ b/chromium/net/http/http_security_headers.cc
@@ -325,7 +325,18 @@ bool ParseHPKPHeader(const std::string& value,
*include_subdomains = include_subdomains_candidate;
for (HashValueVector::const_iterator i = pins.begin();
i != pins.end(); ++i) {
- hashes->push_back(*i);
+ bool found = false;
+
+ for (HashValueVector::const_iterator j = hashes->begin();
+ j != hashes->end(); ++j) {
+ if (j->Equals(*i)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ hashes->push_back(*i);
}
return true;
diff --git a/chromium/net/http/http_security_headers_unittest.cc b/chromium/net/http/http_security_headers_unittest.cc
index 0cc81b57eb8..42a5ee98960 100644
--- a/chromium/net/http/http_security_headers_unittest.cc
+++ b/chromium/net/http/http_security_headers_unittest.cc
@@ -416,6 +416,20 @@ static void TestValidPKPHeaders(HashValueTag tag) {
expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
EXPECT_EQ(expect_max_age, max_age);
EXPECT_FALSE(include_subdomains);
+
+ // Test that parsing the same header twice doesn't duplicate the recorded
+ // hashes.
+ hashes.clear();
+ EXPECT_TRUE(ParseHPKPHeader(
+ " max-age=999; " +
+ backup_pin + ";" + good_pin + "; ",
+ chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_EQ(2u, hashes.size());
+ EXPECT_TRUE(ParseHPKPHeader(
+ " max-age=999; " +
+ backup_pin + ";" + good_pin + "; ",
+ chain_hashes, &max_age, &include_subdomains, &hashes));
+ EXPECT_EQ(2u, hashes.size());
}
TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
diff --git a/chromium/net/http/http_server_properties.cc b/chromium/net/http/http_server_properties.cc
index bff262ade45..a10d5060c06 100644
--- a/chromium/net/http/http_server_properties.cc
+++ b/chromium/net/http/http_server_properties.cc
@@ -16,7 +16,6 @@ namespace {
// The order of these strings much match the order of the enum definition
// for AlternateProtocol.
const char* const kAlternateProtocolStrings[] = {
- "npn-spdy/1",
"npn-spdy/2",
"npn-spdy/3",
"npn-spdy/3.1",
@@ -26,25 +25,28 @@ const char* const kAlternateProtocolStrings[] = {
};
const char kBrokenAlternateProtocol[] = "Broken";
-COMPILE_ASSERT(arraysize(kAlternateProtocolStrings) == NUM_ALTERNATE_PROTOCOLS,
- kAlternateProtocolStringsSize_NUM_ALTERNATE_PROTOCOLS_nut_equal);
+COMPILE_ASSERT(
+ arraysize(kAlternateProtocolStrings) == NUM_VALID_ALTERNATE_PROTOCOLS,
+ kAlternateProtocolStringsSize_kNumValidAlternateProtocols_not_equal);
} // namespace
+bool IsAlternateProtocolValid(AlternateProtocol protocol) {
+ return protocol >= ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION &&
+ protocol <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION;
+}
+
const char* AlternateProtocolToString(AlternateProtocol protocol) {
switch (protocol) {
- case NPN_SPDY_1:
- case NPN_SPDY_2:
+ case DEPRECATED_NPN_SPDY_2:
case NPN_SPDY_3:
case NPN_SPDY_3_1:
case NPN_SPDY_4A2:
case NPN_HTTP2_DRAFT_04:
case QUIC:
- DCHECK_LT(static_cast<size_t>(protocol),
- arraysize(kAlternateProtocolStrings));
- return kAlternateProtocolStrings[protocol];
- case NUM_ALTERNATE_PROTOCOLS:
- break;
+ DCHECK(IsAlternateProtocolValid(protocol));
+ return kAlternateProtocolStrings[
+ protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION];
case ALTERNATE_PROTOCOL_BROKEN:
return kBrokenAlternateProtocol;
case UNINITIALIZED_ALTERNATE_PROTOCOL:
@@ -54,19 +56,22 @@ const char* AlternateProtocolToString(AlternateProtocol protocol) {
return "";
}
-AlternateProtocol AlternateProtocolFromString(const std::string& protocol) {
- for (int i = NPN_SPDY_1; i < NUM_ALTERNATE_PROTOCOLS; ++i)
- if (protocol == kAlternateProtocolStrings[i])
- return static_cast<AlternateProtocol>(i);
- if (protocol == kBrokenAlternateProtocol)
+AlternateProtocol AlternateProtocolFromString(const std::string& str) {
+ for (int i = ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION;
+ i <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION; ++i) {
+ AlternateProtocol protocol = static_cast<AlternateProtocol>(i);
+ if (str == AlternateProtocolToString(protocol))
+ return protocol;
+ }
+ if (str == kBrokenAlternateProtocol)
return ALTERNATE_PROTOCOL_BROKEN;
return UNINITIALIZED_ALTERNATE_PROTOCOL;
}
AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) {
switch (next_proto) {
- case kProtoSPDY2:
- return NPN_SPDY_2;
+ case kProtoDeprecatedSPDY2:
+ return DEPRECATED_NPN_SPDY_2;
case kProtoSPDY3:
return NPN_SPDY_3;
case kProtoSPDY31:
@@ -80,8 +85,6 @@ AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) {
case kProtoUnknown:
case kProtoHTTP11:
- case kProtoSPDY1:
- case kProtoSPDY21:
break;
}
diff --git a/chromium/net/http/http_server_properties.h b/chromium/net/http/http_server_properties.h
index 654d262024a..72fda4355b1 100644
--- a/chromium/net/http/http_server_properties.h
+++ b/chromium/net/http/http_server_properties.h
@@ -18,9 +18,9 @@
namespace net {
enum AlternateProtocol {
- NPN_SPDY_1 = 0,
- NPN_SPDY_MINIMUM_VERSION = NPN_SPDY_1,
- NPN_SPDY_2,
+ DEPRECATED_NPN_SPDY_2 = 0,
+ ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION = DEPRECATED_NPN_SPDY_2,
+ NPN_SPDY_MINIMUM_VERSION = DEPRECATED_NPN_SPDY_2,
NPN_SPDY_3,
NPN_SPDY_3_1,
NPN_SPDY_4A2,
@@ -28,14 +28,25 @@ enum AlternateProtocol {
NPN_HTTP2_DRAFT_04,
NPN_SPDY_MAXIMUM_VERSION = NPN_HTTP2_DRAFT_04,
QUIC,
- NUM_ALTERNATE_PROTOCOLS,
+ ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION = QUIC,
ALTERNATE_PROTOCOL_BROKEN, // The alternate protocol is known to be broken.
UNINITIALIZED_ALTERNATE_PROTOCOL,
};
+// Simply returns whether |protocol| is between
+// ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION and
+// ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION (inclusive).
+NET_EXPORT bool IsAlternateProtocolValid(AlternateProtocol protocol);
+
+enum AlternateProtocolSize {
+ NUM_VALID_ALTERNATE_PROTOCOLS =
+ ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION -
+ ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION + 1,
+};
+
NET_EXPORT const char* AlternateProtocolToString(AlternateProtocol protocol);
NET_EXPORT AlternateProtocol AlternateProtocolFromString(
- const std::string& protocol);
+ const std::string& str);
NET_EXPORT_PRIVATE AlternateProtocol AlternateProtocolFromNextProto(
NextProto next_proto);
diff --git a/chromium/net/http/http_server_properties_impl.cc b/chromium/net/http/http_server_properties_impl.cc
index a0b287de588..a4ac6dc3804 100644
--- a/chromium/net/http/http_server_properties_impl.cc
+++ b/chromium/net/http/http_server_properties_impl.cc
@@ -18,9 +18,9 @@ namespace net {
static const int kDefaultNumHostsToRemember = 200;
HttpServerPropertiesImpl::HttpServerPropertiesImpl()
- : weak_ptr_factory_(this),
- pipeline_capability_map_(
- new CachedPipelineCapabilityMap(kDefaultNumHostsToRemember)) {
+ : pipeline_capability_map_(
+ new CachedPipelineCapabilityMap(kDefaultNumHostsToRemember)),
+ weak_ptr_factory_(this) {
}
HttpServerPropertiesImpl::~HttpServerPropertiesImpl() {
diff --git a/chromium/net/http/http_server_properties_impl.h b/chromium/net/http/http_server_properties_impl.h
index c1e2d4ba20b..cf96b7d4f32 100644
--- a/chromium/net/http/http_server_properties_impl.h
+++ b/chromium/net/http/http_server_properties_impl.h
@@ -145,14 +145,14 @@ class NET_EXPORT HttpServerPropertiesImpl
// pair) that either support or not support SPDY protocol.
typedef base::hash_map<std::string, bool> SpdyServerHostPortTable;
- base::WeakPtrFactory<HttpServerPropertiesImpl> weak_ptr_factory_;
-
SpdyServerHostPortTable spdy_servers_table_;
AlternateProtocolMap alternate_protocol_map_;
SpdySettingsMap spdy_settings_map_;
scoped_ptr<CachedPipelineCapabilityMap> pipeline_capability_map_;
+ base::WeakPtrFactory<HttpServerPropertiesImpl> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl);
};
diff --git a/chromium/net/http/http_server_properties_impl_unittest.cc b/chromium/net/http/http_server_properties_impl_unittest.cc
index d125adcc40c..cf3a4643f9d 100644
--- a/chromium/net/http/http_server_properties_impl_unittest.cc
+++ b/chromium/net/http/http_server_properties_impl_unittest.cc
@@ -189,12 +189,12 @@ typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest;
TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
HostPortPair test_host_port_pair("foo", 80);
EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair));
- impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_1);
+ impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3);
ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair));
const PortAlternateProtocolPair alternate =
impl_.GetAlternateProtocol(test_host_port_pair);
EXPECT_EQ(443, alternate.port);
- EXPECT_EQ(NPN_SPDY_1, alternate.protocol);
+ EXPECT_EQ(NPN_SPDY_3, alternate.protocol);
impl_.Clear();
EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair));
@@ -204,12 +204,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
HostPortPair test_host_port_pair1("foo1", 80);
impl_.SetBrokenAlternateProtocol(test_host_port_pair1);
HostPortPair test_host_port_pair2("foo2", 80);
- impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_1);
+ impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_3);
AlternateProtocolMap alternate_protocol_map;
PortAlternateProtocolPair port_alternate_protocol_pair;
port_alternate_protocol_pair.port = 123;
- port_alternate_protocol_pair.protocol = NPN_SPDY_2;
+ port_alternate_protocol_pair.protocol = NPN_SPDY_3;
alternate_protocol_map[test_host_port_pair2] = port_alternate_protocol_pair;
impl_.InitializeAlternateProtocolServers(&alternate_protocol_map);
@@ -221,7 +221,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
port_alternate_protocol_pair =
impl_.GetAlternateProtocol(test_host_port_pair2);
EXPECT_EQ(123, port_alternate_protocol_pair.port);
- EXPECT_EQ(NPN_SPDY_2, port_alternate_protocol_pair.protocol);
+ EXPECT_EQ(NPN_SPDY_3, port_alternate_protocol_pair.protocol);
}
TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
@@ -235,7 +235,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
impl_.SetAlternateProtocol(
test_host_port_pair,
1234,
- NPN_SPDY_1);
+ NPN_SPDY_3);
alternate = impl_.GetAlternateProtocol(test_host_port_pair);
EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol)
<< "Second attempt should be ignored.";
@@ -246,7 +246,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, Forced) {
PortAlternateProtocolPair default_protocol;
default_protocol.port = 1234;
- default_protocol.protocol = NPN_SPDY_2;
+ default_protocol.protocol = NPN_SPDY_3;
HttpServerPropertiesImpl::ForceAlternateProtocol(default_protocol);
// Verify the forced protocol.
@@ -258,11 +258,11 @@ TEST_F(AlternateProtocolServerPropertiesTest, Forced) {
EXPECT_EQ(default_protocol.protocol, alternate.protocol);
// Verify the real protocol overrides the forced protocol.
- impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_1);
+ impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3);
ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair));
alternate = impl_.GetAlternateProtocol(test_host_port_pair);
EXPECT_EQ(443, alternate.port);
- EXPECT_EQ(NPN_SPDY_1, alternate.protocol);
+ EXPECT_EQ(NPN_SPDY_3, alternate.protocol);
// Turn off the static, forced alternate protocol so that tests don't
// have this state.
diff --git a/chromium/net/http/http_stream_base.h b/chromium/net/http/http_stream_base.h
index 596ed75dff1..f5dcc29409e 100644
--- a/chromium/net/http/http_stream_base.h
+++ b/chromium/net/http/http_stream_base.h
@@ -5,7 +5,7 @@
// HttpStreamBase is an interface for reading and writing data to an
// HTTP-like stream that keeps the client agnostic of the actual underlying
// transport layer. This provides an abstraction for HttpStream and
-// WebSocketStream.
+// WebSocketHandshakeStreamBase.
#ifndef NET_HTTP_HTTP_STREAM_BASE_H_
#define NET_HTTP_HTTP_STREAM_BASE_H_
@@ -110,6 +110,9 @@ class NET_EXPORT_PRIVATE HttpStreamBase {
// allows it to be reused.
virtual bool IsConnectionReusable() const = 0;
+ // Get the total number of bytes received from network for this stream.
+ virtual int64 GetTotalReceivedBytes() const = 0;
+
// Populates the connection establishment part of |load_timing_info|, and
// socket ID. |load_timing_info| must have all null times when called.
// Returns false and does nothing if there is no underlying connection, either
diff --git a/chromium/net/http/http_stream_factory.cc b/chromium/net/http/http_stream_factory.cc
index a55ed075bb5..e88046fba3c 100644
--- a/chromium/net/http/http_stream_factory.cc
+++ b/chromium/net/http/http_stream_factory.cc
@@ -19,7 +19,7 @@ namespace net {
// static
std::vector<std::string>* HttpStreamFactory::next_protos_ = NULL;
// static
-bool HttpStreamFactory::enabled_protocols_[NUM_ALTERNATE_PROTOCOLS];
+bool HttpStreamFactory::enabled_protocols_[NUM_VALID_ALTERNATE_PROTOCOLS];
// static
bool HttpStreamFactory::spdy_enabled_ = true;
// static
@@ -34,6 +34,28 @@ std::list<HostPortPair>* HttpStreamFactory::forced_spdy_exclusions_ = NULL;
HttpStreamFactory::~HttpStreamFactory() {}
// static
+bool HttpStreamFactory::IsProtocolEnabled(AlternateProtocol protocol) {
+ DCHECK(IsAlternateProtocolValid(protocol));
+ return enabled_protocols_[
+ protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION];
+}
+
+// static
+void HttpStreamFactory::SetProtocolEnabled(AlternateProtocol protocol) {
+ DCHECK(IsAlternateProtocolValid(protocol));
+ enabled_protocols_[
+ protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = true;
+}
+
+// static
+void HttpStreamFactory::ResetEnabledProtocols() {
+ for (int i = ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION;
+ i <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION; ++i) {
+ enabled_protocols_[i - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = false;
+ }
+}
+
+// static
void HttpStreamFactory::ResetStaticSettingsToInit() {
// WARNING: These must match the initializers above.
delete next_protos_;
@@ -44,8 +66,7 @@ void HttpStreamFactory::ResetStaticSettingsToInit() {
force_spdy_over_ssl_ = true;
force_spdy_always_ = false;
forced_spdy_exclusions_ = NULL;
- for (int i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i)
- enabled_protocols_[i] = false;
+ ResetEnabledProtocols();
}
void HttpStreamFactory::ProcessAlternateProtocol(
@@ -55,31 +76,31 @@ void HttpStreamFactory::ProcessAlternateProtocol(
std::vector<std::string> port_protocol_vector;
base::SplitString(alternate_protocol_str, ':', &port_protocol_vector);
if (port_protocol_vector.size() != 2) {
- DLOG(WARNING) << kAlternateProtocolHeader
- << " header has too many tokens: "
- << alternate_protocol_str;
+ DVLOG(1) << kAlternateProtocolHeader
+ << " header has too many tokens: "
+ << alternate_protocol_str;
return;
}
int port;
if (!base::StringToInt(port_protocol_vector[0], &port) ||
port <= 0 || port >= 1 << 16) {
- DLOG(WARNING) << kAlternateProtocolHeader
- << " header has unrecognizable port: "
- << port_protocol_vector[0];
+ DVLOG(1) << kAlternateProtocolHeader
+ << " header has unrecognizable port: "
+ << port_protocol_vector[0];
return;
}
AlternateProtocol protocol =
AlternateProtocolFromString(port_protocol_vector[1]);
- if (protocol < NUM_ALTERNATE_PROTOCOLS && !enabled_protocols_[protocol])
+ if (IsAlternateProtocolValid(protocol) && !IsProtocolEnabled(protocol)) {
protocol = ALTERNATE_PROTOCOL_BROKEN;
+ }
if (protocol == ALTERNATE_PROTOCOL_BROKEN) {
- // Currently, we only recognize the npn-spdy protocol.
- DLOG(WARNING) << kAlternateProtocolHeader
- << " header has unrecognized protocol: "
- << port_protocol_vector[1];
+ DVLOG(1) << kAlternateProtocolHeader
+ << " header has unrecognized protocol: "
+ << port_protocol_vector[1];
return;
}
@@ -136,16 +157,6 @@ bool HttpStreamFactory::HasSpdyExclusion(const HostPortPair& endpoint) {
}
// static
-void HttpStreamFactory::EnableNpnSpdy() {
- set_use_alternate_protocols(true);
- std::vector<NextProto> next_protos;
- next_protos.push_back(kProtoHTTP11);
- next_protos.push_back(kProtoQUIC1SPDY3);
- next_protos.push_back(kProtoSPDY2);
- SetNextProtos(next_protos);
-}
-
-// static
void HttpStreamFactory::EnableNpnHttpOnly() {
// Avoid alternate protocol in this case. Otherwise, browser will try SSL
// and then fallback to http. This introduces extra load.
@@ -161,7 +172,6 @@ void HttpStreamFactory::EnableNpnSpdy3() {
std::vector<NextProto> next_protos;
next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoQUIC1SPDY3);
- next_protos.push_back(kProtoSPDY2);
next_protos.push_back(kProtoSPDY3);
SetNextProtos(next_protos);
}
@@ -172,7 +182,18 @@ void HttpStreamFactory::EnableNpnSpdy31() {
std::vector<NextProto> next_protos;
next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoQUIC1SPDY3);
- next_protos.push_back(kProtoSPDY2);
+ next_protos.push_back(kProtoSPDY3);
+ next_protos.push_back(kProtoSPDY31);
+ SetNextProtos(next_protos);
+}
+
+// static
+void HttpStreamFactory::EnableNpnSpdy31WithSpdy2() {
+ set_use_alternate_protocols(true);
+ std::vector<NextProto> next_protos;
+ next_protos.push_back(kProtoHTTP11);
+ next_protos.push_back(kProtoQUIC1SPDY3);
+ next_protos.push_back(kProtoDeprecatedSPDY2);
next_protos.push_back(kProtoSPDY3);
next_protos.push_back(kProtoSPDY31);
SetNextProtos(next_protos);
@@ -184,7 +205,6 @@ void HttpStreamFactory::EnableNpnSpdy4a2() {
std::vector<NextProto> next_protos;
next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoQUIC1SPDY3);
- next_protos.push_back(kProtoSPDY2);
next_protos.push_back(kProtoSPDY3);
next_protos.push_back(kProtoSPDY31);
next_protos.push_back(kProtoSPDY4a2);
@@ -197,7 +217,6 @@ void HttpStreamFactory::EnableNpnHttp2Draft04() {
std::vector<NextProto> next_protos;
next_protos.push_back(kProtoHTTP11);
next_protos.push_back(kProtoQUIC1SPDY3);
- next_protos.push_back(kProtoSPDY2);
next_protos.push_back(kProtoSPDY3);
next_protos.push_back(kProtoSPDY31);
next_protos.push_back(kProtoSPDY4a2);
@@ -212,8 +231,7 @@ void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) {
next_protos_->clear();
- for (uint32 i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i)
- enabled_protocols_[i] = false;
+ ResetEnabledProtocols();
// TODO(rtenneti): bug 116575 - consider combining the NextProto and
// AlternateProtocol.
@@ -229,11 +247,11 @@ void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) {
// which has not corresponding alternative.
if (proto != kProtoHTTP11) {
AlternateProtocol alternate = AlternateProtocolFromNextProto(proto);
- if (alternate == UNINITIALIZED_ALTERNATE_PROTOCOL) {
+ if (!IsAlternateProtocolValid(alternate)) {
NOTREACHED() << "Invalid next proto: " << proto;
continue;
}
- enabled_protocols_[alternate] = true;
+ SetProtocolEnabled(alternate);
}
}
}
diff --git a/chromium/net/http/http_stream_factory.h b/chromium/net/http/http_stream_factory.h
index 0de3b65bc57..0d854a5dd9d 100644
--- a/chromium/net/http/http_stream_factory.h
+++ b/chromium/net/http/http_stream_factory.h
@@ -21,7 +21,7 @@
// This file can be included from net/http even though
// it is in net/websockets because it doesn't
// introduce any link dependency to net/websockets.
-#include "net/websockets/websocket_stream_base.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
class GURL;
@@ -71,17 +71,17 @@ class NET_EXPORT_PRIVATE HttpStreamRequest {
const ProxyInfo& used_proxy_info,
HttpStreamBase* stream) = 0;
- // This is the success case for RequestWebSocketStream.
+ // This is the success case for RequestWebSocketHandshakeStream.
// |stream| is now owned by the delegate.
// |used_ssl_config| indicates the actual SSL configuration used for this
// stream, since the HttpStreamRequest may have modified the configuration
// during stream processing.
// |used_proxy_info| indicates the actual ProxyInfo used for this stream,
// since the HttpStreamRequest performs the proxy resolution.
- virtual void OnWebSocketStreamReady(
+ virtual void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) = 0;
+ WebSocketHandshakeStreamBase* stream) = 0;
// This is the failure to create a stream case.
// |used_ssl_config| indicates the actual SSL configuration used for this
@@ -197,15 +197,16 @@ class NET_EXPORT HttpStreamFactory {
HttpStreamRequest::Delegate* delegate,
const BoundNetLog& net_log) = 0;
- // Request a WebSocket stream.
- // Will call delegate->OnWebSocketStreamReady on successful completion.
- virtual HttpStreamRequest* RequestWebSocketStream(
+ // Request a WebSocket handshake stream.
+ // Will call delegate->OnWebSocketHandshakeStreamReady on successful
+ // completion.
+ virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
const HttpRequestInfo& info,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* factory,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) = 0;
// Requests that enough connections for |num_streams| be opened.
@@ -265,25 +266,24 @@ class NET_EXPORT HttpStreamFactory {
// Sets http/1.1 as the only protocol supported via NPN or Alternate-Protocol.
static void EnableNpnHttpOnly();
- // Sets http/1.1, quic and spdy/2 (the default spdy protocol) as the protocols
- // supported via NPN or Alternate-Protocol.
- static void EnableNpnSpdy();
-
- // Sets http/1.1, quic, spdy/2, and spdy/3 as the protocols supported via NPN
- // or Alternate-Protocol.
+ // Sets http/1.1, quic, and spdy/3 as the protocols supported via
+ // NPN or Alternate-Protocol.
static void EnableNpnSpdy3();
- // Sets http/1.1, quic, spdy/2, spdy/3, and spdy/3.1 as the protocols
+ // Sets http/1.1, quic, spdy/3, and spdy/3.1 as the protocols
// supported via NPN or Alternate-Protocol.
static void EnableNpnSpdy31();
- // Sets http/1.1, quic, spdy/2, spdy/3, spdy/3.1, and spdy/4a2 as
- // the protocols supported via NPN or Alternate-Protocol.
+ // Sets http/1.1, quic, spdy/2, spdy/3, and spdy/3.1 as the
+ // protocols supported via NPN or Alternate-Protocol.
+ static void EnableNpnSpdy31WithSpdy2();
+
+ // Sets http/1.1, quic, spdy/3, spdy/3.1, and spdy/4a2 as the
+ // protocols supported via NPN or Alternate-Protocol.
static void EnableNpnSpdy4a2();
- // Sets http/1.1, quic, spdy/2, spdy/3, spdy/3.1, spdy/4a2, and
- // http/2 draft 04 as the protocols supported via NPN or
- // Alternate-Protocol.
+ // Sets http/1.1, quic, spdy/3, spdy/3.1, spdy/4a2, and http/2 draft
+ // 04 as the protocols supported via NPN or Alternate-Protocol.
static void EnableNpnHttp2Draft04();
// Sets the protocols supported by NPN (next protocol negotiation) during the
@@ -298,8 +298,13 @@ class NET_EXPORT HttpStreamFactory {
HttpStreamFactory();
private:
+ // |protocol| must be a valid protocol value.
+ static bool IsProtocolEnabled(AlternateProtocol protocol);
+ static void SetProtocolEnabled(AlternateProtocol protocol);
+ static void ResetEnabledProtocols();
+
static std::vector<std::string>* next_protos_;
- static bool enabled_protocols_[NUM_ALTERNATE_PROTOCOLS];
+ static bool enabled_protocols_[NUM_VALID_ALTERNATE_PROTOCOLS];
static bool spdy_enabled_;
static bool use_alternate_protocols_;
static bool force_spdy_over_ssl_;
diff --git a/chromium/net/http/http_stream_factory_impl.cc b/chromium/net/http/http_stream_factory_impl.cc
index 35d94d779f8..056a0f6b879 100644
--- a/chromium/net/http/http_stream_factory_impl.cc
+++ b/chromium/net/http/http_stream_factory_impl.cc
@@ -82,22 +82,22 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStream(
net_log);
}
-HttpStreamRequest* HttpStreamFactoryImpl::RequestWebSocketStream(
+HttpStreamRequest* HttpStreamFactoryImpl::RequestWebSocketHandshakeStream(
const HttpRequestInfo& request_info,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* factory,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) {
DCHECK(for_websockets_);
- DCHECK(factory);
+ DCHECK(create_helper);
return RequestStreamInternal(request_info,
priority,
server_ssl_config,
proxy_ssl_config,
delegate,
- factory,
+ create_helper,
net_log);
}
@@ -107,12 +107,13 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal(
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* websocket_stream_factory,
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper,
const BoundNetLog& net_log) {
Request* request = new Request(request_info.url,
this,
delegate,
- websocket_stream_factory,
+ websocket_handshake_stream_create_helper,
net_log);
GURL alternate_url;
@@ -207,11 +208,10 @@ PortAlternateProtocolPair HttpStreamFactoryImpl::GetAlternateProtocolRequestFor(
if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN)
return kNoAlternateProtocol;
- DCHECK_LE(NPN_SPDY_1, alternate.protocol);
- DCHECK_GT(NUM_ALTERNATE_PROTOCOLS, alternate.protocol);
-
- if (alternate.protocol < NPN_SPDY_2)
+ if (!IsAlternateProtocolValid(alternate.protocol)) {
+ NOTREACHED();
return kNoAlternateProtocol;
+ }
// Some shared unix systems may have user home directories (like
// http://foo.com/~mike) which allow users to emit headers. This is a bad
@@ -290,15 +290,15 @@ void HttpStreamFactoryImpl::OnNewSpdySessionReady(
using_spdy,
net_log);
if (for_websockets_) {
- WebSocketStreamBase::Factory* factory =
- request->websocket_stream_factory();
- DCHECK(factory);
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper =
+ request->websocket_handshake_stream_create_helper();
+ DCHECK(create_helper);
bool use_relative_url = direct || request->url().SchemeIs("wss");
- request->OnWebSocketStreamReady(
+ request->OnWebSocketHandshakeStreamReady(
NULL,
used_ssl_config,
used_proxy_info,
- factory->CreateSpdyStream(spdy_session, use_relative_url));
+ create_helper->CreateSpdyStream(spdy_session, use_relative_url));
} else {
bool use_relative_url = direct || request->url().SchemeIs("https");
request->OnStreamReady(
diff --git a/chromium/net/http/http_stream_factory_impl.h b/chromium/net/http/http_stream_factory_impl.h
index 4339fd350d7..4824dece14f 100644
--- a/chromium/net/http/http_stream_factory_impl.h
+++ b/chromium/net/http/http_stream_factory_impl.h
@@ -30,7 +30,8 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl :
public HttpPipelinedHostPool::Delegate {
public:
// RequestStream may only be called if |for_websockets| is false.
- // RequestWebSocketStream may only be called if |for_websockets| is true.
+ // RequestWebSocketHandshakeStream may only be called if |for_websockets|
+ // is true.
HttpStreamFactoryImpl(HttpNetworkSession* session, bool for_websockets);
virtual ~HttpStreamFactoryImpl();
@@ -43,13 +44,13 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl :
HttpStreamRequest::Delegate* delegate,
const BoundNetLog& net_log) OVERRIDE;
- virtual HttpStreamRequest* RequestWebSocketStream(
+ virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
const HttpRequestInfo& info,
RequestPriority priority,
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* factory,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log) OVERRIDE;
virtual void PreconnectStreams(int num_streams,
@@ -84,7 +85,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl :
const SSLConfig& server_ssl_config,
const SSLConfig& proxy_ssl_config,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* factory,
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper,
const BoundNetLog& net_log);
PortAlternateProtocolPair GetAlternateProtocolRequestFor(
diff --git a/chromium/net/http/http_stream_factory_impl_job.cc b/chromium/net/http/http_stream_factory_impl_job.cc
index c0383f4772d..c86bee7495b 100644
--- a/chromium/net/http/http_stream_factory_impl_job.cc
+++ b/chromium/net/http/http_stream_factory_impl_job.cc
@@ -52,7 +52,7 @@ base::Value* NetLogHttpStreamJobCallback(const GURL* original_url,
base::DictionaryValue* dict = new base::DictionaryValue();
dict->SetString("original_url", original_url->GetOrigin().spec());
dict->SetString("url", url->GetOrigin().spec());
- dict->SetInteger("priority", priority);
+ dict->SetString("priority", RequestPriorityToString(priority));
return dict;
}
@@ -221,9 +221,9 @@ void HttpStreamFactoryImpl::Job::Orphan(const Request* request) {
connection_->socket()->Disconnect();
stream_factory_->OnOrphanedJobComplete(this);
} else if (stream_factory_->for_websockets_) {
- // We cancel this job because WebSocketStream can't be created
- // without a WebSocketStreamBase::Factory which is stored in Request class
- // and isn't accessible from this job.
+ // We cancel this job because a WebSocketHandshakeStream can't be created
+ // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in
+ // the Request class and isn't accessible from this job.
if (connection_ && connection_->socket())
connection_->socket()->Disconnect();
stream_factory_->OnOrphanedJobComplete(this);
@@ -314,7 +314,7 @@ void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
// |this| may be deleted after this call.
}
-void HttpStreamFactoryImpl::Job::OnWebSocketStreamReadyCallback() {
+void HttpStreamFactoryImpl::Job::OnWebSocketHandshakeStreamReadyCallback() {
DCHECK(websocket_stream_);
DCHECK(!IsPreconnecting());
DCHECK(stream_factory_->for_websockets_);
@@ -325,10 +325,10 @@ void HttpStreamFactoryImpl::Job::OnWebSocketStreamReadyCallback() {
protocol_negotiated(),
using_spdy(),
net_log_);
- request_->OnWebSocketStreamReady(this,
- server_ssl_config_,
- proxy_info_,
- websocket_stream_.release());
+ request_->OnWebSocketHandshakeStreamReady(this,
+ server_ssl_config_,
+ proxy_info_,
+ websocket_stream_.release());
// |this| may be deleted after this call.
}
@@ -532,9 +532,8 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) {
DCHECK(websocket_stream_);
base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(
- &Job::OnWebSocketStreamReadyCallback,
- ptr_factory_.GetWeakPtr()));
+ base::Bind(&Job::OnWebSocketHandshakeStreamReadyCallback,
+ ptr_factory_.GetWeakPtr()));
} else {
DCHECK(stream_.get());
base::MessageLoop::current()->PostTask(
@@ -1065,10 +1064,10 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
CHECK(stream_.get());
} else if (stream_factory_->for_websockets_) {
DCHECK(request_);
- DCHECK(request_->websocket_stream_factory());
+ DCHECK(request_->websocket_handshake_stream_create_helper());
websocket_stream_.reset(
- request_->websocket_stream_factory()->CreateBasicStream(
- connection_.release(), using_proxy));
+ request_->websocket_handshake_stream_create_helper()
+ ->CreateBasicStream(connection_.Pass(), using_proxy));
} else if (!using_proxy && IsRequestEligibleForPipelining()) {
// TODO(simonjam): Support proxies.
stream_.reset(
@@ -1082,8 +1081,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
protocol_negotiated_));
CHECK(stream_.get());
} else {
- stream_.reset(new HttpBasicStream(connection_.release(), NULL,
- using_proxy));
+ stream_.reset(new HttpBasicStream(connection_.release(), using_proxy));
}
return OK;
}
@@ -1143,10 +1141,10 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
if (stream_factory_->for_websockets_) {
DCHECK(request_);
- DCHECK(request_->websocket_stream_factory());
+ DCHECK(request_->websocket_handshake_stream_create_helper());
bool use_relative_url = direct || request_info_.url.SchemeIs("wss");
websocket_stream_.reset(
- request_->websocket_stream_factory()->CreateSpdyStream(
+ request_->websocket_handshake_stream_create_helper()->CreateSpdyStream(
spdy_session, use_relative_url));
} else {
bool use_relative_url = direct || request_info_.url.SchemeIs("https");
diff --git a/chromium/net/http/http_stream_factory_impl_job.h b/chromium/net/http/http_stream_factory_impl_job.h
index 01a794a1bc7..1970b5be08b 100644
--- a/chromium/net/http/http_stream_factory_impl_job.h
+++ b/chromium/net/http/http_stream_factory_impl_job.h
@@ -130,7 +130,7 @@ class HttpStreamFactoryImpl::Job {
};
void OnStreamReadyCallback();
- void OnWebSocketStreamReadyCallback();
+ void OnWebSocketHandshakeStreamReadyCallback();
// This callback function is called when a new SPDY session is created.
void OnNewSpdySessionReadyCallback();
void OnStreamFailedCallback(int result);
@@ -297,7 +297,7 @@ class HttpStreamFactoryImpl::Job {
bool establishing_tunnel_;
scoped_ptr<HttpStream> stream_;
- scoped_ptr<WebSocketStreamBase> websocket_stream_;
+ scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
// True if we negotiated NPN.
bool was_npn_negotiated_;
diff --git a/chromium/net/http/http_stream_factory_impl_request.cc b/chromium/net/http/http_stream_factory_impl_request.cc
index 57190ed72e7..d731d414b71 100644
--- a/chromium/net/http/http_stream_factory_impl_request.cc
+++ b/chromium/net/http/http_stream_factory_impl_request.cc
@@ -17,11 +17,13 @@ HttpStreamFactoryImpl::Request::Request(
const GURL& url,
HttpStreamFactoryImpl* factory,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* websocket_stream_factory,
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper,
const BoundNetLog& net_log)
: url_(url),
factory_(factory),
- websocket_stream_factory_(websocket_stream_factory),
+ websocket_handshake_stream_create_helper_(
+ websocket_handshake_stream_create_helper),
delegate_(delegate),
net_log_(net_log),
completed_(false),
@@ -110,17 +112,18 @@ void HttpStreamFactoryImpl::Request::OnStreamReady(
delegate_->OnStreamReady(used_ssl_config, used_proxy_info, stream);
}
-void HttpStreamFactoryImpl::Request::OnWebSocketStreamReady(
+void HttpStreamFactoryImpl::Request::OnWebSocketHandshakeStreamReady(
Job* job,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) {
+ WebSocketHandshakeStreamBase* stream) {
DCHECK(factory_->for_websockets_);
DCHECK(stream);
DCHECK(completed_);
OnJobSucceeded(job);
- delegate_->OnWebSocketStreamReady(used_ssl_config, used_proxy_info, stream);
+ delegate_->OnWebSocketHandshakeStreamReady(
+ used_ssl_config, used_proxy_info, stream);
}
void HttpStreamFactoryImpl::Request::OnStreamFailed(
@@ -315,13 +318,13 @@ void HttpStreamFactoryImpl::Request::OnNewSpdySessionReady(
// Cache this so we can still use it if the request is deleted.
HttpStreamFactoryImpl* factory = factory_;
if (factory->for_websockets_) {
- DCHECK(websocket_stream_factory_);
+ DCHECK(websocket_handshake_stream_create_helper_);
bool use_relative_url = direct || url().SchemeIs("wss");
- delegate_->OnWebSocketStreamReady(
+ delegate_->OnWebSocketHandshakeStreamReady(
job->server_ssl_config(),
job->proxy_info(),
- websocket_stream_factory_->CreateSpdyStream(spdy_session,
- use_relative_url));
+ websocket_handshake_stream_create_helper_->CreateSpdyStream(
+ spdy_session, use_relative_url));
} else {
bool use_relative_url = direct || url().SchemeIs("https");
delegate_->OnStreamReady(
diff --git a/chromium/net/http/http_stream_factory_impl_request.h b/chromium/net/http/http_stream_factory_impl_request.h
index d6f9b02cbef..3d3b2c8bd63 100644
--- a/chromium/net/http/http_stream_factory_impl_request.h
+++ b/chromium/net/http/http_stream_factory_impl_request.h
@@ -23,7 +23,8 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
Request(const GURL& url,
HttpStreamFactoryImpl* factory,
HttpStreamRequest::Delegate* delegate,
- WebSocketStreamBase::Factory* websocket_stream_factory,
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper,
const BoundNetLog& net_log);
virtual ~Request();
@@ -66,8 +67,9 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
const base::WeakPtr<SpdySession>& spdy_session,
bool direct);
- WebSocketStreamBase::Factory* websocket_stream_factory() {
- return websocket_stream_factory_;
+ WebSocketHandshakeStreamBase::CreateHelper*
+ websocket_handshake_stream_create_helper() {
+ return websocket_handshake_stream_create_helper_;
}
// HttpStreamRequest::Delegate methods which we implement. Note we don't
@@ -77,10 +79,10 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStreamBase* stream);
- void OnWebSocketStreamReady(Job* job,
- const SSLConfig& used_ssl_config,
- const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream);
+ void OnWebSocketHandshakeStreamReady(Job* job,
+ const SSLConfig& used_ssl_config,
+ const ProxyInfo& used_proxy_info,
+ WebSocketHandshakeStreamBase* stream);
void OnStreamFailed(Job* job, int status, const SSLConfig& used_ssl_config);
void OnCertificateError(Job* job,
int status,
@@ -124,7 +126,8 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
const GURL url_;
HttpStreamFactoryImpl* const factory_;
- WebSocketStreamBase::Factory* const websocket_stream_factory_;
+ WebSocketHandshakeStreamBase::CreateHelper* const
+ websocket_handshake_stream_create_helper_;
HttpStreamRequest::Delegate* const delegate_;
const BoundNetLog net_log_;
diff --git a/chromium/net/http/http_stream_factory_impl_request_unittest.cc b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
index 1f38a2e56f6..b3b12bfa5a3 100644
--- a/chromium/net/http/http_stream_factory_impl_request_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_request_unittest.cc
@@ -19,7 +19,8 @@ class HttpStreamFactoryImplRequestTest
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpStreamFactoryImplRequestTest,
- testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
+ testing::Values(kProtoDeprecatedSPDY2,
+ kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
kProtoHTTP2Draft04));
namespace {
@@ -35,10 +36,10 @@ class DoNothingRequestDelegate : public HttpStreamRequest::Delegate {
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
HttpStreamBase* stream) OVERRIDE {}
- virtual void OnWebSocketStreamReady(
+ virtual void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) OVERRIDE {}
+ WebSocketHandshakeStreamBase* stream) OVERRIDE {}
virtual void OnStreamFailed(
int status,
const SSLConfig& used_ssl_config) OVERRIDE {}
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc
index f378c93ea18..e3169b65993 100644
--- a/chromium/net/http/http_stream_factory_impl_unittest.cc
+++ b/chromium/net/http/http_stream_factory_impl_unittest.cc
@@ -36,7 +36,7 @@
// This file can be included from net/http even though
// it is in net/websockets because it doesn't
// introduce any link dependency to net/websockets.
-#include "net/websockets/websocket_stream_base.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -57,23 +57,66 @@ class UseAlternateProtocolsScopedSetter {
bool use_alternate_protocols_;
};
-class MockWebSocketStream : public WebSocketStreamBase {
+class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
public:
enum StreamType {
kStreamTypeBasic,
kStreamTypeSpdy,
};
- explicit MockWebSocketStream(StreamType type) : type_(type) {}
+ explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {}
- virtual ~MockWebSocketStream() {}
-
- virtual WebSocketStream* AsWebSocketStream() OVERRIDE { return NULL; }
+ virtual ~MockWebSocketHandshakeStream() {}
StreamType type() const {
return type_;
}
+ // HttpStreamBase methods
+ virtual int InitializeStream(const HttpRequestInfo* request_info,
+ RequestPriority priority,
+ const BoundNetLog& net_log,
+ const CompletionCallback& callback) OVERRIDE {
+ return ERR_IO_PENDING;
+ }
+ virtual int SendRequest(const HttpRequestHeaders& request_headers,
+ HttpResponseInfo* response,
+ const CompletionCallback& callback) OVERRIDE {
+ return ERR_IO_PENDING;
+ }
+ virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
+ return ERR_IO_PENDING;
+ }
+ virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
+ return NULL;
+ }
+ virtual int ReadResponseBody(IOBuffer* buf,
+ int buf_len,
+ const CompletionCallback& callback) OVERRIDE {
+ return ERR_IO_PENDING;
+ }
+ virtual void Close(bool not_reusable) OVERRIDE {}
+ virtual bool IsResponseBodyComplete() const OVERRIDE { return false; }
+ virtual bool CanFindEndOfResponse() const OVERRIDE { return false; }
+ virtual bool IsConnectionReused() const OVERRIDE { return false; }
+ virtual void SetConnectionReused() OVERRIDE {}
+ virtual bool IsConnectionReusable() const OVERRIDE { return false; }
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; }
+ virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const
+ OVERRIDE {
+ return false;
+ }
+ virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
+ virtual void GetSSLCertRequestInfo(
+ SSLCertRequestInfo* cert_request_info) OVERRIDE {}
+ virtual bool IsSpdyHttpStream() const OVERRIDE { return false; }
+ virtual void Drain(HttpNetworkSession* session) OVERRIDE {}
+ virtual void SetPriority(RequestPriority priority) OVERRIDE {}
+
+ virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE {
+ return scoped_ptr<WebSocketStream>();
+ }
+
private:
const StreamType type_;
};
@@ -128,10 +171,10 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
used_proxy_info_ = used_proxy_info;
}
- virtual void OnWebSocketStreamReady(
+ virtual void OnWebSocketHandshakeStreamReady(
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- WebSocketStreamBase* stream) OVERRIDE {
+ WebSocketHandshakeStreamBase* stream) OVERRIDE {
stream_done_ = true;
if (waiting_for_stream_)
base::MessageLoop::current()->Quit();
@@ -182,8 +225,8 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
return stream_.get();
}
- MockWebSocketStream* websocket_stream() {
- return static_cast<MockWebSocketStream*>(websocket_stream_.get());
+ MockWebSocketHandshakeStream* websocket_stream() {
+ return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get());
}
bool stream_done() const { return stream_done_; }
@@ -192,19 +235,21 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate {
bool waiting_for_stream_;
bool stream_done_;
scoped_ptr<HttpStreamBase> stream_;
- scoped_ptr<WebSocketStreamBase> websocket_stream_;
+ scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_;
SSLConfig used_ssl_config_;
ProxyInfo used_proxy_info_;
DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter);
};
-class WebSocketSpdyStream : public MockWebSocketStream {
+class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream {
public:
- explicit WebSocketSpdyStream(const base::WeakPtr<SpdySession>& spdy_session)
- : MockWebSocketStream(kStreamTypeSpdy), spdy_session_(spdy_session) {}
+ explicit WebSocketSpdyHandshakeStream(
+ const base::WeakPtr<SpdySession>& spdy_session)
+ : MockWebSocketHandshakeStream(kStreamTypeSpdy),
+ spdy_session_(spdy_session) {}
- virtual ~WebSocketSpdyStream() {}
+ virtual ~WebSocketSpdyHandshakeStream() {}
SpdySession* spdy_session() { return spdy_session_.get(); }
@@ -212,12 +257,14 @@ class WebSocketSpdyStream : public MockWebSocketStream {
base::WeakPtr<SpdySession> spdy_session_;
};
-class WebSocketBasicStream : public MockWebSocketStream {
+class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream {
public:
- explicit WebSocketBasicStream(ClientSocketHandle* connection)
- : MockWebSocketStream(kStreamTypeBasic), connection_(connection) {}
+ explicit WebSocketBasicHandshakeStream(
+ scoped_ptr<ClientSocketHandle> connection)
+ : MockWebSocketHandshakeStream(kStreamTypeBasic),
+ connection_(connection.Pass()) {}
- virtual ~WebSocketBasicStream() {
+ virtual ~WebSocketBasicHandshakeStream() {
connection_->socket()->Disconnect();
}
@@ -227,19 +274,21 @@ class WebSocketBasicStream : public MockWebSocketStream {
scoped_ptr<ClientSocketHandle> connection_;
};
-class WebSocketStreamFactory : public WebSocketStreamBase::Factory {
+class WebSocketStreamCreateHelper
+ : public WebSocketHandshakeStreamBase::CreateHelper {
public:
- virtual ~WebSocketStreamFactory() {}
+ virtual ~WebSocketStreamCreateHelper() {}
- virtual WebSocketStreamBase* CreateBasicStream(ClientSocketHandle* connection,
- bool using_proxy) OVERRIDE {
- return new WebSocketBasicStream(connection);
+ virtual WebSocketHandshakeStreamBase* CreateBasicStream(
+ scoped_ptr<ClientSocketHandle> connection,
+ bool using_proxy) OVERRIDE {
+ return new WebSocketBasicHandshakeStream(connection.Pass());
}
- virtual WebSocketStreamBase* CreateSpdyStream(
+ virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
const base::WeakPtr<SpdySession>& spdy_session,
bool use_relative_url) OVERRIDE {
- return new WebSocketSpdyStream(spdy_session);
+ return new WebSocketSpdyHandshakeStream(spdy_session);
}
};
@@ -261,7 +310,7 @@ void PreconnectHelperForURL(int num_streams,
HttpNetworkSessionPeer peer(session);
MockHttpStreamFactoryImplForPreconnect* mock_factory =
new MockHttpStreamFactoryImplForPreconnect(session, false);
- peer.SetHttpStreamFactory(mock_factory);
+ peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory));
SSLConfig ssl_config;
session->ssl_config_service()->GetSSLConfig(&ssl_config);
@@ -376,6 +425,7 @@ CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool(
cert_verifier,
NULL,
NULL,
+ NULL,
std::string(),
NULL,
NULL,
@@ -392,7 +442,8 @@ class HttpStreamFactoryTest : public ::testing::Test,
INSTANTIATE_TEST_CASE_P(
NextProto,
HttpStreamFactoryTest,
- testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
+ testing::Values(kProtoDeprecatedSPDY2,
+ kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
kProtoHTTP2Draft04));
TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
@@ -410,11 +461,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirect) {
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -439,11 +491,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) {
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -468,11 +521,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) {
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool);
mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
PreconnectHelper(kTests[i], session.get());
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
@@ -503,11 +557,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
PreconnectHelper(kTests[i], session.get());
// We shouldn't be preconnecting if we have an existing session, which is
// the case for https://www.google.com.
@@ -534,10 +589,11 @@ TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) {
new CapturePreconnectsTransportSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- MockClientSocketPoolManager* mock_pool_manager =
- new MockClientSocketPoolManager;
+ scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
+ new MockClientSocketPoolManager);
mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
- peer.SetClientSocketPoolManager(mock_pool_manager);
+ peer.SetClientSocketPoolManager(
+ mock_pool_manager.PassAs<ClientSocketPoolManager>());
PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get());
@@ -864,7 +920,7 @@ TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) {
EXPECT_FALSE(waiter.used_proxy_info().is_direct());
}
-TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStream) {
+TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateDirect());
@@ -883,21 +939,21 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStream) {
SSLConfig ssl_config;
StreamRequestWaiter waiter;
- WebSocketStreamFactory factory;
+ WebSocketStreamCreateHelper create_helper;
scoped_ptr<HttpStreamRequest> request(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter,
+ &create_helper,
+ BoundNetLog()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(NULL == waiter.stream());
ASSERT_TRUE(NULL != waiter.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
waiter.websocket_stream()->type());
EXPECT_EQ(0, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
@@ -911,7 +967,7 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStream) {
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
}
-TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverSSL) {
+TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateDirect());
@@ -934,21 +990,21 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverSSL) {
SSLConfig ssl_config;
StreamRequestWaiter waiter;
- WebSocketStreamFactory factory;
+ WebSocketStreamCreateHelper create_helper;
scoped_ptr<HttpStreamRequest> request(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter,
+ &create_helper,
+ BoundNetLog()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(NULL == waiter.stream());
ASSERT_TRUE(NULL != waiter.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
waiter.websocket_stream()->type());
EXPECT_EQ(0, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
@@ -962,7 +1018,7 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverSSL) {
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
}
-TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverProxy) {
+TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) {
SpdySessionDependencies session_deps(
GetParam(), ProxyService::CreateFixed("myproxy:8888"));
@@ -982,21 +1038,21 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverProxy) {
SSLConfig ssl_config;
StreamRequestWaiter waiter;
- WebSocketStreamFactory factory;
+ WebSocketStreamCreateHelper create_helper;
scoped_ptr<HttpStreamRequest> request(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter,
+ &create_helper,
+ BoundNetLog()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(NULL == waiter.stream());
ASSERT_TRUE(NULL != waiter.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic,
waiter.websocket_stream()->type());
EXPECT_EQ(0, GetSocketPoolGroupCount(
session->GetTransportSocketPool(
@@ -1071,7 +1127,7 @@ TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) {
EXPECT_TRUE(waiter.used_proxy_info().is_direct());
}
-TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyStream) {
+TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStream) {
SpdySessionDependencies session_deps(GetParam(),
ProxyService::CreateDirect());
@@ -1096,44 +1152,44 @@ TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyStream) {
SSLConfig ssl_config;
StreamRequestWaiter waiter1;
- WebSocketStreamFactory factory;
+ WebSocketStreamCreateHelper create_helper;
scoped_ptr<HttpStreamRequest> request1(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter1,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter1,
+ &create_helper,
+ BoundNetLog()));
waiter1.WaitForStream();
EXPECT_TRUE(waiter1.stream_done());
ASSERT_TRUE(NULL != waiter1.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
waiter1.websocket_stream()->type());
EXPECT_TRUE(NULL == waiter1.stream());
StreamRequestWaiter waiter2;
scoped_ptr<HttpStreamRequest> request2(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter2,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter2,
+ &create_helper,
+ BoundNetLog()));
waiter2.WaitForStream();
EXPECT_TRUE(waiter2.stream_done());
ASSERT_TRUE(NULL != waiter2.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
waiter2.websocket_stream()->type());
EXPECT_TRUE(NULL == waiter2.stream());
EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream());
- EXPECT_EQ(static_cast<WebSocketSpdyStream*>(waiter2.websocket_stream())->
- spdy_session(),
- static_cast<WebSocketSpdyStream*>(waiter1.websocket_stream())->
- spdy_session());
+ EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>(
+ waiter2.websocket_stream())->spdy_session(),
+ static_cast<WebSocketSpdyHandshakeStream*>(
+ waiter1.websocket_stream())->spdy_session());
EXPECT_EQ(0, GetSocketPoolGroupCount(
session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)));
@@ -1186,21 +1242,21 @@ TEST_P(HttpStreamFactoryTest, OrphanedWebSocketStream) {
SSLConfig ssl_config;
StreamRequestWaiter waiter;
- WebSocketStreamFactory factory;
+ WebSocketStreamCreateHelper create_helper;
scoped_ptr<HttpStreamRequest> request(
- session->websocket_stream_factory()->RequestWebSocketStream(
- request_info,
- DEFAULT_PRIORITY,
- ssl_config,
- ssl_config,
- &waiter,
- &factory,
- BoundNetLog()));
+ session->http_stream_factory_for_websocket()
+ ->RequestWebSocketHandshakeStream(request_info,
+ DEFAULT_PRIORITY,
+ ssl_config,
+ ssl_config,
+ &waiter,
+ &create_helper,
+ BoundNetLog()));
waiter.WaitForStream();
EXPECT_TRUE(waiter.stream_done());
EXPECT_TRUE(NULL == waiter.stream());
ASSERT_TRUE(NULL != waiter.websocket_stream());
- EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy,
+ EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy,
waiter.websocket_stream()->type());
// Make sure that there was an alternative connection
@@ -1218,7 +1274,7 @@ TEST_P(HttpStreamFactoryTest, OrphanedWebSocketStream) {
// Make sure there is no orphaned job. it is already canceled.
ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>(
- session->websocket_stream_factory())->num_orphaned_jobs());
+ session->http_stream_factory_for_websocket())->num_orphaned_jobs());
}
} // namespace
diff --git a/chromium/net/http/http_stream_parser.cc b/chromium/net/http/http_stream_parser.cc
index 853414a106a..0821c848652 100644
--- a/chromium/net/http/http_stream_parser.cc
+++ b/chromium/net/http/http_stream_parser.cc
@@ -179,6 +179,7 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
read_buf_(read_buffer),
read_buf_unused_offset_(0),
response_header_start_offset_(-1),
+ received_bytes_(0),
response_body_length_(-1),
response_body_read_(0),
user_read_buf_(NULL),
@@ -693,6 +694,9 @@ int HttpStreamParser::DoReadBodyComplete(int result) {
result = ERR_CONTENT_LENGTH_MISMATCH;
}
+ if (result > 0)
+ received_bytes_ += result;
+
// Filter incoming data if appropriate. FilterBuf may return an error.
if (result > 0 && chunked_decoder_.get()) {
result = chunked_decoder_->FilterBuf(user_read_buf_->data(), result);
@@ -734,6 +738,7 @@ int HttpStreamParser::DoReadBodyComplete(int result) {
}
if (save_amount) {
+ received_bytes_ -= save_amount;
memcpy(read_buf_->StartOfBuffer(), user_read_buf_->data() + result,
save_amount);
}
@@ -788,6 +793,7 @@ int HttpStreamParser::DoParseResponseHeaders(int end_offset) {
DCHECK_EQ(0, read_buf_unused_offset_);
if (response_header_start_offset_ >= 0) {
+ received_bytes_ += end_offset;
headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(
read_buf_->StartOfBuffer(), end_offset));
} else {
diff --git a/chromium/net/http/http_stream_parser.h b/chromium/net/http/http_stream_parser.h
index 43e1514c2fe..e3690322bbd 100644
--- a/chromium/net/http/http_stream_parser.h
+++ b/chromium/net/http/http_stream_parser.h
@@ -77,6 +77,8 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
bool IsConnectionReusable() const;
+ int64 received_bytes() const { return received_bytes_; }
+
void GetSSLInfo(SSLInfo* ssl_info);
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
@@ -186,6 +188,10 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// -1 if not found yet.
int response_header_start_offset_;
+ // The amount of received data. If connection is reused then intermediate
+ // value may be bigger than final.
+ int64 received_bytes_;
+
// The parsed response headers. Owned by the caller.
HttpResponseInfo* response_;
diff --git a/chromium/net/http/http_stream_parser_unittest.cc b/chromium/net/http/http_stream_parser_unittest.cc
index 6e0053e6255..dcaf1f3e9c3 100644
--- a/chromium/net/http/http_stream_parser_unittest.cc
+++ b/chromium/net/http/http_stream_parser_unittest.cc
@@ -4,6 +4,10 @@
#include "net/http/http_stream_parser.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
@@ -19,6 +23,7 @@
#include "net/base/upload_file_element_reader.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_response_info.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_test_util.h"
@@ -27,6 +32,8 @@
namespace net {
+namespace {
+
const size_t kOutputSize = 1024; // Just large enough for this test.
// The number of bytes that can fit in a buffer of kOutputSize.
const size_t kMaxPayloadSize =
@@ -98,7 +105,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_NoBody) {
TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_EmptyBody) {
ScopedVector<UploadElementReader> element_readers;
- scoped_ptr<UploadDataStream> body(new UploadDataStream(&element_readers, 0));
+ scoped_ptr<UploadDataStream> body(
+ new UploadDataStream(element_readers.Pass(), 0));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Shouldn't be merged if upload data is empty.
ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -124,8 +132,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath temp_file_path;
- ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir.path(),
- &temp_file_path));
+ ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(),
+ &temp_file_path));
element_readers.push_back(
new UploadFileElementReader(base::MessageLoopProxy::current().get(),
@@ -135,7 +143,7 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_FileBody) {
base::Time()));
scoped_ptr<UploadDataStream> body(
- new UploadDataStream(&element_readers, 0));
+ new UploadDataStream(element_readers.Pass(), 0));
TestCompletionCallback callback;
ASSERT_EQ(ERR_IO_PENDING, body->Init(callback.callback()));
ASSERT_EQ(OK, callback.WaitForResult());
@@ -153,7 +161,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_SmallBodyInMemory) {
element_readers.push_back(new UploadBytesElementReader(
payload.data(), payload.size()));
- scoped_ptr<UploadDataStream> body(new UploadDataStream(&element_readers, 0));
+ scoped_ptr<UploadDataStream> body(
+ new UploadDataStream(element_readers.Pass(), 0));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Yes, should be merged if the in-memory body is small here.
ASSERT_TRUE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -166,7 +175,8 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) {
element_readers.push_back(new UploadBytesElementReader(
payload.data(), payload.size()));
- scoped_ptr<UploadDataStream> body(new UploadDataStream(&element_readers, 0));
+ scoped_ptr<UploadDataStream> body(
+ new UploadDataStream(element_readers.Pass(), 0));
ASSERT_EQ(OK, body->Init(CompletionCallback()));
// Shouldn't be merged if the in-memory body is large here.
ASSERT_FALSE(HttpStreamParser::ShouldMergeRequestHeadersAndBody(
@@ -419,4 +429,381 @@ TEST(HttpStreamParser, TruncatedHeaders) {
}
}
+// Confirm that on 101 response, the headers are parsed but the data that
+// follows remains in the buffer.
+TEST(HttpStreamParser, Websocket101Response) {
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, 1,
+ "HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "\r\n"
+ "a fake websocket frame"),
+ };
+
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"),
+ };
+
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ data.SetStop(2);
+
+ scoped_ptr<DeterministicMockTCPClientSocket> transport(
+ new DeterministicMockTCPClientSocket(NULL, &data));
+ data.set_delegate(transport->AsWeakPtr());
+
+ TestCompletionCallback callback;
+ int rv = transport->Connect(callback.callback());
+ rv = callback.GetResult(rv);
+ ASSERT_EQ(OK, rv);
+
+ scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle);
+ socket_handle->SetSocket(transport.PassAs<StreamSocket>());
+
+ HttpRequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL("http://localhost");
+ request_info.load_flags = LOAD_NORMAL;
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(
+ socket_handle.get(), &request_info, read_buffer.get(), BoundNetLog());
+
+ HttpRequestHeaders request_headers;
+ HttpResponseInfo response_info;
+ rv = parser.SendRequest("GET / HTTP/1.1\r\n", request_headers,
+ &response_info, callback.callback());
+ ASSERT_EQ(OK, rv);
+
+ rv = parser.ReadResponseHeaders(callback.callback());
+ EXPECT_EQ(OK, rv);
+ ASSERT_TRUE(response_info.headers.get());
+ EXPECT_EQ(101, response_info.headers->response_code());
+ EXPECT_TRUE(response_info.headers->HasHeaderValue("Connection", "Upgrade"));
+ EXPECT_TRUE(response_info.headers->HasHeaderValue("Upgrade", "websocket"));
+ EXPECT_EQ(read_buffer->capacity(), read_buffer->offset());
+ EXPECT_EQ("a fake websocket frame",
+ base::StringPiece(read_buffer->StartOfBuffer(),
+ read_buffer->capacity()));
+}
+
+// Helper class for constructing HttpStreamParser and running GET requests.
+class SimpleGetRunner {
+ public:
+ SimpleGetRunner() : read_buffer_(new GrowableIOBuffer), sequence_number_(0) {
+ writes_.push_back(MockWrite(
+ SYNCHRONOUS, sequence_number_++, "GET / HTTP/1.1\r\n\r\n"));
+ }
+
+ HttpStreamParser* parser() { return parser_.get(); }
+ GrowableIOBuffer* read_buffer() { return read_buffer_.get(); }
+ HttpResponseInfo* response_info() { return &response_info_; }
+
+ void AddInitialData(const std::string& data) {
+ int offset = read_buffer_->offset();
+ int size = data.size();
+ read_buffer_->SetCapacity(offset + size);
+ memcpy(read_buffer_->StartOfBuffer() + offset, data.data(), size);
+ read_buffer_->set_offset(offset + size);
+ }
+
+ void AddRead(const std::string& data) {
+ reads_.push_back(MockRead(SYNCHRONOUS, sequence_number_++, data.data()));
+ }
+
+ void SetupParserAndSendRequest() {
+ reads_.push_back(MockRead(SYNCHRONOUS, 0, sequence_number_++)); // EOF
+
+ socket_handle_.reset(new ClientSocketHandle);
+ data_.reset(new DeterministicSocketData(
+ &reads_.front(), reads_.size(), &writes_.front(), writes_.size()));
+ data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
+ data_->SetStop(reads_.size() + writes_.size());
+
+ transport_.reset(new DeterministicMockTCPClientSocket(NULL, data_.get()));
+ data_->set_delegate(transport_->AsWeakPtr());
+
+ TestCompletionCallback callback;
+ int rv = transport_->Connect(callback.callback());
+ rv = callback.GetResult(rv);
+ ASSERT_EQ(OK, rv);
+
+ socket_handle_->SetSocket(transport_.PassAs<StreamSocket>());
+
+ request_info_.method = "GET";
+ request_info_.url = GURL("http://localhost");
+ request_info_.load_flags = LOAD_NORMAL;
+
+ parser_.reset(new HttpStreamParser(
+ socket_handle_.get(), &request_info_, read_buffer(), BoundNetLog()));
+
+ rv = parser_->SendRequest("GET / HTTP/1.1\r\n", request_headers_,
+ &response_info_, callback.callback());
+ ASSERT_EQ(OK, rv);
+ }
+
+ void ReadHeaders() {
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser_->ReadResponseHeaders(callback.callback()));
+ }
+
+ void ReadBody(int user_buf_len, int* read_lengths) {
+ TestCompletionCallback callback;
+ scoped_refptr<IOBuffer> buffer = new IOBuffer(user_buf_len);
+ int rv;
+ int i = 0;
+ while (true) {
+ rv = parser_->ReadResponseBody(buffer, user_buf_len, callback.callback());
+ EXPECT_EQ(read_lengths[i], rv);
+ i++;
+ if (rv <= 0)
+ return;
+ }
+ }
+
+ private:
+ HttpRequestHeaders request_headers_;
+ HttpResponseInfo response_info_;
+ HttpRequestInfo request_info_;
+ scoped_refptr<GrowableIOBuffer> read_buffer_;
+ std::vector<MockRead> reads_;
+ std::vector<MockWrite> writes_;
+ scoped_ptr<ClientSocketHandle> socket_handle_;
+ scoped_ptr<DeterministicSocketData> data_;
+ scoped_ptr<DeterministicMockTCPClientSocket> transport_;
+ scoped_ptr<HttpStreamParser> parser_;
+ int sequence_number_;
+};
+
+// Test that HTTP/0.9 response size is correctly calculated.
+TEST(HttpStreamParser, ReceivedBytesNoHeaders) {
+ std::string response = "hello\r\nworld\r\n";
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(response);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ EXPECT_EQ(0, get_runner.parser()->received_bytes());
+ int response_size = response.size();
+ int read_lengths[] = {response_size, 0};
+ get_runner.ReadBody(response_size, read_lengths);
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+}
+
+// Test basic case where there is no keep-alive or extra data from the socket,
+// and the entire response is received in a single read.
+TEST(HttpStreamParser, ReceivedBytesNormal) {
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 7\r\n\r\n";
+ std::string body = "content";
+ std::string response = headers + body;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(response);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ int64 headers_size = headers.size();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ int64 response_size = response.size();
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+}
+
+// Test that bytes that represent "next" response are not counted
+// as current response "received_bytes".
+TEST(HttpStreamParser, ReceivedBytesExcludesNextResponse) {
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 8\r\n\r\n";
+ std::string body = "content8";
+ std::string response = headers + body;
+ std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO";
+ std::string data = response + next_response;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(data);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ EXPECT_EQ(39, get_runner.parser()->received_bytes());
+ int64 headers_size = headers.size();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ int64 response_size = response.size();
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+ int64 next_response_size = next_response.size();
+ EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
+}
+
+// Test that "received_bytes" calculation works fine when last read
+// contains more data than requested by user.
+// We send data in two reads:
+// 1) Headers + beginning of response
+// 2) remaining part of response + next response start
+// We setup user read buffer so it fully accepts the beginnig of response
+// body, but it is larger that remaining part of body.
+TEST(HttpStreamParser, ReceivedBytesMultiReadExcludesNextResponse) {
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 36\r\n\r\n";
+ int64 user_buf_len = 32;
+ std::string body_start = std::string(user_buf_len, '#');
+ int body_start_size = body_start.size();
+ EXPECT_EQ(user_buf_len, body_start_size);
+ std::string response_start = headers + body_start;
+ std::string body_end = "abcd";
+ std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO";
+ std::string response_end = body_end + next_response;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(response_start);
+ get_runner.AddRead(response_end);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ int64 headers_size = headers.size();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int body_end_size = body_end.size();
+ int read_lengths[] = {body_start_size, body_end_size, 0};
+ get_runner.ReadBody(body_start_size, read_lengths);
+ int64 response_size = response_start.size() + body_end_size;
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+ int64 next_response_size = next_response.size();
+ EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
+}
+
+// Test that "received_bytes" calculation works fine when there is no
+// network activity at all; that is when all data is read from read buffer.
+// In this case read buffer contains two responses. We expect that only
+// bytes that correspond to the first one are taken into account.
+TEST(HttpStreamParser, ReceivedBytesFromReadBufExcludesNextResponse) {
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 7\r\n\r\n";
+ std::string body = "content";
+ std::string response = headers + body;
+ std::string next_response = "HTTP/1.1 200 OK\r\n\r\nFOO";
+ std::string data = response + next_response;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddInitialData(data);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ int64 headers_size = headers.size();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ int64 response_size = response.size();
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+ int64 next_response_size = next_response.size();
+ EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
+}
+
+// Test calculating "received_bytes" when part of request has been already
+// loaded and placed to read buffer by previous stream parser.
+TEST(HttpStreamParser, ReceivedBytesUseReadBuf) {
+ std::string buffer = "HTTP/1.1 200 OK\r\n";
+ std::string remaining_headers = "Content-Length: 7\r\n\r\n";
+ int64 headers_size = buffer.size() + remaining_headers.size();
+ std::string body = "content";
+ std::string response = remaining_headers + body;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddInitialData(buffer);
+ get_runner.AddRead(response);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ EXPECT_EQ(headers_size + body_size, get_runner.parser()->received_bytes());
+ EXPECT_EQ(0, get_runner.read_buffer()->offset());
+}
+
+// Test the case when the resulting read_buf contains both unused bytes and
+// bytes ejected by chunked-encoding filter.
+TEST(HttpStreamParser, ReceivedBytesChunkedTransferExcludesNextResponse) {
+ std::string response = "HTTP/1.1 200 OK\r\n"
+ "Transfer-Encoding: chunked\r\n\r\n"
+ "7\r\nChunk 1\r\n"
+ "8\r\nChunky 2\r\n"
+ "6\r\nTest 3\r\n"
+ "0\r\n\r\n";
+ std::string next_response = "foo bar\r\n";
+ std::string data = response + next_response;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddInitialData(data);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ int read_lengths[] = {4, 3, 6, 2, 6, 0};
+ get_runner.ReadBody(7, read_lengths);
+ int64 response_size = response.size();
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+ int64 next_response_size = next_response.size();
+ EXPECT_EQ(next_response_size, get_runner.read_buffer()->offset());
+}
+
+// Test that data transfered in multiple reads is correctly processed.
+// We feed data into 4-bytes reads. Also we set length of read
+// buffer to 5-bytes to test all possible buffer misaligments.
+TEST(HttpStreamParser, ReceivedBytesMultipleReads) {
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 33\r\n\r\n";
+ std::string body = "foo bar baz\r\n"
+ "sputnik mir babushka";
+ std::string response = headers + body;
+
+ size_t receive_length = 4;
+ std::vector<std::string> blocks;
+ for (size_t i = 0; i < response.size(); i += receive_length) {
+ size_t length = std::min(receive_length, response.size() - i);
+ blocks.push_back(response.substr(i, length));
+ }
+
+ SimpleGetRunner get_runner;
+ for (std::vector<std::string>::size_type i = 0; i < blocks.size(); ++i)
+ get_runner.AddRead(blocks[i]);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ int64 headers_size = headers.size();
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int read_lengths[] = {1, 4, 4, 4, 4, 4, 4, 4, 4, 0};
+ get_runner.ReadBody(receive_length + 1, read_lengths);
+ int64 response_size = response.size();
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+}
+
+// Test that "continue" HTTP header is counted as "received_bytes".
+TEST(HttpStreamParser, ReceivedBytesIncludesContinueHeader) {
+ std::string status100 = "HTTP/1.1 100 OK\r\n\r\n";
+ std::string headers = "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 7\r\n\r\n";
+ int64 headers_size = status100.size() + headers.size();
+ std::string body = "content";
+ std::string response = headers + body;
+
+ SimpleGetRunner get_runner;
+ get_runner.AddRead(status100);
+ get_runner.AddRead(response);
+ get_runner.SetupParserAndSendRequest();
+ get_runner.ReadHeaders();
+ EXPECT_EQ(100, get_runner.response_info()->headers->response_code());
+ int64 status100_size = status100.size();
+ EXPECT_EQ(status100_size, get_runner.parser()->received_bytes());
+ get_runner.ReadHeaders();
+ EXPECT_EQ(200, get_runner.response_info()->headers->response_code());
+ EXPECT_EQ(headers_size, get_runner.parser()->received_bytes());
+ int64 response_size = headers_size + body.size();
+ int body_size = body.size();
+ int read_lengths[] = {body_size, 0};
+ get_runner.ReadBody(body_size, read_lengths);
+ EXPECT_EQ(response_size, get_runner.parser()->received_bytes());
+}
+
+} // namespace
+
} // namespace net
diff --git a/chromium/net/http/http_transaction.h b/chromium/net/http/http_transaction.h
index d44050080ba..849d03af50c 100644
--- a/chromium/net/http/http_transaction.h
+++ b/chromium/net/http/http_transaction.h
@@ -10,6 +10,7 @@
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/base/upload_progress.h"
+#include "net/websockets/websocket_handshake_stream_base.h"
namespace net {
@@ -134,6 +135,12 @@ class NET_EXPORT_PRIVATE HttpTransaction {
// Called when the priority of the parent job changes.
virtual void SetPriority(RequestPriority priority) = 0;
+
+ // Set the WebSocketHandshakeStreamBase::CreateHelper to be used for the
+ // request. Only relevant to WebSocket transactions. Must be called before
+ // Start(). Ownership of |create_helper| remains with the caller.
+ virtual void SetWebSocketHandshakeStreamCreateHelper(
+ WebSocketHandshakeStreamBase::CreateHelper* create_helper) = 0;
};
} // namespace net
diff --git a/chromium/net/http/http_transaction_unittest.cc b/chromium/net/http/http_transaction_unittest.cc
index 9aa81cf608e..e161ecac506 100644
--- a/chromium/net/http/http_transaction_unittest.cc
+++ b/chromium/net/http/http_transaction_unittest.cc
@@ -228,6 +228,7 @@ MockNetworkTransaction::MockNetworkTransaction(
: weak_factory_(this),
data_cursor_(0),
priority_(priority),
+ websocket_handshake_stream_create_helper_(NULL),
transaction_factory_(factory->AsWeakPtr()),
socket_log_id_(net::NetLog::Source::kInvalidId) {
}
@@ -375,6 +376,11 @@ void MockNetworkTransaction::SetPriority(net::RequestPriority priority) {
priority_ = priority;
}
+void MockNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper(
+ net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) {
+ websocket_handshake_stream_create_helper_ = create_helper;
+}
+
void MockNetworkTransaction::CallbackLater(
const net::CompletionCallback& callback, int result) {
base::MessageLoop::current()->PostTask(
diff --git a/chromium/net/http/http_transaction_unittest.h b/chromium/net/http/http_transaction_unittest.h
index 407fc9fff9a..3d6bb0287fb 100644
--- a/chromium/net/http/http_transaction_unittest.h
+++ b/chromium/net/http/http_transaction_unittest.h
@@ -162,6 +162,7 @@ class MockNetworkLayer;
class MockNetworkTransaction
: public net::HttpTransaction,
public base::SupportsWeakPtr<MockNetworkTransaction> {
+ typedef net::WebSocketHandshakeStreamBase::CreateHelper CreateHelper;
public:
MockNetworkTransaction(net::RequestPriority priority,
MockNetworkLayer* factory);
@@ -205,6 +206,12 @@ class MockNetworkTransaction
virtual void SetPriority(net::RequestPriority priority) OVERRIDE;
+ virtual void SetWebSocketHandshakeStreamCreateHelper(
+ CreateHelper* create_helper) OVERRIDE;
+
+ CreateHelper* websocket_handshake_stream_create_helper() {
+ return websocket_handshake_stream_create_helper_;
+ }
net::RequestPriority priority() const { return priority_; }
private:
@@ -217,6 +224,7 @@ class MockNetworkTransaction
int data_cursor_;
int test_mode_;
net::RequestPriority priority_;
+ CreateHelper* websocket_handshake_stream_create_helper_;
base::WeakPtr<MockNetworkLayer> transaction_factory_;
// NetLog ID of the fake / non-existent underlying socket used by the
diff --git a/chromium/net/http/http_util_icu.cc b/chromium/net/http/http_util_icu.cc
index 4f38f84d75b..88ad5906e7b 100644
--- a/chromium/net/http/http_util_icu.cc
+++ b/chromium/net/http/http_util_icu.cc
@@ -14,7 +14,8 @@ namespace net {
// static
std::string HttpUtil::PathForRequest(const GURL& url) {
- DCHECK(url.is_valid() && url.SchemeIsHTTPOrHTTPS());
+ DCHECK(url.is_valid() && (url.SchemeIsHTTPOrHTTPS() ||
+ url.SchemeIsWSOrWSS()));
if (url.has_query())
return url.path() + "?" + url.query();
return url.path();
@@ -23,8 +24,8 @@ std::string HttpUtil::PathForRequest(const GURL& url) {
// static
std::string HttpUtil::SpecForRequest(const GURL& url) {
// We may get ftp scheme when fetching ftp resources through proxy.
- DCHECK(url.is_valid() && (url.SchemeIsHTTPOrHTTPS() ||
- url.SchemeIs("ftp")));
+ DCHECK(url.is_valid() && (url.SchemeIsHTTPOrHTTPS() || url.SchemeIs("ftp") ||
+ url.SchemeIsWSOrWSS()));
return SimplifyUrlForRequest(url).spec();
}
diff --git a/chromium/net/http/http_util_unittest.cc b/chromium/net/http/http_util_unittest.cc
index fe2d8b47496..54acf68d3c3 100644
--- a/chromium/net/http/http_util_unittest.cc
+++ b/chromium/net/http/http_util_unittest.cc
@@ -612,6 +612,21 @@ TEST(HttpUtilTest, RequestUrlSanitize) {
"http://user:pass@google.com",
"http://google.com/",
"/"
+ },
+ { // https scheme
+ "https://www.google.com:78/foobar?query=1#hash",
+ "https://www.google.com:78/foobar?query=1",
+ "/foobar?query=1"
+ },
+ { // WebSocket's ws scheme
+ "ws://www.google.com:78/foobar?query=1#hash",
+ "ws://www.google.com:78/foobar?query=1",
+ "/foobar?query=1"
+ },
+ { // WebSocket's wss scheme
+ "wss://www.google.com:78/foobar?query=1#hash",
+ "wss://www.google.com:78/foobar?query=1",
+ "/foobar?query=1"
}
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
@@ -624,6 +639,13 @@ TEST(HttpUtilTest, RequestUrlSanitize) {
}
}
+// Test SpecForRequest() for "ftp" scheme.
+TEST(HttpUtilTest, SpecForRequestForUrlWithFtpScheme) {
+ GURL ftp_url("ftp://user:pass@google.com/pub/chromium/");
+ EXPECT_EQ("ftp://google.com/pub/chromium/",
+ HttpUtil::SpecForRequest(ftp_url));
+}
+
TEST(HttpUtilTest, GenerateAcceptLanguageHeader) {
EXPECT_EQ(std::string("en-US,fr;q=0.8,de;q=0.6"),
HttpUtil::GenerateAcceptLanguageHeader("en-US,fr,de"));
diff --git a/chromium/net/http/partial_data.cc b/chromium/net/http/partial_data.cc
index 02fda6cc9b1..ee3678b5ea0 100644
--- a/chromium/net/http/partial_data.cc
+++ b/chromium/net/http/partial_data.cc
@@ -25,19 +25,6 @@ const char kLengthHeader[] = "Content-Length";
const char kRangeHeader[] = "Content-Range";
const int kDataStream = 1;
-void AddRangeHeader(int64 start, int64 end, HttpRequestHeaders* headers) {
- DCHECK(start >= 0 || end >= 0);
- std::string my_start, my_end;
- if (start >= 0)
- my_start = base::Int64ToString(start);
- if (end >= 0)
- my_end = base::Int64ToString(end);
-
- headers->SetHeader(
- HttpRequestHeaders::kRange,
- base::StringPrintf("bytes=%s-%s", my_start.c_str(), my_end.c_str()));
-}
-
} // namespace
// A core object that can be detached from the Partialdata object at destruction
@@ -156,8 +143,17 @@ void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const {
byte_range_.suffix_length() : byte_range_.last_byte_position();
headers->CopyFrom(extra_headers_);
- if (!truncated_ && byte_range_.IsValid())
- AddRangeHeader(current_range_start_, end, headers);
+ if (truncated_ || !byte_range_.IsValid())
+ return;
+
+ if (current_range_start_ < 0) {
+ headers->SetHeader(HttpRequestHeaders::kRange,
+ HttpByteRange::Suffix(end).GetHeaderValue());
+ } else {
+ headers->SetHeader(HttpRequestHeaders::kRange,
+ HttpByteRange::Bounded(
+ current_range_start_, end).GetHeaderValue());
+ }
}
int PartialData::ShouldValidateCache(disk_cache::Entry* entry,
@@ -222,11 +218,17 @@ void PartialData::PrepareCacheValidation(disk_cache::Entry* entry,
range_present_ = true;
if (len == cached_min_len_)
final_range_ = true;
- AddRangeHeader(current_range_start_, cached_start_ + cached_min_len_ - 1,
- headers);
+ headers->SetHeader(
+ HttpRequestHeaders::kRange,
+ net::HttpByteRange::Bounded(
+ current_range_start_,
+ cached_start_ + cached_min_len_ - 1).GetHeaderValue());
} else {
// This range is not in the cache.
- AddRangeHeader(current_range_start_, cached_start_ - 1, headers);
+ headers->SetHeader(
+ HttpRequestHeaders::kRange,
+ net::HttpByteRange::Bounded(
+ current_range_start_, cached_start_ - 1).GetHeaderValue());
}
}
@@ -337,8 +339,12 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) {
if (total_length <= 0)
return false;
+ DCHECK_EQ(headers->response_code(), 206);
+
+ // A server should return a valid content length with a 206 (per the standard)
+ // but relax the requirement because some servers don't do that.
int64 content_length = headers->GetContentLength();
- if (content_length < 0 || content_length != end - start + 1)
+ if (content_length > 0 && content_length != end - start + 1)
return false;
if (!resource_size_) {
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.cc b/chromium/net/http/proxy_connect_redirect_http_stream.cc
index 59bb0146953..0857a7451ca 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.cc
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.cc
@@ -82,6 +82,10 @@ bool ProxyConnectRedirectHttpStream::IsConnectionReusable() const {
return false;
}
+int64 ProxyConnectRedirectHttpStream::GetTotalReceivedBytes() const {
+ return 0;
+}
+
bool ProxyConnectRedirectHttpStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
if (!has_load_timing_info_)
diff --git a/chromium/net/http/proxy_connect_redirect_http_stream.h b/chromium/net/http/proxy_connect_redirect_http_stream.h
index c335c218c71..0547654ab92 100644
--- a/chromium/net/http/proxy_connect_redirect_http_stream.h
+++ b/chromium/net/http/proxy_connect_redirect_http_stream.h
@@ -50,6 +50,8 @@ class ProxyConnectRedirectHttpStream : public HttpStream {
virtual void SetConnectionReused() OVERRIDE;
virtual bool IsConnectionReusable() const OVERRIDE;
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE;
+
// This function may be called.
virtual bool GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const OVERRIDE;
diff --git a/chromium/net/http/transport_security_persister.cc b/chromium/net/http/transport_security_persister.cc
new file mode 100644
index 00000000000..771d07dc1bc
--- /dev/null
+++ b/chromium/net/http/transport_security_persister.cc
@@ -0,0 +1,318 @@
+// 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.
+
+#include "net/http/transport_security_persister.h"
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_runner_util.h"
+#include "base/values.h"
+#include "crypto/sha2.h"
+#include "net/cert/x509_certificate.h"
+#include "net/http/transport_security_state.h"
+
+using net::HashValue;
+using net::HashValueTag;
+using net::HashValueVector;
+using net::TransportSecurityState;
+
+namespace {
+
+ListValue* SPKIHashesToListValue(const HashValueVector& hashes) {
+ ListValue* pins = new ListValue;
+ for (size_t i = 0; i != hashes.size(); i++)
+ pins->Append(new StringValue(hashes[i].ToString()));
+ return pins;
+}
+
+void SPKIHashesFromListValue(const ListValue& pins, HashValueVector* hashes) {
+ size_t num_pins = pins.GetSize();
+ for (size_t i = 0; i < num_pins; ++i) {
+ std::string type_and_base64;
+ HashValue fingerprint;
+ if (pins.GetString(i, &type_and_base64) &&
+ fingerprint.FromString(type_and_base64)) {
+ hashes->push_back(fingerprint);
+ }
+ }
+}
+
+// This function converts the binary hashes to a base64 string which we can
+// include in a JSON file.
+std::string HashedDomainToExternalString(const std::string& hashed) {
+ std::string out;
+ base::Base64Encode(hashed, &out);
+ return out;
+}
+
+// This inverts |HashedDomainToExternalString|, above. It turns an external
+// string (from a JSON file) into an internal (binary) string.
+std::string ExternalStringToHashedDomain(const std::string& external) {
+ std::string out;
+ if (!base::Base64Decode(external, &out) ||
+ out.size() != crypto::kSHA256Length) {
+ return std::string();
+ }
+
+ return out;
+}
+
+const char kIncludeSubdomains[] = "include_subdomains";
+const char kStsIncludeSubdomains[] = "sts_include_subdomains";
+const char kPkpIncludeSubdomains[] = "pkp_include_subdomains";
+const char kMode[] = "mode";
+const char kExpiry[] = "expiry";
+const char kDynamicSPKIHashesExpiry[] = "dynamic_spki_hashes_expiry";
+const char kStaticSPKIHashes[] = "static_spki_hashes";
+const char kPreloadedSPKIHashes[] = "preloaded_spki_hashes";
+const char kDynamicSPKIHashes[] = "dynamic_spki_hashes";
+const char kForceHTTPS[] = "force-https";
+const char kStrict[] = "strict";
+const char kDefault[] = "default";
+const char kPinningOnly[] = "pinning-only";
+const char kCreated[] = "created";
+
+std::string LoadState(const base::FilePath& path) {
+ std::string result;
+ if (!base::ReadFileToString(path, &result)) {
+ return "";
+ }
+ return result;
+}
+
+} // namespace
+
+
+namespace net {
+
+TransportSecurityPersister::TransportSecurityPersister(
+ TransportSecurityState* state,
+ const base::FilePath& profile_path,
+ base::SequencedTaskRunner* background_runner,
+ bool readonly)
+ : transport_security_state_(state),
+ writer_(profile_path.AppendASCII("TransportSecurity"), background_runner),
+ foreground_runner_(base::MessageLoop::current()->message_loop_proxy()),
+ background_runner_(background_runner),
+ readonly_(readonly),
+ weak_ptr_factory_(this) {
+ transport_security_state_->SetDelegate(this);
+
+ base::PostTaskAndReplyWithResult(
+ background_runner_,
+ FROM_HERE,
+ base::Bind(&::LoadState, writer_.path()),
+ base::Bind(&TransportSecurityPersister::CompleteLoad,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+TransportSecurityPersister::~TransportSecurityPersister() {
+ DCHECK(foreground_runner_->RunsTasksOnCurrentThread());
+
+ if (writer_.HasPendingWrite())
+ writer_.DoScheduledWrite();
+
+ transport_security_state_->SetDelegate(NULL);
+}
+
+void TransportSecurityPersister::StateIsDirty(
+ TransportSecurityState* state) {
+ DCHECK(foreground_runner_->RunsTasksOnCurrentThread());
+ DCHECK_EQ(transport_security_state_, state);
+
+ if (!readonly_)
+ writer_.ScheduleWrite(this);
+}
+
+bool TransportSecurityPersister::SerializeData(std::string* output) {
+ DCHECK(foreground_runner_->RunsTasksOnCurrentThread());
+
+ DictionaryValue toplevel;
+ base::Time now = base::Time::Now();
+ TransportSecurityState::Iterator state(*transport_security_state_);
+ for (; state.HasNext(); state.Advance()) {
+ const std::string& hostname = state.hostname();
+ const TransportSecurityState::DomainState& domain_state =
+ state.domain_state();
+
+ DictionaryValue* serialized = new DictionaryValue;
+ serialized->SetBoolean(kStsIncludeSubdomains,
+ domain_state.sts_include_subdomains);
+ serialized->SetBoolean(kPkpIncludeSubdomains,
+ domain_state.pkp_include_subdomains);
+ serialized->SetDouble(kCreated, domain_state.created.ToDoubleT());
+ serialized->SetDouble(kExpiry, domain_state.upgrade_expiry.ToDoubleT());
+ serialized->SetDouble(kDynamicSPKIHashesExpiry,
+ domain_state.dynamic_spki_hashes_expiry.ToDoubleT());
+
+ switch (domain_state.upgrade_mode) {
+ case TransportSecurityState::DomainState::MODE_FORCE_HTTPS:
+ serialized->SetString(kMode, kForceHTTPS);
+ break;
+ case TransportSecurityState::DomainState::MODE_DEFAULT:
+ serialized->SetString(kMode, kDefault);
+ break;
+ default:
+ NOTREACHED() << "DomainState with unknown mode";
+ delete serialized;
+ continue;
+ }
+
+ serialized->Set(kStaticSPKIHashes,
+ SPKIHashesToListValue(domain_state.static_spki_hashes));
+
+ if (now < domain_state.dynamic_spki_hashes_expiry) {
+ serialized->Set(kDynamicSPKIHashes,
+ SPKIHashesToListValue(domain_state.dynamic_spki_hashes));
+ }
+
+ toplevel.Set(HashedDomainToExternalString(hostname), serialized);
+ }
+
+ base::JSONWriter::WriteWithOptions(&toplevel,
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ output);
+ return true;
+}
+
+bool TransportSecurityPersister::LoadEntries(const std::string& serialized,
+ bool* dirty) {
+ DCHECK(foreground_runner_->RunsTasksOnCurrentThread());
+
+ transport_security_state_->ClearDynamicData();
+ return Deserialize(serialized, dirty, transport_security_state_);
+}
+
+// static
+bool TransportSecurityPersister::Deserialize(const std::string& serialized,
+ bool* dirty,
+ TransportSecurityState* state) {
+ scoped_ptr<Value> value(base::JSONReader::Read(serialized));
+ DictionaryValue* dict_value = NULL;
+ if (!value.get() || !value->GetAsDictionary(&dict_value))
+ return false;
+
+ const base::Time current_time(base::Time::Now());
+ bool dirtied = false;
+
+ for (DictionaryValue::Iterator i(*dict_value); !i.IsAtEnd(); i.Advance()) {
+ const DictionaryValue* parsed = NULL;
+ if (!i.value().GetAsDictionary(&parsed)) {
+ LOG(WARNING) << "Could not parse entry " << i.key() << "; skipping entry";
+ continue;
+ }
+
+ std::string mode_string;
+ double created;
+ double expiry;
+ double dynamic_spki_hashes_expiry = 0.0;
+ TransportSecurityState::DomainState domain_state;
+
+ // kIncludeSubdomains is a legacy synonym for kStsIncludeSubdomains and
+ // kPkpIncludeSubdomains. Parse at least one of these properties,
+ // preferably the new ones.
+ bool include_subdomains = false;
+ bool parsed_include_subdomains = parsed->GetBoolean(kIncludeSubdomains,
+ &include_subdomains);
+ domain_state.sts_include_subdomains = include_subdomains;
+ domain_state.pkp_include_subdomains = include_subdomains;
+ if (parsed->GetBoolean(kStsIncludeSubdomains, &include_subdomains)) {
+ domain_state.sts_include_subdomains = include_subdomains;
+ parsed_include_subdomains = true;
+ }
+ if (parsed->GetBoolean(kPkpIncludeSubdomains, &include_subdomains)) {
+ domain_state.pkp_include_subdomains = include_subdomains;
+ parsed_include_subdomains = true;
+ }
+
+ if (!parsed_include_subdomains ||
+ !parsed->GetString(kMode, &mode_string) ||
+ !parsed->GetDouble(kExpiry, &expiry)) {
+ LOG(WARNING) << "Could not parse some elements of entry " << i.key()
+ << "; skipping entry";
+ continue;
+ }
+
+ // Don't fail if this key is not present.
+ parsed->GetDouble(kDynamicSPKIHashesExpiry,
+ &dynamic_spki_hashes_expiry);
+
+ const ListValue* pins_list = NULL;
+ // preloaded_spki_hashes is a legacy synonym for static_spki_hashes.
+ if (parsed->GetList(kStaticSPKIHashes, &pins_list))
+ SPKIHashesFromListValue(*pins_list, &domain_state.static_spki_hashes);
+ else if (parsed->GetList(kPreloadedSPKIHashes, &pins_list))
+ SPKIHashesFromListValue(*pins_list, &domain_state.static_spki_hashes);
+
+ if (parsed->GetList(kDynamicSPKIHashes, &pins_list))
+ SPKIHashesFromListValue(*pins_list, &domain_state.dynamic_spki_hashes);
+
+ if (mode_string == kForceHTTPS || mode_string == kStrict) {
+ domain_state.upgrade_mode =
+ TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
+ } else if (mode_string == kDefault || mode_string == kPinningOnly) {
+ domain_state.upgrade_mode =
+ TransportSecurityState::DomainState::MODE_DEFAULT;
+ } else {
+ LOG(WARNING) << "Unknown TransportSecurityState mode string "
+ << mode_string << " found for entry " << i.key()
+ << "; skipping entry";
+ continue;
+ }
+
+ domain_state.upgrade_expiry = base::Time::FromDoubleT(expiry);
+ domain_state.dynamic_spki_hashes_expiry =
+ base::Time::FromDoubleT(dynamic_spki_hashes_expiry);
+ if (parsed->GetDouble(kCreated, &created)) {
+ domain_state.created = base::Time::FromDoubleT(created);
+ } else {
+ // We're migrating an old entry with no creation date. Make sure we
+ // write the new date back in a reasonable time frame.
+ dirtied = true;
+ domain_state.created = base::Time::Now();
+ }
+
+ if (domain_state.upgrade_expiry <= current_time &&
+ domain_state.dynamic_spki_hashes_expiry <= current_time) {
+ // Make sure we dirty the state if we drop an entry.
+ dirtied = true;
+ continue;
+ }
+
+ std::string hashed = ExternalStringToHashedDomain(i.key());
+ if (hashed.empty()) {
+ dirtied = true;
+ continue;
+ }
+
+ state->AddOrUpdateEnabledHosts(hashed, domain_state);
+ }
+
+ *dirty = dirtied;
+ return true;
+}
+
+void TransportSecurityPersister::CompleteLoad(const std::string& state) {
+ DCHECK(foreground_runner_->RunsTasksOnCurrentThread());
+
+ if (state.empty())
+ return;
+
+ bool dirty = false;
+ if (!LoadEntries(state, &dirty)) {
+ LOG(ERROR) << "Failed to deserialize state: " << state;
+ return;
+ }
+ if (dirty)
+ StateIsDirty(transport_security_state_);
+}
+
+} // namespace net
diff --git a/chromium/net/http/transport_security_persister.h b/chromium/net/http/transport_security_persister.h
new file mode 100644
index 00000000000..7725ba124e6
--- /dev/null
+++ b/chromium/net/http/transport_security_persister.h
@@ -0,0 +1,138 @@
+// 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.
+
+// TransportSecurityState maintains an in memory database containing the
+// list of hosts that currently have transport security enabled. This
+// singleton object deals with writing that data out to disk as needed and
+// loading it at startup.
+
+// At startup we need to load the transport security state from the
+// disk. For the moment, we don't want to delay startup for this load, so we
+// let the TransportSecurityState run for a while without being loaded.
+// This means that it's possible for pages opened very quickly not to get the
+// correct transport security information.
+//
+// To load the state, we schedule a Task on file_task_runner, which
+// deserializes and configures the TransportSecurityState.
+//
+// The TransportSecurityState object supports running a callback function
+// when it changes. This object registers the callback, pointing at itself.
+//
+// TransportSecurityState calls...
+// TransportSecurityPersister::StateIsDirty
+// since the callback isn't allowed to block or reenter, we schedule a Task
+// on the file task runner after some small amount of time
+//
+// ...
+//
+// TransportSecurityPersister::SerializeState
+// copies the current state of the TransportSecurityState, serializes
+// and writes to disk.
+
+#ifndef NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
+#define NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/files/important_file_writer.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "net/base/net_export.h"
+#include "net/http/transport_security_state.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace net {
+
+// Reads and updates on-disk TransportSecurity state. Clients of this class
+// should create, destroy, and call into it from one thread.
+//
+// file_task_runner is the task runner this class should use internally to
+// perform file IO, and can optionally be associated with a different thread.
+class NET_EXPORT TransportSecurityPersister
+ : public TransportSecurityState::Delegate,
+ public base::ImportantFileWriter::DataSerializer {
+ public:
+ TransportSecurityPersister(TransportSecurityState* state,
+ const base::FilePath& profile_path,
+ base::SequencedTaskRunner* file_task_runner,
+ bool readonly);
+ virtual ~TransportSecurityPersister();
+
+ // Called by the TransportSecurityState when it changes its state.
+ virtual void StateIsDirty(TransportSecurityState*) OVERRIDE;
+
+ // ImportantFileWriter::DataSerializer:
+ //
+ // Serializes |transport_security_state_| into |*output|. Returns true if
+ // all DomainStates were serialized correctly.
+ //
+ // The serialization format is JSON; the JSON represents a dictionary of
+ // host:DomainState pairs (host is a string). The DomainState is
+ // represented as a dictionary containing the following keys and value
+ // types (not all keys will always be present):
+ //
+ // "sts_include_subdomains": true|false
+ // "pkp_include_subdomains": true|false
+ // "created": double
+ // "expiry": double
+ // "dynamic_spki_hashes_expiry": double
+ // "mode": "default"|"force-https"
+ // legacy value synonyms "strict" = "force-https"
+ // "pinning-only" = "default"
+ // legacy value "spdy-only" is unused and ignored
+ // "static_spki_hashes": list of strings
+ // legacy key synonym "preloaded_spki_hashes"
+ // "bad_static_spki_hashes": list of strings
+ // legacy key synonym "bad_preloaded_spki_hashes"
+ // "dynamic_spki_hashes": list of strings
+ //
+ // The JSON dictionary keys are strings containing
+ // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))).
+ // The reason for hashing them is so that the stored state does not
+ // trivially reveal a user's browsing history to an attacker reading the
+ // serialized state on disk.
+ virtual bool SerializeData(std::string* data) OVERRIDE;
+
+ // Clears any existing non-static entries, and then re-populates
+ // |transport_security_state_|.
+ //
+ // Sets |*dirty| to true if the new state differs from the persisted
+ // state; false otherwise.
+ bool LoadEntries(const std::string& serialized, bool* dirty);
+
+ private:
+ // Populates |state| from the JSON string |serialized|. Returns true if
+ // all entries were parsed and deserialized correctly.
+ //
+ // Sets |*dirty| to true if the new state differs from the persisted
+ // state; false otherwise.
+ static bool Deserialize(const std::string& serialized,
+ bool* dirty,
+ TransportSecurityState* state);
+
+ void CompleteLoad(const std::string& state);
+
+ TransportSecurityState* transport_security_state_;
+
+ // Helper for safely writing the data.
+ base::ImportantFileWriter writer_;
+
+ scoped_refptr<base::SequencedTaskRunner> foreground_runner_;
+ scoped_refptr<base::SequencedTaskRunner> background_runner_;
+
+ // Whether or not we're in read-only mode.
+ const bool readonly_;
+
+ base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportSecurityPersister);
+};
+
+} // namespace net
+
+#endif // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
diff --git a/chromium/net/http/transport_security_persister_unittest.cc b/chromium/net/http/transport_security_persister_unittest.cc
new file mode 100644
index 00000000000..8c41f9e81da
--- /dev/null
+++ b/chromium/net/http/transport_security_persister_unittest.cc
@@ -0,0 +1,201 @@
+// 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.
+
+#include "net/http/transport_security_persister.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop/message_loop.h"
+#include "net/http/transport_security_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using net::TransportSecurityPersister;
+using net::TransportSecurityState;
+
+class TransportSecurityPersisterTest : public testing::Test {
+ public:
+ TransportSecurityPersisterTest() {
+ }
+
+ virtual ~TransportSecurityPersisterTest() {
+ base::MessageLoopForIO::current()->RunUntilIdle();
+ }
+
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ persister_.reset(new TransportSecurityPersister(
+ &state_,
+ temp_dir_.path(),
+ base::MessageLoopForIO::current()->message_loop_proxy(),
+ false));
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ TransportSecurityState state_;
+ scoped_ptr<TransportSecurityPersister> persister_;
+};
+
+TEST_F(TransportSecurityPersisterTest, SerializeData1) {
+ std::string output;
+ bool dirty;
+
+ EXPECT_TRUE(persister_->SerializeData(&output));
+ EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
+ EXPECT_FALSE(dirty);
+}
+
+TEST_F(TransportSecurityPersisterTest, SerializeData2) {
+ TransportSecurityState::DomainState domain_state;
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ static const char kYahooDomain[] = "yahoo.com";
+
+ EXPECT_FALSE(state_.GetDomainState(kYahooDomain, true, &domain_state));
+
+ bool include_subdomains = true;
+ state_.AddHSTS(kYahooDomain, expiry, include_subdomains);
+
+ std::string output;
+ bool dirty;
+ EXPECT_TRUE(persister_->SerializeData(&output));
+ EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
+
+ EXPECT_TRUE(state_.GetDomainState(kYahooDomain, true, &domain_state));
+ EXPECT_EQ(domain_state.upgrade_mode,
+ TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
+ EXPECT_TRUE(state_.GetDomainState("foo.yahoo.com", true, &domain_state));
+ EXPECT_EQ(domain_state.upgrade_mode,
+ TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
+ EXPECT_TRUE(state_.GetDomainState("foo.bar.yahoo.com", true, &domain_state));
+ EXPECT_EQ(domain_state.upgrade_mode,
+ TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
+ EXPECT_TRUE(state_.GetDomainState("foo.bar.baz.yahoo.com", true,
+ &domain_state));
+ EXPECT_EQ(domain_state.upgrade_mode,
+ TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
+ EXPECT_FALSE(state_.GetDomainState("com", true, &domain_state));
+}
+
+TEST_F(TransportSecurityPersisterTest, SerializeData3) {
+ // Add an entry.
+ net::HashValue fp1(net::HASH_VALUE_SHA1);
+ memset(fp1.data(), 0, fp1.size());
+ net::HashValue fp2(net::HASH_VALUE_SHA1);
+ memset(fp2.data(), 1, fp2.size());
+ base::Time expiry =
+ base::Time::Now() + base::TimeDelta::FromSeconds(1000);
+ net::HashValueVector dynamic_spki_hashes;
+ dynamic_spki_hashes.push_back(fp1);
+ dynamic_spki_hashes.push_back(fp2);
+ bool include_subdomains = false;
+ state_.AddHSTS("www.example.com", expiry, include_subdomains);
+ state_.AddHPKP("www.example.com", expiry, include_subdomains,
+ dynamic_spki_hashes);
+
+ // Add another entry.
+ memset(fp1.data(), 2, fp1.size());
+ memset(fp2.data(), 3, fp2.size());
+ expiry =
+ base::Time::Now() + base::TimeDelta::FromSeconds(3000);
+ dynamic_spki_hashes.push_back(fp1);
+ dynamic_spki_hashes.push_back(fp2);
+ state_.AddHSTS("www.example.net", expiry, include_subdomains);
+ state_.AddHPKP("www.example.net", expiry, include_subdomains,
+ dynamic_spki_hashes);
+
+ // Save a copy of everything.
+ std::map<std::string, TransportSecurityState::DomainState> saved;
+ TransportSecurityState::Iterator i(state_);
+ while (i.HasNext()) {
+ saved[i.hostname()] = i.domain_state();
+ i.Advance();
+ }
+
+ std::string serialized;
+ EXPECT_TRUE(persister_->SerializeData(&serialized));
+
+ // Persist the data to the file. For the test to be fast and not flaky, we
+ // just do it directly rather than call persister_->StateIsDirty. (That uses
+ // ImportantFileWriter, which has an asynchronous commit interval rather
+ // than block.) Use a different basename just for cleanliness.
+ base::FilePath path =
+ temp_dir_.path().AppendASCII("TransportSecurityPersisterTest");
+ EXPECT_TRUE(file_util::WriteFile(path, serialized.c_str(),
+ serialized.size()));
+
+ // Read the data back.
+ std::string persisted;
+ EXPECT_TRUE(base::ReadFileToString(path, &persisted));
+ EXPECT_EQ(persisted, serialized);
+ bool dirty;
+ EXPECT_TRUE(persister_->LoadEntries(persisted, &dirty));
+ EXPECT_FALSE(dirty);
+
+ // Check that states are the same as saved.
+ size_t count = 0;
+ TransportSecurityState::Iterator j(state_);
+ while (j.HasNext()) {
+ count++;
+ j.Advance();
+ }
+ EXPECT_EQ(count, saved.size());
+}
+
+TEST_F(TransportSecurityPersisterTest, SerializeDataOld) {
+ // This is an old-style piece of transport state JSON, which has no creation
+ // date.
+ std::string output =
+ "{ "
+ "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {"
+ "\"expiry\": 1266815027.983453, "
+ "\"include_subdomains\": false, "
+ "\"mode\": \"strict\" "
+ "}"
+ "}";
+ bool dirty;
+ EXPECT_TRUE(persister_->LoadEntries(output, &dirty));
+ EXPECT_TRUE(dirty);
+}
+
+TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
+ TransportSecurityState::DomainState domain_state;
+ static const char kTestDomain[] = "example.com";
+ EXPECT_FALSE(state_.GetDomainState(kTestDomain, false, &domain_state));
+ net::HashValueVector hashes;
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+
+ net::HashValue sha1(net::HASH_VALUE_SHA1);
+ memset(sha1.data(), '1', sha1.size());
+ domain_state.dynamic_spki_hashes.push_back(sha1);
+
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+
+ hashes.push_back(sha1);
+ EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes));
+
+ hashes[0].data()[0] = '2';
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+ bool include_subdomains = false;
+ state_.AddHSTS(kTestDomain, expiry, include_subdomains);
+ state_.AddHPKP(kTestDomain, expiry, include_subdomains,
+ domain_state.dynamic_spki_hashes);
+ std::string ser;
+ EXPECT_TRUE(persister_->SerializeData(&ser));
+ bool dirty;
+ EXPECT_TRUE(persister_->LoadEntries(ser, &dirty));
+ EXPECT_TRUE(state_.GetDomainState(kTestDomain, false, &domain_state));
+ EXPECT_EQ(1u, domain_state.dynamic_spki_hashes.size());
+ EXPECT_EQ(sha1.tag, domain_state.dynamic_spki_hashes[0].tag);
+ EXPECT_EQ(0, memcmp(domain_state.dynamic_spki_hashes[0].data(), sha1.data(),
+ sha1.size()));
+}
diff --git a/chromium/net/http/transport_security_state.cc b/chromium/net/http/transport_security_state.cc
index d238e995568..f9ba807ff79 100644
--- a/chromium/net/http/transport_security_state.cc
+++ b/chromium/net/http/transport_security_state.cc
@@ -244,18 +244,8 @@ std::string TransportSecurityState::CanonicalizeHost(const std::string& host) {
break;
for (size_t j = 0; j < label_length; ++j) {
- // RFC 3490, 4.1, step 3
- if (!IsSTD3ASCIIValidCharacter(new_host[i + 1 + j]))
- return std::string();
-
new_host[i + 1 + j] = tolower(new_host[i + 1 + j]);
}
-
- // step 3(b)
- if (new_host[i + 1] == '-' ||
- new_host[i + label_length] == '-') {
- return std::string();
- }
}
return new_host;
@@ -522,6 +512,9 @@ enum SecondLevelDomainName {
DOMAIN_CHROMIUM_ORG,
DOMAIN_CRYPTO_CAT,
+ DOMAIN_LAVABIT_COM,
+
+ DOMAIN_GOOGLETAGMANAGER_COM,
// Boundary value for UMA_HISTOGRAM_ENUMERATION:
DOMAIN_NUM_EVENTS
diff --git a/chromium/net/http/transport_security_state.h b/chromium/net/http/transport_security_state.h
index ccbc53a087d..97b4d7c1fc8 100644
--- a/chromium/net/http/transport_security_state.h
+++ b/chromium/net/http/transport_security_state.h
@@ -35,7 +35,7 @@ class SSLInfo;
class NET_EXPORT TransportSecurityState
: NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
- class Delegate {
+ class NET_EXPORT Delegate {
public:
// This function may not block and may be called with internal locks held.
// Thus it must not reenter the TransportSecurityState object.
diff --git a/chromium/net/http/transport_security_state_static.certs b/chromium/net/http/transport_security_state_static.certs
index ca6ef535bc8..718b7300f57 100644
--- a/chromium/net/http/transport_security_state_static.certs
+++ b/chromium/net/http/transport_security_state_static.certs
@@ -54,136 +54,12 @@ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
-Google1024
------BEGIN CERTIFICATE-----
-MIICsDCCAhmgAwIBAgIDC2dxMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDkwNjA4MjA0MzI3WhcNMTMwNjA3MTk0MzI3
-WjBGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZ
-R29vZ2xlIEludGVybmV0IEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAye23pIucV+eEPkB9hPSP0XFjU5nneXQUr0SZMyCSjXvlKAy6rWxJfoNf
-NFlOCnowzdDXxFdF7dWq1nMmzq0yE7jXDx07393cCDaob1FEm8rWIFJztyaHNWrb
-qeXUWaUr/GcZOfqTGBhs3t0lig4zFEfC7wFQeeT9adGnwKziV28CAwEAAaOBozCB
-oDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFL/AMOv1QxE+Z7qekfv8atrjaxIk
-MB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMBIGA1UdEwEB/wQIMAYB
-Af8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20v
-Y3Jscy9zZWN1cmVjYS5jcmwwDQYJKoZIhvcNAQEFBQADgYEAuIojxkiWsRF8YHde
-BZqrocb6ghwYB8TrgbCoZutJqOkM0ymt9e8kTP3kS8p/XmOrmSfLnzYhLLkQYGfN
-0rTw8Ktx5YtaiScRhKqOv5nwnQkhClIZmloJ0pC3+gz4fniisIWvXEyZ2VxVKfml
-UUIuOss4jHg7y/j7lYe8vJD5UDI=
------END CERTIFICATE-----
-
-Google2048
-sha1/AbkhxY0L343gKf+cki7NVWp+ozk=
-
-GoogleBackup1024
-sha1/fVujyo43ZR18ccPjt3TN6XsbWUM=
-
GoogleBackup2048
sha1/vq7OyjSnqOco9nyMCDGdy77eijM=
GoogleG2
sha1/Q9rWMO5T+KmAym79hfRqo3mQ4Oo=
-ThawteSGCCA
------BEGIN CERTIFICATE-----
-MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
-bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
-MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
-d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
-QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
-PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
-5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
-3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
-A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
-BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
-L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
-AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
-BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
-BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
-q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
-bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
------END CERTIFICATE-----
-
-VeriSignClass3SSPIntermediateCA
------BEGIN CERTIFICATE-----
-MIIGVDCCBTygAwIBAgIQGYH0QFTS4OtUK7v7RciQfjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMTk5OSBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzMwHhcNMTEwMTA3MDAwMDAwWhcNMTMxMjMxMjM1OTU5WjB2MQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxLTArBgNVBAMTJFZlcmlTaWduIENsYXNzIDMg
-U1NQIEludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBANfMaBonchSI7reVYNNe3hhSwUY/fbEmnDwCoonR2MFXsQkP9n8yNaU1nhRT
-Eovg4zAetI+e0bDAt9/0Lw/n1x/FdiTTPdMN6SxKLqc8z7xql0MZ+MBzyhsstmIB
-RmJWkGisFFAZ51BYB/k9AfLtHjQnvc1yHYBgo0ySG2a6ejkJd2r6U/dvjgbu2dSj
-Eo5XJGl//xSSLKs4HPhkuAsdZr2HqPiBwjlFpCd//Fs8he43JBI60+bRSBiUKpQC
-ssu6oAj2rvKcy2AMTvjIAlz9Iy3B92fB1Q1JxpbWcLochUca7/NFQTkKMaVeBXxy
-i2D+SFWfuBLtcl7p/kbtwqfiDbMCAwEAAaOCAocwggKDMA8GA1UdEwEB/wQFMAMB
-Af8wDgYDVR0PAQH/BAQDAgEGMIHoBgNVHSAEgeAwgd0wDwYNYIZIAYb4RQEHFwMB
-BjAPBg1ghkgBhvhFAQcXAwEHMA8GDWCGSAGG+EUBBxcDAQgwDwYNYIZIAYb4RQEH
-FwMBDTAPBg1ghkgBhvhFAQcXAwEOMA8GDWCGSAGG+EUBBxcDAQ8wDwYNYIZIAYb4
-RQEHFwMBETAPBg1ghkgBhvhFAQcXAwEUMA8GDWCGSAGG+EUBBxcDARcwDwYNYIZI
-AYb4RQEHFwMBGDAPBg1ghkgBhvhFAQcXAwEZMA8GDWCGSAGG+EUBBxcDARowDwYN
-YIZIAYb4RQEHFwMBGzA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vc3NwLWNybC52
-ZXJpc2lnbi5jb20vcGNhMy1nMy5jcmwwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMT
-EFZlcmlTaWduTVBLSS0xLTgwHQYDVR0OBBYEFCwx/8HOq/lN6IkVwGry5atCfUL6
-MIHxBgNVHSMEgekwgeahgdCkgc0wgcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5W
-ZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6
-MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJp
-bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczghEAm34GSaM+YrnV7pBI
-cSnvVzANBgkqhkiG9w0BAQUFAAOCAQEAIS19vzG9j+KXiQ0G1bOuJCeiD9KKW1+8
-69cutvgDf3hEvrw39Gr2ek3cAdso7dvwW0Z17muzpHV08gWTjjKba8mBzjijmgr9
-I2vE2K/Ls72WJvTDUjCAHfBJKeK1q8v7xv1xtf2Jz7BV8sNH3kDB7jhhE++8zLVC
-gyFilU0KZfhBpLPVlVYnLozRdvsHfNnO/JskJvRqhDYbeC5ginQT0m5sTQiyTYqL
-/IU+i82TxANXjC7syl0dfcGr8pJ85T9bF1EZLxdgikAYLKPGTuXMwOGqT5bR0dKD
-lWShiGTRl7HW0KJMg05F0HjOnYpdOYGaFrQghecrkcrRPRevSdFVHQ==
------END CERTIFICATE-----
-
-EquifaxSecureCA
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
-UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
-dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
-MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
-dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
-BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
-cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
-AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
-MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
-aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
-ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
-MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
-A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
-1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
-
-Aetna
------BEGIN CERTIFICATE-----
-MIICsjCCAhugAwIBAgIDBe3YMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDUwODMxMjA0MDM3WhcNMTIwODMxMjA0MDM3
-WjBIMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQWV0bmEgSW5jLjEkMCIGA1UEAxMb
-QWV0bmEgSW5jLiBTZWN1cmUgU2VydmVyIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQCnB2yrm4i44DG5epPu0fbe/pOZDWOvAS7qCcy6YbSkPfOHfH9Blmf3
-8L6D5yY1pzmTXaU7cDQu4qmj21toEIGwBziMmW6NsiV8nHtmtfXfHP6xrmyPUdN2
-DdTj937fnrYOoyMhGgBYEjiemeHFQxZSpKZdolFEFXbUa2/yWQafrQIDAQABo4Gj
-MIGgMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU2S4/xnaeitmFkzoxLnZeo33n
-H4owHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gjIBBPM5iQn9QwEgYDVR0TAQH/BAgw
-BgEB/wIBADA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNv
-bS9jcmxzL3NlY3VyZWNhLmNybDANBgkqhkiG9w0BAQUFAAOBgQBMSoZHIrD1rq8v
-UG3UYbN76xiF9FDRzWTs5Mvv4Psvf2kk426slzNO0ukFAsmwqN1mA/P9Nc4FlMMC
-YtcnLNwC/syEYdQBOJjxfTVGTqh5q6jDs7S3rPJv8mrFk8ldC8PxU1ZJVfSlFCDn
-6diMDgvOAJfUeJlIRLGu2k/ksI0Y1w==
------END CERTIFICATE-----
-
GeoTrustGlobal
-----BEGIN CERTIFICATE-----
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
@@ -230,83 +106,6 @@ HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t
e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk=
-----END CERTIFICATE-----
-Intel
------BEGIN CERTIFICATE-----
-MIIFijCCBHKgAwIBAgIKYSCKYgAAAAAACDANBgkqhkiG9w0BAQUFADBSMQswCQYD
-VQQGEwJVUzEaMBgGA1UEChMRSW50ZWwgQ29ycG9yYXRpb24xJzAlBgNVBAMTHklu
-dGVsIEV4dGVybmFsIEJhc2ljIFBvbGljeSBDQTAeFw0wOTA1MTUxOTI3MjZaFw0x
-NTA1MTUxOTM3MjZaMFYxCzAJBgNVBAYTAlVTMRowGAYDVQQKExFJbnRlbCBDb3Jw
-b3JhdGlvbjErMCkGA1UEAxMiSW50ZWwgRXh0ZXJuYWwgQmFzaWMgSXNzdWluZyBD
-QSAzQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKQEM1Wn9TU9vc9C
-+/Tc7KB+eiYElmrcEWE32WUdHvWG+IcQHVQsikTmMyKKojNLw2B5s6Iekc8ivDo/
-wCfjZzX9JyftMnc+AArc0la87Olybzm8K9jXEfTBvTnUSFSiI9ZYefITdiUgqlAF
-uljFZEHYKYtLuhrRacpmQfP4mV63NKdc2bT804HRf6YptZFa4k6YN94zlrGNrBuQ
-Q74WFzz/jLBusbUpEkro6Mu/ZYFOFWQrV9lBhF9Ruk8yN+3N6n9fUo/qBigiF2kE
-n9xVh1ykl7SCGL2jBUkXx4qgV27a6Si8lRRdgrHGtN/HWnSWlLXTH5l575H4Lq++
-77OFv38CAwEAAaOCAlwwggJYMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA7G
-KvdZsggQkCVvw939imYxMCvFMAsGA1UdDwQEAwIBhjASBgkrBgEEAYI3FQEEBQID
-AQABMCMGCSsGAQQBgjcVAgQWBBQ5oFY2ekKQ/5Ktim+VdMeSWb4QWTAZBgkrBgEE
-AYI3FAIEDB4KAFMAdQBiAEMAQTAfBgNVHSMEGDAWgBQaxgxKxEdvqNutK/D0Vgaj
-7TdUDDCBvQYDVR0fBIG1MIGyMIGvoIGsoIGphk5odHRwOi8vd3d3LmludGVsLmNv
-bS9yZXBvc2l0b3J5L0NSTC9JbnRlbCUyMEV4dGVybmFsJTIwQmFzaWMlMjBQb2xp
-Y3klMjBDQS5jcmyGV2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuaW50ZWwuY29tL3JlcG9z
-aXRvcnkvQ1JML0ludGVsJTIwRXh0ZXJuYWwlMjBCYXNpYyUyMFBvbGljeSUyMENB
-LmNybDCB4wYIKwYBBQUHAQEEgdYwgdMwYwYIKwYBBQUHMAKGV2h0dHA6Ly93d3cu
-aW50ZWwuY29tL3JlcG9zaXRvcnkvY2VydGlmaWNhdGVzL0ludGVsJTIwRXh0ZXJu
-YWwlMjBCYXNpYyUyMFBvbGljeSUyMENBLmNydDBsBggrBgEFBQcwAoZgaHR0cDov
-L2NlcnRpZmljYXRlcy5pbnRlbC5jb20vcmVwb3NpdG9yeS9jZXJ0aWZpY2F0ZXMv
-SW50ZWwlMjBFeHRlcm5hbCUyMEJhc2ljJTIwUG9saWN5JTIwQ0EuY3J0MA0GCSqG
-SIb3DQEBBQUAA4IBAQCxtQEHchVQhXyjEqtMVUMe6gkmPsIczHxSeqNbo9dsD+6x
-bT65JT+oYgpIAtfEsYXeUJu1cChqpb22U5bMAz7eaQcW5bzefufWvA6lg2048B8o
-czBj/q+5P5NpYrUO8jOmN4jTjfJq3ElZ7yFWpy7rB3Vm/aN6ATYqWfMbS/xfh+JC
-xmH3droUmMJI0/aZJHsLtjbjFnNsHDNrJZX1vxlM78Lb1hjskTENPmhbVbfTj5i/
-ZGnhv4tmI8QZPCNtcegXJrfhRl2D9bWpdTOPrWiLDUqzy1Z6KL7TcOS/PCl8RHCJ
-XkPau/thTQCpIoDa2+c+3XA++gRTfAQ4svTO260N
------END CERTIFICATE-----
-
-TCTrustCenter
------BEGIN CERTIFICATE-----
-MIIDWzCCAsSgAwIBAgIDCaxIMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDgwODE1MTY0NTE1WhcNMTMwMjE0MTc0NTE1
-WjBtMQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21iSDEe
-MBwGA1UECxMVVEMgVHJ1c3RDZW50ZXIgU1NMIENBMSAwHgYDVQQDExdUQyBUcnVz
-dENlbnRlciBTU0wgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AOkCoJoNbJw33wSxNWbDdmIfDIedR8Zmr/mjOhMkXdxRYb6qrl/WfMEuo4PBcysJ
-kF81LaDMkBH0zc7Hs1eYixrMVObkCmEUjxYylgOk4ExGwhmIWDJUWGslNBUIIhFf
-+ucDWuGZNfILQrwCWRHYBG0n/6lZPylCqopCMYhBK5sTI/PyuHEAzDL7+buep/Na
-zn+oy/a6x1nobsuL9X2oFaWZb7Z6ty5kZ/U56JHa7vnsLrg4ePwiQb8jtyUdz0fD
-uMHkNzK0gWxr4hm0v92otYFuOTZqNLEJneeiILxUCCMop2chr1obpq2zGVNxJ/rP
-StWmcu75KBGMpT+mzFgIyf0CAwEAAaOBozCBoDAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFOe/bKlImXeG4tD/MKCQHQtk0IU6MB8GA1UdIwQYMBaAFEjmaPkr0rKV
-10fYIyAQTzOYkJ/UMBIGA1UdEwEB/wQIMAYBAf8CAQAwOgYDVR0fBDMwMTAvoC2g
-K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5jcmwwDQYJ
-KoZIhvcNAQEFBQADgYEAVKyJLbJha83PggEit8+dzh50wIsKXpTV2K6K4HnUI1kh
-xqocLVfQORluC+LS7L78D2EKTWLZ8WNujiP6DbbIPSTsMasuiBMQMBUlJMUqsp/M
-XmQJgIGAbxsr19MY6mmB30oWuo4cjHnkMzSCfhcON6Rxvbjijk2qCWXkk2T2HAk=
------END CERTIFICATE-----
-
-Vodafone
------BEGIN CERTIFICATE-----
-MIIDJDCCAo2gAwIBAgIDBfw3MA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
-MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
-aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYwNzIxMTUwNTA2WhcNMTEwNzEyMTUwNTA2
-WjA5MQswCQYDVQQGEwJVSzEXMBUGA1UEChMOVm9kYWZvbmUgR3JvdXAxETAPBgNV
-BAMTCFZvZGFmb25lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs61K
-wbMcB+GGGbjyo1dYEiVNGRYKRsDXfeOgeq03Vebf7D5Xq6a0Qs4Rvp6CuRTSNDPi
-M+0vuQRW5sib9UD8UB2x4znc6FriRV4FUpAyKNVqQ9NB0MOBpQekVlX9DzcXkn+p
-zWRi6tt3CtPsaDyHo06oAwX5qu3tW3pjtf0vnQqJWwwA6Mp4YJ/acHD/vVtt67hz
-a0Upz0O2DEJetb3OaqI5yaNZ91y6i7sK0KTvBQxZHeJs+y5UjluHv3ptMUZvmsf0
-SiKysXnkg5mtsZSFlfM+U7dADq1zNb764NV5sSlmbDLEkvohQyg1p9gh2HX9Jk4A
-e9nnF4hjw2U33HLBXwIDAQABo4GgMIGdMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUR+YiAaq+68BPLD6l0UcvzlkcgvswHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwDwYDVR0TAQH/BAUwAwEB/zA6BgNVHR8EMzAxMC+gLaArhilodHRw
-Oi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDANBgkqhkiG9w0B
-AQUFAAOBgQCs37zuSY/KkPigCvJevu+ewWy9GP2bFZi5EaxKuHGF+tYFZUNkyc06
-ACYMM3ADPM6dVUYeXIDZnPfV8BJFCpdoAHkSNlg341AVjabCOWtzOYolBn0ua8Wi
-BM471XfzzXD7yMliek9J4fUn2vQU7MYgEkSAA53ZkMScGDkA/c1wMQ==
------END CERTIFICATE-----
-
RapidSSL
-----BEGIN CERTIFICATE-----
MIID1TCCAr2gAwIBAgIDAjbRMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
@@ -1346,3 +1145,111 @@ TvwjIDhO+wtc3qXjtO1zej3+GBmGz7RcZckturc2pZe3NRWQ7wO8ZzWShWU/ii3z
2PftKlqZo3WAeJoUCPtQNsLnBFGvdUx2rUZwMhdgPuGeV4kEULAtu8M74xR5/Opz
nRGP22zr1K4q
-----END CERTIFICATE-----
+
+Libertylavabitcom
+-----BEGIN CERTIFICATE-----
+MIIGWjCCBUKgAwIBAgIHAMn6RGIIgjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
+BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
+BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
+aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
+IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
+ODcwHhcNMTMxMDExMDgzNjAyWhcNMTQxMDExMDgzNjAyWjBBMSEwHwYDVQQLExhE
+b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxHDAaBgNVBAMTE2xpYmVydHkubGF2YWJp
+dC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCo/gQ2t5YtS2dj
+BhIo2ke667uC2qhnUbnroyuqyf+GZafWZC/cmPYpkAWclu14ETBsR3u+6QtDHhOe
+q3OBN0+IVLu5QwYSB2sqYUwyOHZ342uHQktWpPvNiwNHyfl1LsHL4WLuvQw3stK4
+DR+l6H/Ex11bl4KVvfk8uy+kXawcIQv7gr69OwEFEmGqeLSqr+fZdegLKPY20Ujx
+WHSe8ErtW0eMY2A/DvrDrnfw+rVX5sxJIKk77AutIoyt+Ce2TwMVQtfbeQVWy91g
+ST+sqC69wI5BOSguV5zECqIP1zxo939VVVciNGA3+3gyLJa+NDDpbT8xCwXClXN4
+3iektxfP7OgPjPwhDueZNhq54mA5mBY+qdkLyCmvURiczSNeoDTWouqaJq1lKjuh
+CgkAhgoaLueAQv+uGNlVFtbQHApEvYcdz8XTqoL24wf3kadu6vxhrYVS+hguVVEE
+YOc7LJsiQ3ERDjh1naFlL9h5khn6qhjw77oS6PWaCIJT8GfD8bjqCozdOdS1e+Sh
+Bbp2Yg48m/XyQ3ocpEUmTt7n3fRv41XOY4tmBhloqkdPIDccl5deUhI//1VgycJv
+uDqsMgRhyZvdS1kxhDAwbi1GtomURGdB/9kptYshUrR6xk1EP60pjWNxuvB7HMPg
+seGNxPa15U/4z+5h8iSFdKa2TLkk7wIDAQABo4IByzCCAccwDwYDVR0TAQH/BAUw
+AwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
+AgWgMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rz
+MS0xMDAuY3JsMFMGA1UdIARMMEowSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcC
+ARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCB
+gAYIKwYBBQUHAQEEdDByMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5
+LmNvbS8wSgYIKwYBBQUHMAKGPmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
+b20vcmVwb3NpdG9yeS9nZF9pbnRlcm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2s
+YTKTbEXW4u6FX5q653aZaMznMDcGA1UdEQQwMC6CE2xpYmVydHkubGF2YWJpdC5j
+b22CF3d3dy5saWJlcnR5LmxhdmFiaXQuY29tMB0GA1UdDgQWBBSVRSbXCJKN6lms
+ZtlccHBz/xVLwDANBgkqhkiG9w0BAQUFAAOCAQEAKja1YxyoTuHD1RV4L7wULpiy
+ot4Z3OEuoOZTPJsoHfUCtOtKlUu2ZSwp5+IpaLnC3iCIxy1Yb6qu6Li5dqgtOkxl
+4JqrOooQ9IUzuTLhSzPf6rEtw9gnYN/dpQ2q0YLh+K5SgRUm9y0PHBV4acfSh2TJ
+vyaXDmuonX5zG7u3nz/oCo/qziW46Phz/leMhCAgLnZUYcAv6KPET+RMRmt4n8gg
+C0xlOcCQbMh9VIPZ0WSnmdFn5DUCW+oVlwhxDB/3CvWIa0k/WI6NNW8vg+VdSyW7
+p/dp4mikGH37Tc5VAhcYMbAem69nSg7Qfrs35tak/JPJlx1LWayERGHLvTy7Ag==
+-----END CERTIFICATE-----
+
+GlobalSignRootCA
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+
+GlobalSignRootCA_R2
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+
+GlobalSignRootCA_R3
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
diff --git a/chromium/net/http/transport_security_state_static.h b/chromium/net/http/transport_security_state_static.h
index a924550cbec..6a28ca4562b 100644
--- a/chromium/net/http/transport_security_state_static.h
+++ b/chromium/net/http/transport_security_state_static.h
@@ -22,18 +22,6 @@ static const char kSPKIHash_VeriSignClass3_G3[] =
"\x22\xf1\x9e\x2e\xc6\xea\xcc\xfc\x5d\x23"
"\x46\xf4\xc2\xe8\xf6\xc5\x54\xdd\x5e\x07";
-static const char kSPKIHash_Google1024[] =
- "\x40\xc5\x40\x1d\x6f\x8c\xba\xf0\x8b\x00"
- "\xed\xef\xb1\xee\x87\xd0\x05\xb3\xb9\xcd";
-
-static const char kSPKIHash_Google2048[] =
- "\x01\xb9\x21\xc5\x8d\x0b\xdf\x8d\xe0\x29"
- "\xff\x9c\x92\x2e\xcd\x55\x6a\x7e\xa3\x39";
-
-static const char kSPKIHash_GoogleBackup1024[] =
- "\x7d\x5b\xa3\xca\x8e\x37\x65\x1d\x7c\x71"
- "\xc3\xe3\xb7\x74\xcd\xe9\x7b\x1b\x59\x43";
-
static const char kSPKIHash_GoogleBackup2048[] =
"\xbe\xae\xce\xca\x34\xa7\xa8\xe7\x28\xf6"
"\x7c\x8c\x08\x31\x9d\xcb\xbe\xde\x8a\x33";
@@ -42,22 +30,6 @@ static const char kSPKIHash_GoogleG2[] =
"\x43\xda\xd6\x30\xee\x53\xf8\xa9\x80\xca"
"\x6e\xfd\x85\xf4\x6a\xa3\x79\x90\xe0\xea";
-static const char kSPKIHash_ThawteSGCCA[] =
- "\x87\x31\xea\x0e\x3d\xf5\xe8\x70\x3e\x83"
- "\x72\x57\x77\xa9\x65\x3b\x3b\xfa\x5e\x14";
-
-static const char kSPKIHash_VeriSignClass3SSPIntermediateCA[] =
- "\x99\x6a\x20\x6a\x85\x57\x62\xcb\x9a\xf2"
- "\x02\x37\xb3\xc0\x69\x5d\xa9\x1e\xc2\x22";
-
-static const char kSPKIHash_EquifaxSecureCA[] =
- "\x48\xe6\x68\xf9\x2b\xd2\xb2\x95\xd7\x47"
- "\xd8\x23\x20\x10\x4f\x33\x98\x90\x9f\xd4";
-
-static const char kSPKIHash_Aetna[] =
- "\x92\x52\xaa\x14\xde\xbf\x80\xae\x30\xaa"
- "\xd9\x4e\x60\x38\x70\x24\xa5\x43\x2f\x1a";
-
static const char kSPKIHash_GeoTrustGlobal[] =
"\xc0\x7a\x98\x68\x8d\x89\xfb\xab\x05\x64"
"\x0c\x11\x7d\xaa\x7d\x65\xb8\xca\xcc\x4e";
@@ -66,18 +38,6 @@ static const char kSPKIHash_GeoTrustPrimary[] =
"\xb0\x19\x89\xe7\xef\xfb\x4a\xaf\xcb\x14"
"\x8f\x58\x46\x39\x76\x22\x41\x50\xe1\xba";
-static const char kSPKIHash_Intel[] =
- "\x0e\xc6\x2a\xf7\x59\xb2\x08\x10\x90\x25"
- "\x6f\xc3\xdd\xfd\x8a\x66\x31\x30\x2b\xc5";
-
-static const char kSPKIHash_TCTrustCenter[] =
- "\x83\x3b\x84\x10\x00\x7f\x6e\x4a\x9d\x41"
- "\x2d\xc4\x22\x39\x36\x6f\x2e\xe5\x5b\xe9";
-
-static const char kSPKIHash_Vodafone[] =
- "\x0d\x7f\xe1\x5c\x55\x14\x36\x68\x99\xfc"
- "\x40\xd6\x22\x08\xef\x22\xeb\xd1\x15\x1c";
-
static const char kSPKIHash_RapidSSL[] =
"\xa3\x93\x99\xc4\x04\xc3\xb2\x09\xb0\x81"
"\xc2\x1f\x21\x62\x27\x78\xc2\x74\x8e\x4c";
@@ -250,6 +210,22 @@ static const char kSPKIHash_CryptoCat1[] =
"\x4c\x87\xce\x85\x2c\xf4\xc0\x4d\x67\xa9"
"\xe0\xec\x51\x0c\x7f\x3b\x14\xb3\xe9\xc9";
+static const char kSPKIHash_Libertylavabitcom[] =
+ "\x41\xbb\x3b\x8b\xc7\xcf\x3d\x13\x3f\x17"
+ "\xb3\x25\x7e\xe4\x03\xca\x8a\x5c\x6d\x36";
+
+static const char kSPKIHash_GlobalSignRootCA[] =
+ "\x87\xdb\xd4\x5f\xb0\x92\x8d\x4e\x1d\xf8"
+ "\x15\x67\xe7\xf2\xab\xaf\xd6\x2b\x67\x75";
+
+static const char kSPKIHash_GlobalSignRootCA_R2[] =
+ "\xa5\x06\x8a\x78\xcf\x84\xbd\x74\x32\xdd"
+ "\x58\xf9\x65\xeb\x3a\x55\xe7\xc7\x80\xdc";
+
+static const char kSPKIHash_GlobalSignRootCA_R3[] =
+ "\xf7\x93\x19\xef\xdf\xc1\xf5\x20\xfb\xac"
+ "\x85\x55\x2c\xf2\xd2\x8f\x5a\xb9\xca\x0b";
+
// The following is static data describing the hosts that are hardcoded with
// certificate pins or HSTS information.
@@ -268,29 +244,13 @@ static const char* const kTestAcceptableCerts[] = {
}
static const char* const kGoogleAcceptableCerts[] = {
- kSPKIHash_VeriSignClass3,
- kSPKIHash_VeriSignClass3_G3,
- kSPKIHash_Google1024,
- kSPKIHash_Google2048,
- kSPKIHash_GoogleBackup1024,
kSPKIHash_GoogleBackup2048,
kSPKIHash_GoogleG2,
- kSPKIHash_EquifaxSecureCA,
- kSPKIHash_GeoTrustGlobal,
- NULL,
-};
-static const char* const kGoogleRejectedCerts[] = {
- kSPKIHash_Aetna,
- kSPKIHash_Intel,
- kSPKIHash_TCTrustCenter,
- kSPKIHash_Vodafone,
- kSPKIHash_ThawteSGCCA,
- kSPKIHash_VeriSignClass3SSPIntermediateCA,
NULL,
};
#define kGooglePins { \
kGoogleAcceptableCerts, \
- kGoogleRejectedCerts, \
+ kNoRejectedPublicKeys, \
}
static const char* const kTorAcceptableCerts[] = {
@@ -377,6 +337,9 @@ static const char* const kTwitterCDNAcceptableCerts[] = {
kSPKIHash_UTNUSERFirstObject,
kSPKIHash_GTECyberTrustGlobalRoot,
kSPKIHash_BaltimoreCyberTrustRoot,
+ kSPKIHash_GlobalSignRootCA,
+ kSPKIHash_GlobalSignRootCA_R2,
+ kSPKIHash_GlobalSignRootCA_R3,
NULL,
};
#define kTwitterCDNPins { \
@@ -404,6 +367,15 @@ static const char* const kCryptoCatAcceptableCerts[] = {
kNoRejectedPublicKeys, \
}
+static const char* const kLavabitAcceptableCerts[] = {
+ kSPKIHash_Libertylavabitcom,
+ NULL,
+};
+#define kLavabitPins { \
+ kLavabitAcceptableCerts, \
+ kNoRejectedPublicKeys, \
+}
+
#define kNoPins {\
NULL, NULL, \
}
@@ -430,6 +402,10 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{19, true, "\006script\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{20, true, "\007history\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{21, true, "\010security\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
+ {17, true, "\004goto\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
+ {18, true, "\005cloud\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
+ {18, true, "\005glass\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
+ {17, false, "\004play\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
{20, true, "\006market\007android\003com", true, kGooglePins, DOMAIN_ANDROID_COM },
{26, true, "\003ssl\020google-analytics\003com", true, kGooglePins, DOMAIN_GOOGLE_ANALYTICS_COM },
{18, true, "\005drive\006google\003com", true, kGooglePins, DOMAIN_GOOGLE_COM },
@@ -453,13 +429,14 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{13, true, "\007appspot\003com", false, kGooglePins, DOMAIN_APPSPOT_COM },
{23, true, "\021googlesyndication\003com", false, kGooglePins, DOMAIN_GOOGLESYNDICATION_COM },
{17, true, "\013doubleclick\003net", false, kGooglePins, DOMAIN_DOUBLECLICK_NET },
- {17, true, "\003ssl\007gstatic\003com", false, kGooglePins, DOMAIN_GSTATIC_COM },
+ {13, true, "\007gstatic\003com", false, kGooglePins, DOMAIN_GSTATIC_COM },
{10, true, "\005youtu\002be", false, kGooglePins, DOMAIN_YOUTU_BE },
{13, true, "\007android\003com", false, kGooglePins, DOMAIN_ANDROID_COM },
{20, true, "\016googlecommerce\003com", false, kGooglePins, DOMAIN_GOOGLECOMMERCE_COM },
{12, true, "\006urchin\003com", false, kGooglePins, DOMAIN_URCHIN_COM },
{8, true, "\003goo\002gl", false, kGooglePins, DOMAIN_GOO_GL },
{6, true, "\001g\002co", false, kGooglePins, DOMAIN_G_CO },
+ {22, true, "\020googletagmanager\003com", false, kGooglePins, DOMAIN_GOOGLETAGMANAGER_COM },
{11, true, "\006google\002ac", false, kGooglePins, DOMAIN_GOOGLE_AC },
{11, true, "\006google\002ad", false, kGooglePins, DOMAIN_GOOGLE_AD },
{11, true, "\006google\002ae", false, kGooglePins, DOMAIN_GOOGLE_AE },
@@ -753,8 +730,7 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{17, true, "\003dev\007twitter\003com", false, kTwitterComPins, DOMAIN_TWITTER_COM },
{22, true, "\010business\007twitter\003com", false, kTwitterComPins, DOMAIN_TWITTER_COM },
{22, true, "\010platform\007twitter\003com", false, kTwitterCDNPins, DOMAIN_TWITTER_COM },
- {15, true, "\003si0\005twimg\003com", false, kTwitterCDNPins, DOMAIN_TWIMG_COM },
- {23, true, "\010twimg0-a\010akamaihd\003net", false, kTwitterCDNPins, DOMAIN_AKAMAIHD_NET },
+ {11, true, "\005twimg\003com", false, kTwitterCDNPins, DOMAIN_TWIMG_COM },
{22, true, "\020braintreegateway\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{23, false, "\021braintreepayments\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{27, false, "\003www\021braintreepayments\003com", true, kNoPins, DOMAIN_NOT_PINNED },
@@ -794,8 +770,12 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{17, false, "\003www\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{15, false, "\011mylookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{19, false, "\003www\011mylookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
- {16, false, "\002dm\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
- {18, false, "\002dm\011mylookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {16, true, "\002dm\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {22, true, "\010business\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {18, true, "\004blog\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {17, true, "\003faq\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {22, true, "\010platform\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {19, true, "\005email\007lookout\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{15, true, "\011itriskltd\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{15, true, "\012stocktrade\002de", true, kNoPins, DOMAIN_NOT_PINNED },
{22, true, "\011openshift\006redhat\003com", true, kNoPins, DOMAIN_NOT_PINNED },
@@ -855,8 +835,6 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{21, true, "\003www\013cyveillance\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{22, true, "\004blog\013cyveillance\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{12, true, "\006whonix\003org", true, kNoPins, DOMAIN_NOT_PINNED },
- {13, true, "\010blueseed\002co", true, kNoPins, DOMAIN_NOT_PINNED },
- {26, true, "\005forum\016quantifiedself\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{11, true, "\006shodan\002io", true, kNoPins, DOMAIN_NOT_PINNED },
{18, true, "\015rapidresearch\002me", true, kNoPins, DOMAIN_NOT_PINNED },
{14, true, "\010surkatty\003org", true, kNoPins, DOMAIN_NOT_PINNED },
@@ -873,6 +851,39 @@ static const struct HSTSPreload kPreloadedSTS[] = {
{22, true, "\020appseccalifornia\003org", true, kNoPins, DOMAIN_NOT_PINNED },
{17, true, "\013crowdcurity\003com", true, kNoPins, DOMAIN_NOT_PINNED },
{19, true, "\013saturngames\002co\002uk", true, kNoPins, DOMAIN_NOT_PINNED },
+ {23, true, "\021strongest-privacy\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {25, true, "\011ecosystem\011atlassian\003net", true, kNoPins, DOMAIN_NOT_PINNED },
+ {18, true, "\002id\011atlassian\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {15, false, "\011bitbucket\003org", true, kNoPins, DOMAIN_NOT_PINNED },
+ {12, true, "\007cupcake\002io", true, kNoPins, DOMAIN_NOT_PINNED },
+ {12, true, "\007cupcake\002is", true, kNoPins, DOMAIN_NOT_PINNED },
+ {9, true, "\004tent\002io", true, kNoPins, DOMAIN_NOT_PINNED },
+ {12, true, "\006cybozu\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {17, true, "\013davidlyness\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {12, true, "\006medium\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {21, true, "\007liberty\007lavabit\003com", true, kLavabitPins, DOMAIN_LAVABIT_COM },
+ {16, true, "\012getlantern\003org", true, kNoPins, DOMAIN_NOT_PINNED },
+ {15, false, "\011kinsights\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {15, false, "\007simbolo\002co\002uk", true, kNoPins, DOMAIN_NOT_PINNED },
+ {19, false, "\003www\007simbolo\002co\002uk", true, kNoPins, DOMAIN_NOT_PINNED },
+ {16, false, "\012zenpayroll\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {20, false, "\003www\012zenpayroll\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {20, false, "\003get\012zenpayroll\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {23, false, "\006errors\012zenpayroll\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {23, false, "\006manage\012zenpayroll\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {19, true, "\016gernert-server\002de", true, kNoPins, DOMAIN_NOT_PINNED },
+ {19, true, "\010skydrive\004live\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {21, true, "\011lifeguard\005aecom\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {17, false, "\004data\003qld\003gov\002au", true, kNoPins, DOMAIN_NOT_PINNED },
+ {25, false, "\014publications\003qld\003gov\002au", true, kNoPins, DOMAIN_NOT_PINNED },
+ {13, true, "\002go\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {16, true, "\005login\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {13, true, "\002my\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {18, true, "\007payroll\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {13, true, "\002in\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {14, true, "\003api\004xero\003com", true, kNoPins, DOMAIN_NOT_PINNED },
+ {9, true, "\003eff\003org", true, kNoPins, DOMAIN_NOT_PINNED },
+ {9, true, "\004mail\002de", true, kNoPins, DOMAIN_NOT_PINNED },
};
static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS);
diff --git a/chromium/net/http/transport_security_state_static.json b/chromium/net/http/transport_security_state_static.json
index 67e5a86ccd8..500e1782110 100644
--- a/chromium/net/http/transport_security_state_static.json
+++ b/chromium/net/http/transport_security_state_static.json
@@ -42,23 +42,8 @@
{
"name": "google",
"static_spki_hashes": [
- "VeriSignClass3",
- "VeriSignClass3_G3",
- "Google1024",
- "Google2048",
- "GoogleBackup1024",
"GoogleBackup2048",
- "GoogleG2",
- "EquifaxSecureCA",
- "GeoTrustGlobal"
- ],
- "bad_static_spki_hashes": [
- "Aetna",
- "Intel",
- "TCTrustCenter",
- "Vodafone",
- "ThawteSGCCA",
- "VeriSignClass3SSPIntermediateCA"
+ "GoogleG2"
]
},
{
@@ -141,7 +126,10 @@
"UTNUSERFirstHardware",
"UTNUSERFirstObject",
"GTECyberTrustGlobalRoot",
- "BaltimoreCyberTrustRoot"
+ "BaltimoreCyberTrustRoot",
+ "GlobalSignRootCA",
+ "GlobalSignRootCA_R2",
+ "GlobalSignRootCA_R3"
]
},
{
@@ -157,6 +145,12 @@
"DigiCertEVRoot",
"CryptoCat1"
]
+ },
+ {
+ "name": "lavabit",
+ "static_spki_hashes": [
+ "Libertylavabitcom"
+ ]
}
],
@@ -187,6 +181,11 @@
{ "name": "script.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "history.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
{ "name": "security.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "goto.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "cloud.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ { "name": "glass.google.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
+ // play.google.com doesn't have include_subdomains because of crbug.com/327834.
+ { "name": "play.google.com", "mode": "force-https", "pins": "google" },
// Other Google-related domains that must use HTTPS.
{ "name": "market.android.com", "include_subdomains": true, "mode": "force-https", "pins": "google" },
@@ -219,13 +218,14 @@
{ "name": "appspot.com", "include_subdomains": true, "pins": "google" },
{ "name": "googlesyndication.com", "include_subdomains": true, "pins": "google" },
{ "name": "doubleclick.net", "include_subdomains": true, "pins": "google" },
- { "name": "ssl.gstatic.com", "include_subdomains": true, "pins": "google" },
+ { "name": "gstatic.com", "include_subdomains": true, "pins": "google" },
{ "name": "youtu.be", "include_subdomains": true, "pins": "google" },
{ "name": "android.com", "include_subdomains": true, "pins": "google" },
{ "name": "googlecommerce.com", "include_subdomains": true, "pins": "google" },
{ "name": "urchin.com", "include_subdomains": true, "pins": "google" },
{ "name": "goo.gl", "include_subdomains": true, "pins": "google" },
{ "name": "g.co", "include_subdomains": true, "pins": "google" },
+ { "name": "googletagmanager.com", "include_subdomains": true, "pins": "google" },
{ "name": "google.ac", "include_subdomains": true, "pins": "google" },
{ "name": "google.ad", "include_subdomains": true, "pins": "google" },
{ "name": "google.ae", "include_subdomains": true, "pins": "google" },
@@ -523,8 +523,7 @@
{ "name": "dev.twitter.com", "include_subdomains": true, "pins": "twitterCom" },
{ "name": "business.twitter.com", "include_subdomains": true, "pins": "twitterCom" },
{ "name": "platform.twitter.com", "include_subdomains": true, "pins": "twitterCDN" },
- { "name": "si0.twimg.com", "include_subdomains": true, "pins": "twitterCDN" },
- { "name": "twimg0-a.akamaihd.net", "include_subdomains": true, "pins": "twitterCDN" },
+ { "name": "twimg.com", "include_subdomains": true, "pins": "twitterCDN" },
{ "name": "braintreegateway.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "braintreepayments.com", "mode": "force-https" },
{ "name": "www.braintreepayments.com", "mode": "force-https" },
@@ -564,8 +563,12 @@
{ "name": "www.lookout.com", "mode": "force-https" },
{ "name": "mylookout.com", "mode": "force-https" },
{ "name": "www.mylookout.com", "mode": "force-https" },
- { "name": "dm.lookout.com", "mode": "force-https" },
- { "name": "dm.mylookout.com", "mode": "force-https" },
+ { "name": "dm.lookout.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "business.lookout.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "blog.lookout.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "faq.lookout.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "platform.lookout.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "email.lookout.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "itriskltd.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "stocktrade.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "openshift.redhat.com", "include_subdomains": true, "mode": "force-https" },
@@ -625,8 +628,6 @@
{ "name": "www.cyveillance.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "blog.cyveillance.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "whonix.org", "include_subdomains": true, "mode": "force-https" },
- { "name": "blueseed.co", "include_subdomains": true, "mode": "force-https" },
- { "name": "forum.quantifiedself.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "shodan.io", "include_subdomains": true, "mode": "force-https" },
{ "name": "rapidresearch.me", "include_subdomains": true, "mode": "force-https" },
{ "name": "surkatty.org", "include_subdomains": true, "mode": "force-https" },
@@ -643,6 +644,39 @@
{ "name": "appseccalifornia.org", "include_subdomains": true, "mode": "force-https" },
{ "name": "crowdcurity.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "saturngames.co.uk", "include_subdomains": true, "mode": "force-https" },
+ { "name": "strongest-privacy.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "ecosystem.atlassian.net", "include_subdomains": true, "mode": "force-https" },
+ { "name": "id.atlassian.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "bitbucket.org", "mode": "force-https" },
+ { "name": "cupcake.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cupcake.is", "include_subdomains": true, "mode": "force-https" },
+ { "name": "tent.io", "include_subdomains": true, "mode": "force-https" },
+ { "name": "cybozu.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "davidlyness.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "medium.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "liberty.lavabit.com", "include_subdomains": true, "mode": "force-https", "pins": "lavabit" },
+ { "name": "getlantern.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "kinsights.com", "mode": "force-https" },
+ { "name": "simbolo.co.uk", "mode": "force-https" },
+ { "name": "www.simbolo.co.uk", "mode": "force-https" },
+ { "name": "zenpayroll.com", "mode": "force-https" },
+ { "name": "www.zenpayroll.com", "mode": "force-https" },
+ { "name": "get.zenpayroll.com", "mode": "force-https" },
+ { "name": "errors.zenpayroll.com", "mode": "force-https" },
+ { "name": "manage.zenpayroll.com", "mode": "force-https" },
+ { "name": "gernert-server.de", "include_subdomains": true, "mode": "force-https" },
+ { "name": "skydrive.live.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "lifeguard.aecom.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "data.qld.gov.au", "mode": "force-https" },
+ { "name": "publications.qld.gov.au", "mode": "force-https" },
+ { "name": "go.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "login.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "my.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "payroll.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "in.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "api.xero.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "eff.org", "include_subdomains": true, "mode": "force-https" },
+ { "name": "mail.de", "include_subdomains": true, "mode": "force-https" },
// Entries that are only valid if the client supports SNI.
{ "name": "gmail.com", "mode": "force-https", "pins": "google", "snionly": true },
diff --git a/chromium/net/http/transport_security_state_unittest.cc b/chromium/net/http/transport_security_state_unittest.cc
index 936d5628249..c3d15da29f9 100644
--- a/chromium/net/http/transport_security_state_unittest.cc
+++ b/chromium/net/http/transport_security_state_unittest.cc
@@ -117,6 +117,19 @@ TEST_F(TransportSecurityStateTest, SubdomainMatches) {
EXPECT_FALSE(state.GetDomainState("com", true, &domain_state));
}
+TEST_F(TransportSecurityStateTest, InvalidDomains) {
+ TransportSecurityState state;
+ TransportSecurityState::DomainState domain_state;
+ const base::Time current_time(base::Time::Now());
+ const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
+
+ EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
+ bool include_subdomains = true;
+ state.AddHSTS("yahoo.com", expiry, include_subdomains);
+ EXPECT_TRUE(state.GetDomainState("www-.foo.yahoo.com", true, &domain_state));
+ EXPECT_TRUE(state.GetDomainState("2\x01.foo.yahoo.com", true, &domain_state));
+}
+
TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) {
TransportSecurityState state;
TransportSecurityState::DomainState domain_state;
@@ -506,7 +519,8 @@ TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
EXPECT_TRUE(HasPublicKeyPins("apis.google.com"));
EXPECT_TRUE(HasPublicKeyPins("ssl.gstatic.com"));
- EXPECT_FALSE(HasPublicKeyPins("www.gstatic.com"));
+ EXPECT_TRUE(HasPublicKeyPins("gstatic.com"));
+ EXPECT_TRUE(HasPublicKeyPins("www.gstatic.com"));
EXPECT_TRUE(HasPublicKeyPins("ssl.google-analytics.com"));
EXPECT_TRUE(HasPublicKeyPins("www.googleplex.com"));
@@ -521,7 +535,6 @@ TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
EXPECT_TRUE(HasPublicKeyPins("business.twitter.com"));
EXPECT_TRUE(HasPublicKeyPins("platform.twitter.com"));
EXPECT_TRUE(HasPublicKeyPins("si0.twimg.com"));
- EXPECT_TRUE(HasPublicKeyPins("twimg0-a.akamaihd.net"));
}
static bool AddHash(const std::string& type_and_base64,
@@ -534,43 +547,6 @@ static bool AddHash(const std::string& type_and_base64,
return true;
}
-TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCerts) {
- // kGoodPath is plus.google.com via Google Internet Authority.
- static const char* kGoodPath[] = {
- "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
- "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=",
- "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
- NULL,
- };
-
- // kBadPath is plus.google.com via Trustcenter, which contains a required
- // certificate (Equifax root), but also an excluded certificate
- // (Trustcenter).
- static const char* kBadPath[] = {
- "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
- "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
- "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
- NULL,
- };
-
- HashValueVector good_hashes, bad_hashes;
-
- for (size_t i = 0; kGoodPath[i]; i++) {
- EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
- }
- for (size_t i = 0; kBadPath[i]; i++) {
- EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
- }
-
- TransportSecurityState state;
- TransportSecurityState::DomainState domain_state;
- EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state));
- EXPECT_TRUE(domain_state.HasPublicKeyPins());
-
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(good_hashes));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes));
-}
-
TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) {
// kGoodPath is blog.torproject.org.
static const char* kGoodPath[] = {
@@ -607,100 +583,6 @@ TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) {
EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes));
}
-TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCertsMixedHashes) {
- static const char* ee_sha1 = "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=";
- static const char* ee_sha256 =
- "sha256/sRJBQqWhpaKIGcc1NA7/jJ4vgWj+47oYfyU7waOS1+I=";
- static const char* google_1024_sha1 = "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=";
- static const char* google_1024_sha256 =
- "sha256/trlUMquuV/4CDLK3T0+fkXPIxwivyecyrOIyeQR8bQU=";
- static const char* equifax_sha1 = "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=";
- static const char* equifax_sha256 =
- "sha256//1aAzXOlcD2gSBegdf1GJQanNQbEuBoVg+9UlHjSZHY=";
- static const char* trustcenter_sha1 = "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=";
- static const char* trustcenter_sha256 =
- "sha256/Dq58KIA4NMLsboWMLU8/aTREzaAGEFW+EtUule8dd/M=";
-
- // Good chains for plus.google.com chain up through google_1024_sha{1,256}
- // to equifax_sha{1,256}. Bad chains chain up to Equifax through
- // trustcenter_sha{1,256}, which is a blacklisted key. Even though Equifax
- // and Google1024 are known-good, the blacklistedness of Trustcenter
- // should override and cause pin validation failure.
-
- TransportSecurityState state;
- TransportSecurityState::DomainState domain_state;
- EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state));
- EXPECT_TRUE(domain_state.HasPublicKeyPins());
-
- // The statically-defined pins are all SHA-1, so we add some SHA-256 pins
- // manually:
- EXPECT_TRUE(AddHash(google_1024_sha256, &domain_state.static_spki_hashes));
- EXPECT_TRUE(AddHash(trustcenter_sha256,
- &domain_state.bad_static_spki_hashes));
-
- // Try an all-good SHA1 chain.
- HashValueVector validated_chain;
- EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try an all-bad SHA1 chain.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(trustcenter_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try an all-good SHA-256 chain.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(google_1024_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try an all-bad SHA-256 chain.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try a mixed-hash good chain.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try a mixed-hash bad chain.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try a chain with all good hashes.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(google_1024_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(validated_chain));
-
- // Try a chain with all bad hashes.
- validated_chain.clear();
- EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(trustcenter_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
- EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
- EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(validated_chain));
-}
-
TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) {
TransportSecurityState state;
TransportSecurityState::DomainState domain_state;
@@ -744,38 +626,6 @@ TEST_F(TransportSecurityStateTest, OverrideBuiltins) {
EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state));
}
-static const uint8 kSidePinLeafSPKI[] = {
- 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
- 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xe4,
- 0x1d, 0xcc, 0xf2, 0x92, 0xe7, 0x7a, 0xc6, 0x36, 0xf7, 0x1a, 0x62, 0x31, 0x7d,
- 0x37, 0xea, 0x0d, 0xa2, 0xa8, 0x12, 0x2b, 0xc2, 0x1c, 0x82, 0x3e, 0xa5, 0x70,
- 0x4a, 0x83, 0x5d, 0x9b, 0x84, 0x82, 0x70, 0xa4, 0x88, 0x98, 0x98, 0x41, 0x29,
- 0x31, 0xcb, 0x6e, 0x2a, 0x54, 0x65, 0x14, 0x60, 0xcc, 0x00, 0xe8, 0x10, 0x30,
- 0x0a, 0x4a, 0xd1, 0xa7, 0x52, 0xfe, 0x2d, 0x31, 0x2a, 0x1d, 0x0d, 0x02, 0x03,
- 0x01, 0x00, 0x01,
-};
-
-static const uint8 kSidePinInfo[] = {
- 0x01, 0x00, 0x53, 0x50, 0x49, 0x4e, 0xa0, 0x00, 0x03, 0x00, 0x53, 0x49, 0x47,
- 0x00, 0x50, 0x55, 0x42, 0x4b, 0x41, 0x4c, 0x47, 0x4f, 0x47, 0x00, 0x41, 0x00,
- 0x04, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xfb, 0x26, 0xd5, 0xe8, 0x76, 0x35,
- 0x96, 0x6d, 0x91, 0x9b, 0x5b, 0x27, 0xe6, 0x09, 0x1c, 0x7b, 0x6c, 0xcd, 0xc8,
- 0x10, 0x25, 0x95, 0xc0, 0xa5, 0xf6, 0x6c, 0x6f, 0xfb, 0x59, 0x1e, 0x2d, 0xf4,
- 0x02, 0x20, 0x33, 0x0a, 0xf8, 0x8b, 0x3e, 0xc4, 0xca, 0x75, 0x28, 0xdf, 0x5f,
- 0xab, 0xe4, 0x46, 0xa0, 0xdd, 0x2d, 0xe5, 0xad, 0xc3, 0x81, 0x44, 0x70, 0xb2,
- 0x10, 0x87, 0xe8, 0xc3, 0xd6, 0x6e, 0x12, 0x5d, 0x04, 0x67, 0x0b, 0x7d, 0xf2,
- 0x99, 0x75, 0x57, 0x99, 0x3a, 0x98, 0xf8, 0xe4, 0xdf, 0x79, 0xdf, 0x8e, 0x02,
- 0x2c, 0xbe, 0xd8, 0xfd, 0x75, 0x80, 0x18, 0xb1, 0x6f, 0x43, 0xd9, 0x8a, 0x79,
- 0xc3, 0x6e, 0x18, 0xdf, 0x79, 0xc0, 0x59, 0xab, 0xd6, 0x77, 0x37, 0x6a, 0x94,
- 0x5a, 0x7e, 0xfb, 0xa9, 0xc5, 0x54, 0x14, 0x3a, 0x7b, 0x97, 0x17, 0x2a, 0xb6,
- 0x1e, 0x59, 0x4f, 0x2f, 0xb1, 0x15, 0x1a, 0x34, 0x50, 0x32, 0x35, 0x36,
-};
-
-static const uint8 kSidePinExpectedHash[20] = {
- 0xb5, 0x91, 0x66, 0x47, 0x43, 0x16, 0x62, 0x86, 0xd4, 0x1e, 0x5d, 0x36, 0xe1,
- 0xc4, 0x09, 0x3d, 0x2d, 0x1d, 0xea, 0x1e,
-};
-
TEST_F(TransportSecurityStateTest, GooglePinnedProperties) {
EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
"www.example.com", true));