summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-28 21:49:31 +0100
committerKristian Monsen <kristianm@google.com>2011-07-08 17:55:00 +0100
commitddb351dbec246cf1fab5ec20d2d5520909041de1 (patch)
tree158e3fb57bdcac07c7f1e767fde3c70687c9fbb1 /net/http
parent6b92e04f5f151c896e3088e86f70db7081009308 (diff)
downloadexternal_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.zip
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.gz
external_chromium-ddb351dbec246cf1fab5ec20d2d5520909041de1.tar.bz2
Merge Chromium at r12.0.742.93: Initial merge by git
Change-Id: Ic5ee2fec31358bbee305f7e915442377bfa6cda6
Diffstat (limited to 'net/http')
-rw-r--r--net/http/des.cc16
-rw-r--r--net/http/disk_cache_based_ssl_host_info.h6
-rw-r--r--net/http/http_auth.h4
-rw-r--r--net/http/http_auth_cache.h4
-rw-r--r--net/http/http_auth_controller.cc54
-rw-r--r--net/http/http_auth_controller.h11
-rw-r--r--net/http/http_auth_controller_unittest.cc112
-rw-r--r--net/http/http_auth_filter_unittest.cc4
-rw-r--r--net/http/http_auth_gssapi_posix.cc5
-rw-r--r--net/http/http_auth_gssapi_posix_unittest.cc4
-rw-r--r--net/http/http_auth_handler_basic_unittest.cc4
-rw-r--r--net/http/http_auth_handler_digest.h4
-rw-r--r--net/http/http_auth_handler_factory.h4
-rw-r--r--net/http/http_auth_handler_factory_unittest.cc4
-rw-r--r--net/http/http_auth_unittest.cc6
-rw-r--r--net/http/http_basic_stream.cc10
-rw-r--r--net/http/http_basic_stream.h39
-rw-r--r--net/http/http_cache.cc4
-rw-r--r--net/http/http_cache.h6
-rw-r--r--net/http/http_cache_transaction.cc165
-rw-r--r--net/http/http_cache_transaction.h11
-rw-r--r--net/http/http_cache_unittest.cc100
-rw-r--r--net/http/http_net_log_params.h4
-rw-r--r--net/http/http_network_layer.cc2
-rw-r--r--net/http/http_network_layer.h6
-rw-r--r--net/http/http_network_session.cc4
-rw-r--r--net/http/http_network_session.h8
-rw-r--r--net/http/http_network_session_peer.cc7
-rw-r--r--net/http/http_network_session_peer.h8
-rw-r--r--net/http/http_network_transaction.cc169
-rw-r--r--net/http/http_network_transaction.h15
-rw-r--r--net/http/http_network_transaction_unittest.cc468
-rw-r--r--net/http/http_proxy_client_socket.cc4
-rw-r--r--net/http/http_proxy_client_socket.h5
-rw-r--r--net/http/http_proxy_client_socket_pool.cc81
-rw-r--r--net/http/http_proxy_client_socket_pool.h63
-rw-r--r--net/http/http_proxy_client_socket_pool_unittest.cc27
-rw-r--r--net/http/http_request_info.cc3
-rw-r--r--net/http/http_request_info.h8
-rw-r--r--net/http/http_response_body_drainer.h6
-rw-r--r--net/http/http_response_body_drainer_unittest.cc36
-rw-r--r--net/http/http_response_headers.h4
-rw-r--r--net/http/http_response_info.cc30
-rw-r--r--net/http/http_response_info.h4
-rw-r--r--net/http/http_stream.h10
-rw-r--r--net/http/http_stream_factory.cc13
-rw-r--r--net/http/http_stream_factory.h16
-rw-r--r--net/http/http_stream_factory_impl.cc114
-rw-r--r--net/http/http_stream_factory_impl.h14
-rw-r--r--net/http/http_stream_factory_impl_job.cc439
-rw-r--r--net/http/http_stream_factory_impl_job.h125
-rw-r--r--net/http/http_stream_factory_impl_request.cc34
-rw-r--r--net/http/http_stream_factory_impl_request.h7
-rw-r--r--net/http/http_stream_factory_impl_unittest.cc22
-rw-r--r--net/http/http_stream_parser.cc6
-rw-r--r--net/http/http_stream_parser.h4
-rw-r--r--net/http/http_transaction_factory.h4
-rw-r--r--net/http/http_util.cc97
-rw-r--r--net/http/http_util.h21
-rw-r--r--net/http/partial_data.cc5
-rw-r--r--net/http/url_security_manager.h4
-rw-r--r--net/http/url_security_manager_win.cc6
62 files changed, 1510 insertions, 970 deletions
diff --git a/net/http/des.cc b/net/http/des.cc
index 30706e9..e9d6388 100644
--- a/net/http/des.cc
+++ b/net/http/des.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,17 +8,17 @@
#if defined(USE_OPENSSL)
#include <openssl/des.h>
-#include "base/openssl_util.h"
+#include "crypto/openssl_util.h"
#elif defined(USE_NSS)
#include <nss.h>
#include <pk11pub.h>
-#include "base/nss_util.h"
+#include "crypto/nss_util.h"
#elif defined(OS_MACOSX)
#include <CommonCrypto/CommonCryptor.h>
#elif defined(OS_WIN)
#include <windows.h>
#include <wincrypt.h>
-#include "base/crypto/scoped_capi_types.h"
+#include "crypto/scoped_capi_types.h"
#endif
// The Mac and Windows (CryptoAPI) versions of DESEncrypt are our own code.
@@ -90,7 +90,7 @@ void DESMakeKey(const uint8* raw, uint8* key) {
#if defined(USE_OPENSSL)
void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
- base::EnsureOpenSSLInit();
+ crypto::EnsureOpenSSLInit();
DES_key_schedule ks;
DES_set_key_unchecked(
@@ -112,7 +112,7 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
SECStatus rv;
unsigned int n;
- base::EnsureNSSInit();
+ crypto::EnsureNSSInit();
slot = PK11_GetBestSlot(cipher_mech, NULL);
if (!slot)
@@ -171,7 +171,7 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
#elif defined(OS_WIN)
void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
- base::ScopedHCRYPTPROV provider;
+ crypto::ScopedHCRYPTPROV provider;
if (!CryptAcquireContext(provider.receive(), NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
return;
@@ -191,7 +191,7 @@ void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
key_blob.key_size = 8; // 64 bits
memcpy(key_blob.key_data, key, 8);
- base::ScopedHCRYPTKEY key;
+ crypto::ScopedHCRYPTKEY key;
BOOL import_ok = CryptImportKey(provider,
reinterpret_cast<BYTE*>(&key_blob),
sizeof key_blob, 0, 0, key.receive());
diff --git a/net/http/disk_cache_based_ssl_host_info.h b/net/http/disk_cache_based_ssl_host_info.h
index 905a3a9..1df838c 100644
--- a/net/http/disk_cache_based_ssl_host_info.h
+++ b/net/http/disk_cache_based_ssl_host_info.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,9 +7,9 @@
#include <string>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
-#include "base/weak_ptr.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/disk_cache.h"
#include "net/socket/ssl_host_info.h"
diff --git a/net/http/http_auth.h b/net/http/http_auth.h
index cc147a2..99c3c81 100644
--- a/net/http/http_auth.h
+++ b/net/http/http_auth.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <set>
#include <string>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "net/http/http_util.h"
diff --git a/net/http/http_auth_cache.h b/net/http/http_auth_cache.h
index 965cff7..e8f7f16 100644
--- a/net/http/http_auth_cache.h
+++ b/net/http/http_auth_cache.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,7 +10,7 @@
#include <string>
#include "base/gtest_prod_util.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/string16.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_auth.h"
diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc
index 52fc3f1..f337c30 100644
--- a/net/http/http_auth_controller.cc
+++ b/net/http/http_auth_controller.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -192,13 +192,12 @@ int HttpAuthController::MaybeGenerateAuthToken(const HttpRequestInfo* request,
request,
&io_callback_,
&auth_token_);
+ if (DisableOnAuthHandlerResult(rv))
+ rv = OK;
if (rv == ERR_IO_PENDING)
user_callback_ = callback;
else
OnIOComplete(rv);
- // This error occurs with GSSAPI, if the user has not already logged in.
- if (rv == ERR_MISSING_AUTH_CREDENTIALS)
- rv = OK;
return rv;
}
@@ -244,9 +243,13 @@ void HttpAuthController::AddAuthorizationHeader(
HttpRequestHeaders* authorization_headers) {
DCHECK(CalledOnValidThread());
DCHECK(HaveAuth());
- authorization_headers->SetHeader(
- HttpAuth::GetAuthorizationHeaderName(target_), auth_token_);
- auth_token_.clear();
+ // auth_token_ can be empty if we encountered a permanent error with
+ // the auth scheme and want to retry.
+ if (!auth_token_.empty()) {
+ authorization_headers->SetHeader(
+ HttpAuth::GetAuthorizationHeaderName(target_), auth_token_);
+ auth_token_.clear();
+ }
}
int HttpAuthController::HandleAuthChallenge(
@@ -498,15 +501,40 @@ void HttpAuthController::PopulateAuthChallenge() {
auth_info_->realm = ASCIIToWide(handler_->realm());
}
+bool HttpAuthController::DisableOnAuthHandlerResult(int result) {
+ DCHECK(CalledOnValidThread());
+
+ switch (result) {
+ // Occurs with GSSAPI, if the user has not already logged in.
+ case ERR_MISSING_AUTH_CREDENTIALS:
+
+ // Can occur with GSSAPI or SSPI if the underlying library reports
+ // a permanent error.
+ case ERR_UNSUPPORTED_AUTH_SCHEME:
+
+ // These two error codes represent failures we aren't handling.
+ case ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS:
+ case ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS:
+
+ // Can be returned by SSPI if the authenticating authority or
+ // target is not known.
+ case ERR_MISCONFIGURED_AUTH_ENVIRONMENT:
+
+ // In these cases, disable the current scheme as it cannot
+ // succeed.
+ DisableAuthScheme(handler_->auth_scheme());
+ auth_token_.clear();
+ return true;
+
+ default:
+ return false;
+ }
+}
+
void HttpAuthController::OnIOComplete(int result) {
DCHECK(CalledOnValidThread());
- // This error occurs with GSSAPI, if the user has not already logged in.
- // In that case, disable the current scheme as it cannot succeed.
- if (result == ERR_MISSING_AUTH_CREDENTIALS) {
- DisableAuthScheme(handler_->auth_scheme());
- auth_token_.clear();
+ if (DisableOnAuthHandlerResult(result))
result = OK;
- }
if (user_callback_) {
CompletionCallback* c = user_callback_;
user_callback_ = NULL;
diff --git a/net/http/http_auth_controller.h b/net/http/http_auth_controller.h
index d7faaac..8fed8c8 100644
--- a/net/http/http_auth_controller.h
+++ b/net/http/http_auth_controller.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,8 +10,8 @@
#include <string>
#include "base/basictypes.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "base/threading/non_thread_safe.h"
#include "googleurl/src/gurl.h"
@@ -107,6 +107,11 @@ class HttpAuthController : public base::RefCounted<HttpAuthController>,
// URLRequestHttpJob can prompt for a username/password.
void PopulateAuthChallenge();
+ // If |result| indicates a permanent failure, disables the current
+ // auth scheme for this controller and returns true. Returns false
+ // otherwise.
+ bool DisableOnAuthHandlerResult(int result);
+
void OnIOComplete(int result);
// Indicates if this handler is for Proxy auth or Server auth.
diff --git a/net/http/http_auth_controller_unittest.cc b/net/http/http_auth_controller_unittest.cc
new file mode 100644
index 0000000..f324e66
--- /dev/null
+++ b/net/http/http_auth_controller_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2011 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_auth_controller.h"
+
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/test_completion_callback.h"
+#include "net/http/http_auth_cache.h"
+#include "net/http/http_auth_handler_mock.h"
+#include "net/http/http_request_info.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+enum HandlerRunMode {
+ RUN_HANDLER_SYNC,
+ RUN_HANDLER_ASYNC
+};
+
+enum SchemeState {
+ SCHEME_IS_DISABLED,
+ SCHEME_IS_ENABLED
+};
+
+// Runs an HttpAuthController with a single round mock auth handler
+// that returns |handler_rv| on token generation. The handler runs in
+// async if |run_mode| is RUN_HANDLER_ASYNC. Upon completion, the
+// return value of the controller is tested against
+// |expected_controller_rv|. |scheme_state| indicates whether the
+// auth scheme used should be disabled after this run.
+void RunSingleRoundAuthTest(HandlerRunMode run_mode,
+ int handler_rv,
+ int expected_controller_rv,
+ SchemeState scheme_state) {
+ BoundNetLog dummy_log;
+ HttpAuthCache dummy_auth_cache;
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://example.com");
+
+ const std::string headers_raw_string =
+ "HTTP/1.1 407\r\n"
+ "Proxy-Authenticate: MOCK foo\r\n"
+ "\r\n";
+ std::string headers_string = HttpUtil::AssembleRawHeaders(
+ headers_raw_string.c_str(), headers_raw_string.length());
+ scoped_refptr<HttpResponseHeaders> headers(
+ new HttpResponseHeaders(headers_string));
+
+ HttpAuthHandlerMock::Factory auth_handler_factory;
+ HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock();
+ auth_handler->SetGenerateExpectation((run_mode == RUN_HANDLER_ASYNC),
+ handler_rv);
+ auth_handler_factory.set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY);
+ auth_handler_factory.set_do_init_from_challenge(true);
+
+ scoped_refptr<HttpAuthController> controller(
+ new HttpAuthController(HttpAuth::AUTH_PROXY,
+ GURL("http://example.com"),
+ &dummy_auth_cache, &auth_handler_factory));
+ ASSERT_EQ(OK,
+ controller->HandleAuthChallenge(headers, false, false, dummy_log));
+ EXPECT_TRUE(controller->HaveAuthHandler());
+ controller->ResetAuth(string16(), string16());
+ EXPECT_TRUE(controller->HaveAuth());
+
+ TestCompletionCallback callback;
+ EXPECT_EQ((run_mode == RUN_HANDLER_ASYNC)? ERR_IO_PENDING:
+ expected_controller_rv,
+ controller->MaybeGenerateAuthToken(&request, &callback,
+ dummy_log));
+ if (run_mode == RUN_HANDLER_ASYNC)
+ EXPECT_EQ(expected_controller_rv, callback.WaitForResult());
+ EXPECT_EQ((scheme_state == SCHEME_IS_DISABLED),
+ controller->IsAuthSchemeDisabled(HttpAuth::AUTH_SCHEME_MOCK));
+}
+
+} // namespace
+
+// If an HttpAuthHandler returns an error code that indicates a
+// permanent error, the HttpAuthController should disable the scheme
+// used and retry the request.
+TEST(HttpAuthControllerTest, PermanentErrors) {
+
+ // Run a synchronous handler that returns
+ // ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS. We expect a return value
+ // of OK from the controller so we can retry the request.
+ RunSingleRoundAuthTest(RUN_HANDLER_SYNC,
+ ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS,
+ OK, SCHEME_IS_DISABLED);
+
+ // Now try an async handler that returns
+ // ERR_MISSING_AUTH_CREDENTIALS. Async and sync handlers invoke
+ // different code paths in HttpAuthController when generating
+ // tokens.
+ RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_MISSING_AUTH_CREDENTIALS, OK,
+ SCHEME_IS_DISABLED);
+
+ // If a non-permanent error is returned by the handler, then the
+ // controller should report it unchanged.
+ RunSingleRoundAuthTest(RUN_HANDLER_ASYNC, ERR_INVALID_AUTH_CREDENTIALS,
+ ERR_INVALID_AUTH_CREDENTIALS, SCHEME_IS_ENABLED);
+}
+
+} // namespace net
diff --git a/net/http/http_auth_filter_unittest.cc b/net/http/http_auth_filter_unittest.cc
index c7f91f9..73f649e 100644
--- a/net/http/http_auth_filter_unittest.cc
+++ b/net/http/http_auth_filter_unittest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 <iostream>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_auth_filter.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/net/http/http_auth_gssapi_posix.cc b/net/http/http_auth_gssapi_posix.cc
index 9a69ec3..8a39688 100644
--- a/net/http/http_auth_gssapi_posix.cc
+++ b/net/http/http_auth_gssapi_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -437,6 +437,7 @@ base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() {
#else
"libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian
"libgssapi.so.4", // Heimdal - Suse10, MDK
+ "libgssapi.so.2", // Heimdal - Gentoo
"libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10
#endif
};
@@ -451,7 +452,7 @@ base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() {
// TODO(asanka): Move library loading to a separate thread.
// http://crbug.com/66702
base::ThreadRestrictions::ScopedAllowIO allow_io_temporarily;
- base::NativeLibrary lib = base::LoadNativeLibrary(file_path);
+ base::NativeLibrary lib = base::LoadNativeLibrary(file_path, NULL);
if (lib) {
// Only return this library if we can bind the functions we need.
if (BindMethods(lib))
diff --git a/net/http/http_auth_gssapi_posix_unittest.cc b/net/http/http_auth_gssapi_posix_unittest.cc
index 43a3285..01a62b3 100644
--- a/net/http/http_auth_gssapi_posix_unittest.cc
+++ b/net/http/http_auth_gssapi_posix_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,8 @@
#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/native_library.h"
-#include "base/scoped_ptr.h"
#include "net/base/net_errors.h"
#include "net/http/mock_gssapi_library_posix.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/net/http/http_auth_handler_basic_unittest.cc b/net/http/http_auth_handler_basic_unittest.cc
index 51352da..b75e2c9 100644
--- a/net/http/http_auth_handler_basic_unittest.cc
+++ b/net/http/http_auth_handler_basic_unittest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 <string>
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_errors.h"
diff --git a/net/http/http_auth_handler_digest.h b/net/http/http_auth_handler_digest.h
index fca77e4..f279b65 100644
--- a/net/http/http_auth_handler_digest.h
+++ b/net/http/http_auth_handler_digest.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,7 +10,7 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
diff --git a/net/http/http_auth_handler_factory.h b/net/http/http_auth_handler_factory.h
index 1e4134f..c5cf98e 100644
--- a/net/http/http_auth_handler_factory.h
+++ b/net/http/http_auth_handler_factory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,7 +10,7 @@
#include <string>
#include <vector>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "net/http/http_auth.h"
#include "net/http/url_security_manager.h"
diff --git a/net/http/http_auth_handler_factory_unittest.cc b/net/http/http_auth_handler_factory_unittest.cc
index 3145c4b..81c4af6 100644
--- a/net/http/http_auth_handler_factory_unittest.cc
+++ b/net/http/http_auth_handler_factory_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth_handler.h"
diff --git a/net/http/http_auth_unittest.cc b/net/http/http_auth_unittest.cc
index 6788be2..fe11c03 100644
--- a/net/http/http_auth_unittest.cc
+++ b/net/http/http_auth_unittest.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 <set>
#include <string>
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc
index 3e69d7a..6501a59 100644
--- a/net/http/http_basic_stream.cc
+++ b/net/http/http_basic_stream.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -102,6 +102,10 @@ void HttpBasicStream::SetConnectionReused() {
parser_->SetConnectionReused();
}
+bool HttpBasicStream::IsConnectionReusable() const {
+ return parser_->IsConnectionReusable();
+}
+
void HttpBasicStream::GetSSLInfo(SSLInfo* ssl_info) {
parser_->GetSSLInfo(ssl_info);
}
@@ -111,4 +115,8 @@ void HttpBasicStream::GetSSLCertRequestInfo(
parser_->GetSSLCertRequestInfo(cert_request_info);
}
+bool HttpBasicStream::IsSpdyHttpStream() const {
+ return false;
+}
+
} // namespace net
diff --git a/net/http/http_basic_stream.h b/net/http/http_basic_stream.h
index 918596a..267c7c1 100644
--- a/net/http/http_basic_stream.h
+++ b/net/http/http_basic_stream.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -13,7 +13,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "net/http/http_stream.h"
namespace net {
@@ -42,39 +42,44 @@ class HttpBasicStream : public HttpStream {
// HttpStream methods:
virtual int InitializeStream(const HttpRequestInfo* request_info,
const BoundNetLog& net_log,
- CompletionCallback* callback);
+ CompletionCallback* callback) OVERRIDE;
virtual int SendRequest(const HttpRequestHeaders& headers,
UploadDataStream* request_body,
HttpResponseInfo* response,
- CompletionCallback* callback);
+ CompletionCallback* callback) OVERRIDE;
- virtual uint64 GetUploadProgress() const;
+ virtual uint64 GetUploadProgress() const OVERRIDE;
- virtual int ReadResponseHeaders(CompletionCallback* callback);
+ virtual int ReadResponseHeaders(CompletionCallback* callback) OVERRIDE;
- virtual const HttpResponseInfo* GetResponseInfo() const;
+ virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE;
virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
- CompletionCallback* callback);
+ CompletionCallback* callback) OVERRIDE;
- virtual void Close(bool not_reusable);
+ virtual void Close(bool not_reusable) OVERRIDE;
- virtual HttpStream* RenewStreamForAuth();
+ virtual HttpStream* RenewStreamForAuth() OVERRIDE;
- virtual bool IsResponseBodyComplete() const;
+ virtual bool IsResponseBodyComplete() const OVERRIDE;
- virtual bool CanFindEndOfResponse() const;
+ virtual bool CanFindEndOfResponse() const OVERRIDE;
- virtual bool IsMoreDataBuffered() const;
+ virtual bool IsMoreDataBuffered() const OVERRIDE;
- virtual bool IsConnectionReused() const;
+ virtual bool IsConnectionReused() const OVERRIDE;
- virtual void SetConnectionReused();
+ virtual void SetConnectionReused() OVERRIDE;
- virtual void GetSSLInfo(SSLInfo* ssl_info);
+ virtual bool IsConnectionReusable() const OVERRIDE;
- virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+ virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
+
+ virtual void GetSSLCertRequestInfo(
+ SSLCertRequestInfo* cert_request_info) OVERRIDE;
+
+ virtual bool IsSpdyHttpStream() const OVERRIDE;
private:
scoped_refptr<GrowableIOBuffer> read_buf_;
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 830fbaa..3943619 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,9 +14,9 @@
#include "base/callback.h"
#include "base/format_macros.h"
+#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/pickle.h"
-#include "base/ref_counted.h"
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index b33689d..f1c5fbe 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -22,11 +22,11 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/hash_tables.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop_proxy.h"
-#include "base/scoped_ptr.h"
#include "base/task.h"
#include "base/threading/non_thread_safe.h"
-#include "base/weak_ptr.h"
#include "net/base/cache_type.h"
#include "net/base/completion_callback.h"
#include "net/base/load_states.h"
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 6665d5f..a12a64f 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -13,9 +13,9 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
-#include "base/ref_counted.h"
#include "base/string_util.h"
#include "base/time.h"
#include "net/base/cert_status_flags.h"
@@ -23,10 +23,12 @@
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
+#include "net/base/network_delegate.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_config_service.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/disk_cache_based_ssl_host_info.h"
+#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_transaction.h"
@@ -179,19 +181,6 @@ int HttpCache::Transaction::WriteMetadata(IOBuffer* buf, int buf_len,
callback, true);
}
-// Histogram data from the end of 2010 show the following distribution of
-// response headers:
-//
-// Content-Length............... 87%
-// Date......................... 98%
-// Last-Modified................ 49%
-// Etag......................... 19%
-// Accept-Ranges: bytes......... 25%
-// Accept-Ranges: none.......... 0.4%
-// Strong Validator............. 50%
-// Strong Validator + ranges.... 24%
-// Strong Validator + CL........ 49%
-//
bool HttpCache::Transaction::AddTruncatedFlag() {
DCHECK(mode_ & WRITE);
@@ -199,13 +188,7 @@ bool HttpCache::Transaction::AddTruncatedFlag() {
if (partial_.get() && !truncated_)
return true;
- // Double check that there is something worth keeping.
- if (!entry_->disk_entry->GetDataSize(kResponseContentIndex))
- return false;
-
- if (response_.headers->GetContentLength() <= 0 ||
- response_.headers->HasHeaderValue("Accept-Ranges", "none") ||
- !response_.headers->HasStrongValidators())
+ if (!CanResume(true))
return false;
truncated_ = true;
@@ -486,6 +469,13 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_ADD_TO_ENTRY_COMPLETE:
rv = DoAddToEntryComplete(rv);
break;
+ case STATE_NOTIFY_BEFORE_SEND_HEADERS:
+ DCHECK_EQ(OK, rv);
+ rv = DoNotifyBeforeSendHeaders();
+ break;
+ case STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE:
+ rv = DoNotifyBeforeSendHeadersComplete(rv);
+ break;
case STATE_START_PARTIAL_CACHE_VALIDATION:
DCHECK_EQ(OK, rv);
rv = DoStartPartialCacheValidation();
@@ -909,6 +899,57 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) {
return OK;
}
+int HttpCache::Transaction::DoNotifyBeforeSendHeaders() {
+ // Balanced in DoNotifyBeforeSendHeadersComplete.
+ cache_callback_->AddRef();
+ next_state_ = STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE;
+
+ if (cache_->GetSession() && cache_->GetSession()->network_delegate()) {
+ // TODO(mpcomplete): need to be able to modify these headers.
+ HttpRequestHeaders headers = request_->extra_headers;
+ return cache_->GetSession()->network_delegate()->NotifyBeforeSendHeaders(
+ request_->request_id, cache_callback_, &headers);
+ }
+
+ return OK;
+}
+
+int HttpCache::Transaction::DoNotifyBeforeSendHeadersComplete(int result) {
+ cache_callback_->Release(); // Balanced in DoNotifyBeforeSendHeaders.
+
+ // We now have access to the cache entry.
+ //
+ // o if we are a reader for the transaction, then we can start reading the
+ // cache entry.
+ //
+ // o if we can read or write, then we should check if the cache entry needs
+ // to be validated and then issue a network request if needed or just read
+ // from the cache if the cache entry is already valid.
+ //
+ // o if we are set to UPDATE, then we are handling an externally
+ // conditionalized request (if-modified-since / if-none-match). We check
+ // if the request headers define a validation request.
+ //
+ if (result == net::OK) {
+ switch (mode_) {
+ case READ:
+ result = BeginCacheRead();
+ break;
+ case READ_WRITE:
+ result = BeginPartialCacheValidation();
+ break;
+ case UPDATE:
+ result = BeginExternallyConditionalizedRequest();
+ break;
+ case WRITE:
+ default:
+ NOTREACHED();
+ result = ERR_FAILED;
+ }
+ }
+ return result;
+}
+
// We may end up here multiple times for a given request.
int HttpCache::Transaction::DoStartPartialCacheValidation() {
if (mode_ == NONE)
@@ -1013,6 +1054,16 @@ int HttpCache::Transaction::DoOverwriteCachedResponse() {
partial_->FixContentLength(new_response_->headers);
response_ = *new_response_;
+
+ if (server_responded_206_ && !CanResume(false)) {
+ // There is no point in storing this resource because it will never be used.
+ DoneWritingToEntry(false);
+ if (partial_.get())
+ partial_->FixResponseHeaders(response_.headers, true);
+ next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
+ return OK;
+ }
+
target_state_ = STATE_TRUNCATE_CACHED_DATA;
next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE :
STATE_CACHE_WRITE_RESPONSE;
@@ -1109,6 +1160,7 @@ int HttpCache::Transaction::DoCacheReadResponse() {
int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
cache_callback_->Release(); // Balance the AddRef from DoCacheReadResponse.
+
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
if (result != io_buf_len_ ||
!HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_,
@@ -1117,35 +1169,8 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
return ERR_CACHE_READ_FAILURE;
}
- // We now have access to the cache entry.
- //
- // o if we are a reader for the transaction, then we can start reading the
- // cache entry.
- //
- // o if we can read or write, then we should check if the cache entry needs
- // to be validated and then issue a network request if needed or just read
- // from the cache if the cache entry is already valid.
- //
- // o if we are set to UPDATE, then we are handling an externally
- // conditionalized request (if-modified-since / if-none-match). We check
- // if the request headers define a validation request.
- //
- switch (mode_) {
- case READ:
- result = BeginCacheRead();
- break;
- case READ_WRITE:
- result = BeginPartialCacheValidation();
- break;
- case UPDATE:
- result = BeginExternallyConditionalizedRequest();
- break;
- case WRITE:
- default:
- NOTREACHED();
- result = ERR_FAILED;
- }
- return result;
+ next_state_ = STATE_NOTIFY_BEFORE_SEND_HEADERS;
+ return OK;
}
int HttpCache::Transaction::DoCacheWriteResponse() {
@@ -1480,8 +1505,11 @@ int HttpCache::Transaction::BeginCacheValidation() {
// response. If we cannot do so, then we just resort to a normal fetch.
// Our mode remains READ_WRITE for a conditional request. We'll switch to
// either READ or WRITE mode once we hear back from the server.
- if (!ConditionalizeRequest())
+ if (!ConditionalizeRequest()) {
+ DCHECK(!partial_.get());
+ DCHECK_NE(206, response_.headers->response_code());
mode_ = WRITE;
+ }
next_state_ = STATE_SEND_REQUEST;
}
return OK;
@@ -1634,6 +1662,10 @@ bool HttpCache::Transaction::ConditionalizeRequest() {
response_.headers->response_code() != 206)
return false;
+ // We should have handled this case before.
+ DCHECK(response_.headers->response_code() != 206 ||
+ response_.headers->HasStrongValidators());
+
// Just use the first available ETag and/or Last-Modified header value.
// TODO(darin): Or should we use the last?
@@ -1936,6 +1968,35 @@ int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) {
return result;
}
+// Histogram data from the end of 2010 show the following distribution of
+// response headers:
+//
+// Content-Length............... 87%
+// Date......................... 98%
+// Last-Modified................ 49%
+// Etag......................... 19%
+// Accept-Ranges: bytes......... 25%
+// Accept-Ranges: none.......... 0.4%
+// Strong Validator............. 50%
+// Strong Validator + ranges.... 24%
+// Strong Validator + CL........ 49%
+//
+bool HttpCache::Transaction::CanResume(bool has_data) {
+ // Double check that there is something worth keeping.
+ if (has_data && !entry_->disk_entry->GetDataSize(kResponseContentIndex))
+ return false;
+
+ if (request_->method != "GET")
+ return false;
+
+ if (response_.headers->GetContentLength() <= 0 ||
+ response_.headers->HasHeaderValue("Accept-Ranges", "none") ||
+ !response_.headers->HasStrongValidators())
+ return false;
+
+ return true;
+}
+
void HttpCache::Transaction::OnIOComplete(int result) {
DoLoop(result);
}
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index 81160d5..945a70e 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -141,6 +141,8 @@ class HttpCache::Transaction : public HttpTransaction {
STATE_DOOM_ENTRY_COMPLETE,
STATE_ADD_TO_ENTRY,
STATE_ADD_TO_ENTRY_COMPLETE,
+ STATE_NOTIFY_BEFORE_SEND_HEADERS,
+ STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE,
STATE_START_PARTIAL_CACHE_VALIDATION,
STATE_COMPLETE_PARTIAL_CACHE_VALIDATION,
STATE_UPDATE_CACHED_RESPONSE,
@@ -195,6 +197,8 @@ class HttpCache::Transaction : public HttpTransaction {
int DoDoomEntryComplete(int result);
int DoAddToEntry();
int DoAddToEntryComplete(int result);
+ int DoNotifyBeforeSendHeaders();
+ int DoNotifyBeforeSendHeadersComplete(int result);
int DoStartPartialCacheValidation();
int DoCompletePartialCacheValidation(int result);
int DoUpdateCachedResponse();
@@ -314,6 +318,11 @@ class HttpCache::Transaction : public HttpTransaction {
// working with range requests.
int DoPartialCacheReadCompleted(int result);
+ // Returns true if we should bother attempting to resume this request if it
+ // is aborted while in progress. If |has_data| is true, the size of the stored
+ // data is considered for the result.
+ bool CanResume(bool has_data);
+
// Called to signal completion of asynchronous IO.
void OnIOComplete(int result);
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 52e48e6..5e52c31 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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_cache.h"
#include "base/hash_tables.h"
+#include "base/memory/scoped_vector.h"
#include "base/message_loop.h"
-#include "base/scoped_vector.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "net/base/cache_type.h"
@@ -1176,6 +1176,29 @@ TEST(HttpCache, SimpleGETWithDiskFailures2) {
EXPECT_EQ(2, cache.disk_cache()->create_count());
}
+// Tests that we don't crash after failures to read from the cache.
+TEST(HttpCache, SimpleGETWithDiskFailures3) {
+ MockHttpCache cache;
+
+ // Read from the network, and write to the cache.
+ RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
+
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(1, cache.disk_cache()->create_count());
+
+ cache.disk_cache()->set_soft_failures(true);
+
+ // Now fail to read from the cache.
+ scoped_ptr<Context> c(new Context());
+ int rv = cache.http_cache()->CreateTransaction(&c->trans);
+ EXPECT_EQ(net::OK, rv);
+
+ MockHttpRequest request(kSimpleGET_Transaction);
+ rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
+ EXPECT_EQ(net::ERR_CACHE_READ_FAILURE, c->callback.GetResult(rv));
+}
+
TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
MockHttpCache cache;
@@ -2877,6 +2900,35 @@ TEST(HttpCache, GET_Crazy206) {
RemoveMockTransaction(&transaction);
}
+// Tests that we don't cache partial responses that can't be validated.
+TEST(HttpCache, RangeGET_NoStrongValidators) {
+ MockHttpCache cache;
+ std::string headers;
+
+ // Attempt to write to the cache (40-49).
+ MockTransaction transaction(kRangeGET_TransactionOK);
+ AddMockTransaction(&transaction);
+ transaction.response_headers = "Content-Length: 10\n"
+ "ETag: w/\"foo\"\n";
+ RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
+
+ Verify206Response(headers, 40, 49);
+ 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.
+ RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
+ &headers);
+
+ Verify206Response(headers, 40, 49);
+ EXPECT_EQ(2, cache.network_layer()->transaction_count());
+ EXPECT_EQ(0, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, 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) {
@@ -3425,6 +3477,49 @@ TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
RemoveMockTransaction(&kRangeGET_TransactionOK);
}
+// Tests that we can handle cached 206 responses that can't be validated.
+TEST(HttpCache, GET_Previous206_NotValidation) {
+ MockHttpCache cache;
+
+ // Create a disk cache entry that stores 206 headers.
+ disk_cache::Entry* entry;
+ ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
+ NULL));
+
+ // Make sure that the headers cannot be validated with the server.
+ std::string raw_headers(kRangeGET_TransactionOK.status);
+ raw_headers.append("\n");
+ raw_headers.append("Content-Length: 80\n");
+ raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
+ raw_headers.size());
+
+ net::HttpResponseInfo response;
+ response.headers = new net::HttpResponseHeaders(raw_headers);
+ EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
+
+ scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
+ int len = static_cast<int>(base::strlcpy(buf->data(),
+ kRangeGET_TransactionOK.data, 500));
+ TestCompletionCallback cb;
+ int rv = entry->WriteData(1, 0, buf, len, &cb, true);
+ EXPECT_EQ(len, cb.GetResult(rv));
+ entry->Close();
+
+ // Now see that we don't use the stored entry.
+ std::string headers;
+ RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
+ &headers);
+
+ // We are expecting a 200.
+ std::string expected_headers(kSimpleGET_Transaction.status);
+ expected_headers.append("\n");
+ expected_headers.append(kSimpleGET_Transaction.response_headers);
+ EXPECT_EQ(expected_headers, headers);
+ EXPECT_EQ(1, cache.network_layer()->transaction_count());
+ EXPECT_EQ(1, cache.disk_cache()->open_count());
+ EXPECT_EQ(2, cache.disk_cache()->create_count());
+}
+
// Tests that we can handle range requests with cached 200 responses.
TEST(HttpCache, RangeGET_Previous200) {
MockHttpCache cache;
@@ -3823,6 +3918,7 @@ TEST(HttpCache, RangeGET_LargeValues) {
transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
EXTRA_HEADER;
transaction.response_headers =
+ "ETag: \"foo\"\n"
"Content-Range: bytes 4294967288-4294967297/4294967299\n"
"Content-Length: 10\n";
AddMockTransaction(&transaction);
diff --git a/net/http/http_net_log_params.h b/net/http/http_net_log_params.h
index c32250e..92039ca 100644
--- a/net/http/http_net_log_params.h
+++ b/net/http/http_net_log_params.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "net/base/net_log.h"
#include "net/http/http_request_headers.h"
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 0fb1050..ce3fab8 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h
index db3d809..f4843fe 100644
--- a/net/http/http_network_layer.h
+++ b/net/http/http_network_layer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,8 +8,8 @@
#include <string>
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "net/http/http_transaction_factory.h"
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index e67390c..d13ec97 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -40,7 +40,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params)
params.ssl_host_info_factory,
params.proxy_service,
params.ssl_config_service),
- spdy_session_pool_(params.ssl_config_service),
+ spdy_session_pool_(params.host_resolver, params.ssl_config_service),
ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_factory_(
new HttpStreamFactoryImpl(this))) {
DCHECK(params.proxy_service);
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 9a4b85c..14b85ae 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,7 +7,7 @@
#pragma once
#include <set>
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
#include "net/base/host_port_pair.h"
#include "net/base/host_resolver.h"
@@ -87,8 +87,8 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>,
return &alternate_protocols_;
}
- TCPClientSocketPool* tcp_socket_pool() {
- return socket_pool_manager_.tcp_socket_pool();
+ TransportClientSocketPool* transport_socket_pool() {
+ return socket_pool_manager_.transport_socket_pool();
}
SSLClientSocketPool* ssl_socket_pool() {
diff --git a/net/http/http_network_session_peer.cc b/net/http/http_network_session_peer.cc
index 2ed3e76..921322a 100644
--- a/net/http/http_network_session_peer.cc
+++ b/net/http/http_network_session_peer.cc
@@ -9,7 +9,7 @@
#include "net/proxy/proxy_service.h"
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket_pool.h"
-#include "net/socket/tcp_client_socket_pool.h"
+#include "net/socket/transport_client_socket_pool.h"
namespace net {
@@ -19,8 +19,9 @@ HttpNetworkSessionPeer::HttpNetworkSessionPeer(
HttpNetworkSessionPeer::~HttpNetworkSessionPeer() {}
-void HttpNetworkSessionPeer::SetTCPSocketPool(TCPClientSocketPool* pool) {
- session_->socket_pool_manager_.tcp_socket_pool_.reset(pool);
+void HttpNetworkSessionPeer::SetTransportSocketPool(
+ TransportClientSocketPool* pool) {
+ session_->socket_pool_manager_.transport_socket_pool_.reset(pool);
}
void HttpNetworkSessionPeer::SetSocketPoolForSOCKSProxy(
diff --git a/net/http/http_network_session_peer.h b/net/http/http_network_session_peer.h
index 06101ca..51b1f81 100644
--- a/net/http/http_network_session_peer.h
+++ b/net/http/http_network_session_peer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,7 @@
#define NET_HTTP_HTTP_NETWORK_SESSION_PEER_H_
#pragma once
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
namespace net {
@@ -17,7 +17,7 @@ class HttpStreamFactory;
class ProxyService;
class SOCKSClientSocketPool;
class SSLClientSocketPool;
-class TCPClientSocketPool;
+class TransportClientSocketPool;
class HttpNetworkSessionPeer {
public:
@@ -25,7 +25,7 @@ class HttpNetworkSessionPeer {
const scoped_refptr<HttpNetworkSession>& session);
~HttpNetworkSessionPeer();
- void SetTCPSocketPool(TCPClientSocketPool* pool);
+ void SetTransportSocketPool(TransportClientSocketPool* pool);
void SetSocketPoolForSOCKSProxy(
const HostPortPair& socks_proxy,
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index d3ed391..55330e2 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,10 +9,10 @@
#include "base/compiler_specific.h"
#include "base/format_macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
-#include "base/scoped_ptr.h"
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
@@ -20,6 +20,7 @@
#include "build/build_config.h"
#include "googleurl/src/gurl.h"
#include "net/base/auth.h"
+#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
@@ -49,7 +50,7 @@
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
-#include "net/socket/tcp_client_socket_pool.h"
+#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/spdy_http_stream.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
@@ -98,6 +99,9 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
: pending_auth_target_(HttpAuth::AUTH_NONE),
ALLOW_THIS_IN_INITIALIZER_LIST(
io_callback_(this, &HttpNetworkTransaction::OnIOComplete)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(delegate_callback_(
+ new CancelableCompletionCallback<HttpNetworkTransaction>(
+ this, &HttpNetworkTransaction::OnIOComplete))),
user_callback_(NULL),
session_(session),
request_(NULL),
@@ -128,6 +132,9 @@ HttpNetworkTransaction::~HttpNetworkTransaction() {
if (stream_->IsResponseBodyComplete()) {
// If the response body is complete, we can just reuse the socket.
stream_->Close(false /* reusable */);
+ } else if (stream_->IsSpdyHttpStream()) {
+ // Doesn't really matter for SpdyHttpStream. Just close it.
+ stream_->Close(true /* not reusable */);
} else {
// Otherwise, we try to drain the response body.
// TODO(willchan): Consider moving this response body draining to the
@@ -142,6 +149,8 @@ HttpNetworkTransaction::~HttpNetworkTransaction() {
}
}
}
+
+ delegate_callback_->Cancel();
}
int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
@@ -264,7 +273,7 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
if (stream_.get()) {
HttpStream* new_stream = NULL;
- if (keep_alive) {
+ if (keep_alive && stream_->IsConnectionReusable()) {
// We should call connection_->set_idle_time(), but this doesn't occur
// often enough to be worth the trouble.
stream_->SetConnectionReused();
@@ -272,7 +281,10 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) {
}
if (!new_stream) {
- stream_->Close(!keep_alive);
+ // Close the stream and mark it as not_reusable. Even in the
+ // keep_alive case, we've determined that the stream_ is not
+ // reusable if new_stream is NULL.
+ stream_->Close(true);
next_state_ = STATE_CREATE_STREAM;
} else {
next_state_ = STATE_INIT_STREAM;
@@ -368,8 +380,6 @@ void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config,
stream_.reset(stream);
ssl_config_ = used_ssl_config;
proxy_info_ = used_proxy_info;
- response_.was_alternate_protocol_available =
- stream_request_->was_alternate_protocol_available();
response_.was_npn_negotiated = stream_request_->was_npn_negotiated();
response_.was_fetched_via_spdy = stream_request_->using_spdy();
response_.was_fetched_via_proxy = !proxy_info_.is_direct();
@@ -512,9 +522,16 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
rv = DoGenerateServerAuthTokenComplete(rv);
break;
- case STATE_SEND_REQUEST:
+ case STATE_BUILD_REQUEST:
DCHECK_EQ(OK, rv);
net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, NULL);
+ rv = DoBuildRequest();
+ break;
+ case STATE_BUILD_REQUEST_COMPLETE:
+ rv = DoBuildRequestComplete(rv);
+ break;
+ case STATE_SEND_REQUEST:
+ DCHECK_EQ(OK, rv);
rv = DoSendRequest();
break;
case STATE_SEND_REQUEST_COMPLETE:
@@ -659,38 +676,123 @@ int HttpNetworkTransaction::DoGenerateServerAuthToken() {
int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
DCHECK_NE(ERR_IO_PENDING, rv);
if (rv == OK)
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_BUILD_REQUEST;
return rv;
}
-int HttpNetworkTransaction::DoSendRequest() {
- next_state_ = STATE_SEND_REQUEST_COMPLETE;
+void HttpNetworkTransaction::BuildRequestHeaders(bool using_proxy) {
+ request_headers_.SetHeader(HttpRequestHeaders::kHost,
+ GetHostAndOptionalPort(request_->url));
- UploadDataStream* request_body = NULL;
+ // For compat with HTTP/1.0 servers and proxies:
+ if (using_proxy) {
+ request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection,
+ "keep-alive");
+ } else {
+ request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
+ }
+
+ // Our consumer should have made sure that this is a safe referrer. See for
+ // instance WebCore::FrameLoader::HideReferrer.
+ if (request_->referrer.is_valid()) {
+ request_headers_.SetHeader(HttpRequestHeaders::kReferer,
+ request_->referrer.spec());
+ }
+
+ // Add a content length header?
+ if (request_body_.get()) {
+ if (request_body_->is_chunked()) {
+ request_headers_.SetHeader(
+ HttpRequestHeaders::kTransferEncoding, "chunked");
+ } else {
+ request_headers_.SetHeader(
+ HttpRequestHeaders::kContentLength,
+ base::Uint64ToString(request_body_->size()));
+ }
+ } else if (request_->method == "POST" || request_->method == "PUT" ||
+ request_->method == "HEAD") {
+ // An empty POST/PUT request still needs a content length. As for HEAD,
+ // IE and Safari also add a content length header. Presumably it is to
+ // support sending a HEAD request to an URL that only expects to be sent a
+ // POST or some other method that normally would have a message body.
+ request_headers_.SetHeader(HttpRequestHeaders::kContentLength, "0");
+ }
+
+ // Honor load flags that impact proxy caches.
+ if (request_->load_flags & LOAD_BYPASS_CACHE) {
+ request_headers_.SetHeader(HttpRequestHeaders::kPragma, "no-cache");
+ request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "no-cache");
+ } else if (request_->load_flags & LOAD_VALIDATE_CACHE) {
+ request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "max-age=0");
+ }
+
+ if (ShouldApplyProxyAuth() && HaveAuth(HttpAuth::AUTH_PROXY))
+ auth_controllers_[HttpAuth::AUTH_PROXY]->AddAuthorizationHeader(
+ &request_headers_);
+ if (ShouldApplyServerAuth() && HaveAuth(HttpAuth::AUTH_SERVER))
+ auth_controllers_[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader(
+ &request_headers_);
+
+ // Headers that will be stripped from request_->extra_headers to prevent,
+ // e.g., plugins from overriding headers that are controlled using other
+ // means. Otherwise a plugin could set a referrer although sending the
+ // referrer is inhibited.
+ // TODO(jochen): check whether also other headers should be stripped.
+ static const char* const kExtraHeadersToBeStripped[] = {
+ "Referer"
+ };
+
+ HttpRequestHeaders stripped_extra_headers;
+ stripped_extra_headers.CopyFrom(request_->extra_headers);
+ for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i)
+ stripped_extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
+ request_headers_.MergeFrom(stripped_extra_headers);
+}
+
+int HttpNetworkTransaction::DoBuildRequest() {
+ next_state_ = STATE_BUILD_REQUEST_COMPLETE;
+ delegate_callback_->AddRef(); // balanced in DoSendRequestComplete
+
+ request_body_.reset(NULL);
if (request_->upload_data) {
int error_code;
- request_body = UploadDataStream::Create(request_->upload_data, &error_code);
- if (!request_body)
+ request_body_.reset(
+ UploadDataStream::Create(request_->upload_data, &error_code));
+ if (!request_body_.get())
return error_code;
}
+ headers_valid_ = false;
+
// This is constructed lazily (instead of within our Start method), so that
// we have proxy info available.
if (request_headers_.IsEmpty()) {
- bool using_proxy = (proxy_info_.is_http()|| proxy_info_.is_https()) &&
+ bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) &&
!is_https_request();
- HttpUtil::BuildRequestHeaders(request_, request_body, auth_controllers_,
- ShouldApplyServerAuth(),
- ShouldApplyProxyAuth(), using_proxy,
- &request_headers_);
+ BuildRequestHeaders(using_proxy);
+ }
- if (session_->network_delegate())
- session_->network_delegate()->NotifySendHttpRequest(&request_headers_);
+ if (session_->network_delegate()) {
+ return session_->network_delegate()->NotifyBeforeSendHeaders(
+ request_->request_id, delegate_callback_, &request_headers_);
}
- headers_valid_ = false;
- return stream_->SendRequest(request_headers_, request_body, &response_,
- &io_callback_);
+ return OK;
+}
+
+int HttpNetworkTransaction::DoBuildRequestComplete(int result) {
+ delegate_callback_->Release(); // balanced in DoBuildRequest
+
+ if (result == OK)
+ next_state_ = STATE_SEND_REQUEST;
+ return result;
+}
+
+int HttpNetworkTransaction::DoSendRequest() {
+ next_state_ = STATE_SEND_REQUEST_COMPLETE;
+
+ return stream_->SendRequest(
+ request_headers_, request_body_.release(), &response_, &io_callback_);
}
int HttpNetworkTransaction::DoSendRequestComplete(int result) {
@@ -1062,26 +1164,16 @@ int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
case ERR_SSL_BAD_RECORD_MAC_ALERT:
- if (ssl_config_.tls1_enabled &&
- !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) {
+ if (ssl_config_.tls1_enabled) {
// This could be a TLS-intolerant server, an SSL 3.0 server that
// chose a TLS-only cipher suite or a server with buggy DEFLATE
// support. Turn off TLS 1.0, DEFLATE support and retry.
- session_->http_stream_factory()->AddTLSIntolerantServer(request_->url);
+ session_->http_stream_factory()->AddTLSIntolerantServer(
+ HostPortPair::FromURL(request_->url));
ResetConnectionAndRequestForResend();
error = OK;
}
break;
- case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
- // This means that we tried to Snap Start a connection, but we
- // mispredicted the NPN result. This isn't a problem from the point of
- // view of the SSL layer because the server will ignore the application
- // data in the Snap Start extension. However, at the HTTP layer, we have
- // already decided that it's a HTTP or SPDY connection and it's easier to
- // abort and start again.
- ResetConnectionAndRequestForResend();
- error = OK;
- break;
}
return error;
}
@@ -1206,7 +1298,6 @@ bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const {
auth_controllers_[target]->HaveAuth();
}
-
GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const {
switch (target) {
case HttpAuth::AUTH_PROXY: {
@@ -1235,6 +1326,8 @@ std::string HttpNetworkTransaction::DescribeState(State state) {
switch (state) {
STATE_CASE(STATE_CREATE_STREAM);
STATE_CASE(STATE_CREATE_STREAM_COMPLETE);
+ STATE_CASE(STATE_BUILD_REQUEST);
+ STATE_CASE(STATE_BUILD_REQUEST_COMPLETE);
STATE_CASE(STATE_SEND_REQUEST);
STATE_CASE(STATE_SEND_REQUEST_COMPLETE);
STATE_CASE(STATE_READ_HEADERS);
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 3cec010..00e9a65 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -10,8 +10,8 @@
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "net/base/net_log.h"
#include "net/base/request_priority.h"
@@ -94,6 +94,8 @@ class HttpNetworkTransaction : public HttpTransaction,
STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
STATE_GENERATE_SERVER_AUTH_TOKEN,
STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
+ STATE_BUILD_REQUEST,
+ STATE_BUILD_REQUEST_COMPLETE,
STATE_SEND_REQUEST,
STATE_SEND_REQUEST_COMPLETE,
STATE_READ_HEADERS,
@@ -125,6 +127,8 @@ class HttpNetworkTransaction : public HttpTransaction,
int DoGenerateProxyAuthTokenComplete(int result);
int DoGenerateServerAuthToken();
int DoGenerateServerAuthTokenComplete(int result);
+ int DoBuildRequest();
+ int DoBuildRequestComplete(int result);
int DoSendRequest();
int DoSendRequestComplete(int result);
int DoReadHeaders();
@@ -134,6 +138,8 @@ class HttpNetworkTransaction : public HttpTransaction,
int DoDrainBodyForAuthRestart();
int DoDrainBodyForAuthRestartComplete(int result);
+ void BuildRequestHeaders(bool using_proxy);
+
// Record histogram of time until first byte of header is received.
void LogTransactionConnectedMetrics();
@@ -217,7 +223,10 @@ class HttpNetworkTransaction : public HttpTransaction,
HttpAuth::Target pending_auth_target_;
CompletionCallbackImpl<HttpNetworkTransaction> io_callback_;
+ scoped_refptr<CancelableCompletionCallback<HttpNetworkTransaction> >
+ delegate_callback_;
CompletionCallback* user_callback_;
+ scoped_ptr<UploadDataStream> request_body_;
scoped_refptr<HttpNetworkSession> session_;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index ecd6132..b614ec8 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,7 +11,7 @@
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/file_util.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "net/base/auth.h"
#include "net/base/capturing_net_log.h"
@@ -295,8 +295,8 @@ class CaptureGroupNameSocketPool : public ParentPool {
std::string last_group_name_;
};
-typedef CaptureGroupNameSocketPool<TCPClientSocketPool>
-CaptureGroupNameTCPSocketPool;
+typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
+CaptureGroupNameTransportSocketPool;
typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
CaptureGroupNameHttpProxySocketPool;
typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
@@ -1192,9 +1192,18 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
MockRead("Hello"),
};
+ // If there is a regression where we disconnect a Keep-Alive
+ // connection during an auth roundtrip, we'll end up reading this.
+ MockRead data_reads2[] = {
+ MockRead(false, ERR_FAILED),
+ };
+
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ NULL, 0);
session_deps.socket_factory.AddSocketDataProvider(&data1);
+ session_deps.socket_factory.AddSocketDataProvider(&data2);
TestCompletionCallback callback1;
@@ -1224,7 +1233,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
EXPECT_EQ(OK, rv);
response = trans->GetResponseInfo();
- EXPECT_FALSE(response == NULL);
+ ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
EXPECT_EQ(5, response->headers->GetContentLength());
}
@@ -1265,9 +1274,17 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
MockRead("hello"),
};
+ // An incorrect reconnect would cause this to be read.
+ MockRead data_reads2[] = {
+ MockRead(false, ERR_FAILED),
+ };
+
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ NULL, 0);
session_deps.socket_factory.AddSocketDataProvider(&data1);
+ session_deps.socket_factory.AddSocketDataProvider(&data2);
TestCompletionCallback callback1;
@@ -1297,7 +1314,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
EXPECT_EQ(OK, rv);
response = trans->GetResponseInfo();
- EXPECT_FALSE(response == NULL);
+ ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
EXPECT_EQ(5, response->headers->GetContentLength());
}
@@ -1346,9 +1363,17 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
MockRead("hello"),
};
+ // An incorrect reconnect would cause this to be read.
+ MockRead data_reads2[] = {
+ MockRead(false, ERR_FAILED),
+ };
+
StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
data_writes1, arraysize(data_writes1));
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ NULL, 0);
session_deps.socket_factory.AddSocketDataProvider(&data1);
+ session_deps.socket_factory.AddSocketDataProvider(&data2);
TestCompletionCallback callback1;
@@ -1378,7 +1403,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
EXPECT_EQ(OK, rv);
response = trans->GetResponseInfo();
- EXPECT_FALSE(response == NULL);
+ ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
EXPECT_EQ(5, response->headers->GetContentLength());
}
@@ -3120,7 +3145,7 @@ TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
// Make sure that we don't try to reuse a TCPClientSocket when failing to
// establish tunnel.
// http://code.google.com/p/chromium/issues/detail?id=3772
-TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) {
+TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
HttpRequestInfo request;
request.method = "GET";
request.url = GURL("https://www.google.com/");
@@ -3170,11 +3195,11 @@ TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) {
// We now check to make sure the TCPClientSocket was not added back to
// the pool.
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
trans.reset();
MessageLoop::current()->RunAllPending();
// Make sure that the socket didn't get recycled after calling the destructor.
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
}
// Make sure that we recycle a socket after reading all of the response body.
@@ -3217,7 +3242,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
std::string status_line = response->headers->GetStatusLine();
EXPECT_EQ("HTTP/1.1 200 OK", status_line);
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -3229,7 +3254,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
MessageLoop::current()->RunAllPending();
// We now check to make sure the socket was added back to the pool.
- EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount());
}
// Make sure that we recycle a SSL socket after reading all of the response
@@ -3276,7 +3301,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
ASSERT_TRUE(response->headers != NULL);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -3344,7 +3369,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
ASSERT_TRUE(response->headers != NULL);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -3372,7 +3397,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
ASSERT_TRUE(response->headers != NULL);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
rv = ReadTransaction(trans.get(), &response_data);
EXPECT_EQ(OK, rv);
@@ -3428,7 +3453,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
std::string status_line = response->headers->GetStatusLine();
EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
- EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
std::string response_data;
rv = ReadTransaction(trans.get(), &response_data);
@@ -3440,7 +3465,7 @@ TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
MessageLoop::current()->RunAllPending();
// We now check to make sure the socket was added back to the pool.
- EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount());
+ EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount());
}
TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
@@ -5439,9 +5464,8 @@ struct GroupNameTest {
};
scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
- const std::string& proxy_server) {
- SessionDependencies session_deps(ProxyService::CreateFixed(proxy_server));
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+ SessionDependencies* session_deps) {
+ scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps));
HttpAlternateProtocols* alternate_protocols =
session->mutable_alternate_protocols();
@@ -5507,13 +5531,15 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
HttpStreamFactory::set_use_alternate_protocols(true);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed(tests[i].proxy_server));
scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(tests[i].proxy_server));
+ SetupSessionForGroupNameTests(&session_deps));
HttpNetworkSessionPeer peer(session);
- CaptureGroupNameTCPSocketPool* tcp_conn_pool =
- new CaptureGroupNameTCPSocketPool(NULL, NULL);
- peer.SetTCPSocketPool(tcp_conn_pool);
+ CaptureGroupNameTransportSocketPool* transport_conn_pool =
+ new CaptureGroupNameTransportSocketPool(NULL, NULL);
+ peer.SetTransportSocketPool(transport_conn_pool);
CaptureGroupNameSSLSocketPool* ssl_conn_pool =
new CaptureGroupNameSSLSocketPool(NULL, NULL);
peer.SetSSLSocketPool(ssl_conn_pool);
@@ -5525,7 +5551,7 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
ssl_conn_pool->last_group_name_received());
else
EXPECT_EQ(tests[i].expected_group_name,
- tcp_conn_pool->last_group_name_received());
+ transport_conn_pool->last_group_name_received());
}
HttpStreamFactory::set_use_alternate_protocols(false);
@@ -5559,8 +5585,10 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
HttpStreamFactory::set_use_alternate_protocols(true);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed(tests[i].proxy_server));
scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(tests[i].proxy_server));
+ SetupSessionForGroupNameTests(&session_deps));
HttpNetworkSessionPeer peer(session);
@@ -5625,8 +5653,11 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
HttpStreamFactory::set_use_alternate_protocols(true);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ SessionDependencies session_deps(
+ ProxyService::CreateFixed(tests[i].proxy_server));
scoped_refptr<HttpNetworkSession> session(
- SetupSessionForGroupNameTests(tests[i].proxy_server));
+ SetupSessionForGroupNameTests(&session_deps));
+
HttpNetworkSessionPeer peer(session);
HostPortPair proxy_host("socks_proxy", 1080);
@@ -6437,7 +6468,6 @@ TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
EXPECT_FALSE(response->was_fetched_via_spdy);
EXPECT_FALSE(response->was_npn_negotiated);
- EXPECT_FALSE(response->was_alternate_protocol_available);
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
@@ -6455,7 +6485,7 @@ TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
HttpStreamFactory::set_next_protos("");
}
-TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocol) {
+TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
HttpStreamFactory::set_use_alternate_protocols(true);
SessionDependencies session_deps;
@@ -6478,11 +6508,6 @@ TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocol) {
data_reads, arraysize(data_reads), NULL, 0);
session_deps.socket_factory.AddSocketDataProvider(&second_data);
- // TODO(willchan): Delete this extra data provider. It's necessary due to a
- // ClientSocketPoolBaseHelper bug that starts up too many ConnectJobs:
- // http://crbug.com/37454.
- session_deps.socket_factory.AddSocketDataProvider(&second_data);
-
TestCompletionCallback callback;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
@@ -6517,60 +6542,7 @@ TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocol) {
HttpStreamFactory::set_use_alternate_protocols(false);
}
-// TODO(willchan): Redo this test to use TLS/NPN=>SPDY. Currently, the code
-// says that it does SPDY, but it just does the TLS handshake, but the NPN
-// response does not indicate SPDY, so we just do standard HTTPS over the port.
-// We should add code such that we don't fallback to HTTPS, but fallback to HTTP
-// on the original port.
-// TEST_F(HttpNetworkTransactionTest, UseAlternateProtocol) {
-// SessionDependencies session_deps;
-//
-// HttpRequestInfo request;
-// request.method = "GET";
-// request.url = GURL("http://www.google.com/");
-// request.load_flags = 0;
-//
-// MockRead data_reads[] = {
-// MockRead("HTTP/1.1 200 OK\r\n\r\n"),
-// MockRead("hello world"),
-// MockRead(true, OK),
-// };
-// StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
-// session_deps.socket_factory.AddSocketDataProvider(&data);
-//
-// SSLSocketDataProvider ssl(true, OK);
-// session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
-//
-// TestCompletionCallback callback;
-//
-// scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
-//
-// HostPortPair http_host_port_pair;
-// http_host_port_pair.host = "www.google.com";
-// http_host_port_pair.port = 80;
-// HttpAlternateProtocols* alternate_protocols =
-// session->mutable_alternate_protocols();
-// alternate_protocols->SetAlternateProtocolFor(
-// http_host_port_pair, 1234 /* port is ignored */,
-// HttpAlternateProtocols::NPN_SPDY_1);
-//
-// scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
-//
-// int rv = trans->Start(&request, &callback, BoundNetLog());
-// EXPECT_EQ(ERR_IO_PENDING, rv);
-// EXPECT_EQ(OK, callback.WaitForResult());
-//
-// const HttpResponseInfo* response = trans->GetResponseInfo();
-// ASSERT_TRUE(response != NULL);
-// ASSERT_TRUE(response->headers != NULL);
-// EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
-//
-// std::string response_data;
-// ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
-// EXPECT_EQ("hello world", response_data);
-// }
-
-TEST_F(HttpNetworkTransactionTest, FailNpnSpdyAndFallback) {
+TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
HttpStreamFactory::set_use_alternate_protocols(true);
HttpStreamFactory::set_next_protos(kExpectedNPNString);
SessionDependencies session_deps;
@@ -6580,33 +6552,53 @@ TEST_F(HttpNetworkTransactionTest, FailNpnSpdyAndFallback) {
request.url = GURL("http://www.google.com/");
request.load_flags = 0;
- StaticSocketDataProvider first_tcp_connect;
- session_deps.socket_factory.AddSocketDataProvider(&first_tcp_connect);
-
- SSLSocketDataProvider ssl(true, OK);
- session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
-
MockRead data_reads[] = {
- MockRead("HTTP/1.1 200 OK\r\n\r\n"),
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kAlternateProtocolHttpHeader),
MockRead("hello world"),
MockRead(true, OK),
};
- StaticSocketDataProvider fallback_data(
+
+ StaticSocketDataProvider first_transaction(
data_reads, arraysize(data_reads), NULL, 0);
- session_deps.socket_factory.AddSocketDataProvider(&fallback_data);
+ session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
- TestCompletionCallback callback;
+ SSLSocketDataProvider ssl(true, OK);
+ ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
+ ssl.next_proto = "spdy/2";
+ ssl.was_npn_negotiated = true;
+ session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+ scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+ MockWrite spdy_writes[] = { CreateMockWrite(*req) };
- HostPortPair http_host_port_pair("www.google.com", 80);
- HttpAlternateProtocols* alternate_protocols =
- session->mutable_alternate_protocols();
- alternate_protocols->SetAlternateProtocolFor(
- http_host_port_pair, 1234 /* port is ignored */,
- HttpAlternateProtocols::NPN_SPDY_2);
+ scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
+ MockRead spdy_reads[] = {
+ CreateMockRead(*resp),
+ CreateMockRead(*data),
+ MockRead(true, 0, 0),
+ };
- scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
+ scoped_refptr<DelayedSocketData> spdy_data(
+ new DelayedSocketData(
+ 1, // wait for one write to finish before reading.
+ spdy_reads, arraysize(spdy_reads),
+ spdy_writes, arraysize(spdy_writes)));
+ session_deps.socket_factory.AddSocketDataProvider(spdy_data);
+
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ StaticSocketDataProvider hanging_non_alternate_protocol_socket(
+ NULL, 0, NULL, 0);
+ hanging_non_alternate_protocol_socket.set_connect_data(
+ never_finishing_connect);
+ session_deps.socket_factory.AddSocketDataProvider(
+ &hanging_non_alternate_protocol_socket);
+
+ TestCompletionCallback callback;
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+ scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
int rv = trans->Start(&request, &callback, BoundNetLog());
EXPECT_EQ(ERR_IO_PENDING, rv);
@@ -6620,11 +6612,28 @@ TEST_F(HttpNetworkTransactionTest, FailNpnSpdyAndFallback) {
std::string response_data;
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
EXPECT_EQ("hello world", response_data);
+
+ trans.reset(new HttpNetworkTransaction(session));
+
+ rv = trans->Start(&request, &callback, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback.WaitForResult());
+
+ response = trans->GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_TRUE(response->was_fetched_via_spdy);
+ EXPECT_TRUE(response->was_npn_negotiated);
+
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
+ EXPECT_EQ("hello!", response_data);
+
HttpStreamFactory::set_next_protos("");
HttpStreamFactory::set_use_alternate_protocols(false);
}
-TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
+TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
HttpStreamFactory::set_use_alternate_protocols(true);
HttpStreamFactory::set_next_protos(kExpectedNPNString);
SessionDependencies session_deps;
@@ -6643,32 +6652,143 @@ TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
StaticSocketDataProvider first_transaction(
data_reads, arraysize(data_reads), NULL, 0);
+ // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ StaticSocketDataProvider hanging_socket(
+ NULL, 0, NULL, 0);
+ hanging_socket.set_connect_data(never_finishing_connect);
+ // Socket 2 and 3 are the hanging Alternate-Protocol and
+ // non-Alternate-Protocol jobs from the 2nd transaction.
+ session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
+ session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
+
SSLSocketDataProvider ssl(true, OK);
ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
ssl.next_proto = "spdy/2";
ssl.was_npn_negotiated = true;
session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
- scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
- MockWrite spdy_writes[] = { CreateMockWrite(*req) };
-
- scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
+ scoped_ptr<spdy::SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
+ scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
+ MockWrite spdy_writes[] = {
+ CreateMockWrite(*req1),
+ CreateMockWrite(*req2),
+ };
+ scoped_ptr<spdy::SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
+ scoped_ptr<spdy::SpdyFrame> data1(ConstructSpdyBodyFrame(1, true));
+ scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
+ scoped_ptr<spdy::SpdyFrame> data2(ConstructSpdyBodyFrame(3, true));
MockRead spdy_reads[] = {
- CreateMockRead(*resp),
- CreateMockRead(*data),
+ CreateMockRead(*resp1),
+ CreateMockRead(*data1),
+ CreateMockRead(*resp2),
+ CreateMockRead(*data2),
MockRead(true, 0, 0),
};
scoped_refptr<DelayedSocketData> spdy_data(
new DelayedSocketData(
- 1, // wait for one write to finish before reading.
+ 2, // wait for writes to finish before reading.
spdy_reads, arraysize(spdy_reads),
spdy_writes, arraysize(spdy_writes)));
+ // Socket 4 is the successful Alternate-Protocol for transaction 3.
session_deps.socket_factory.AddSocketDataProvider(spdy_data);
+ // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
+ session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
+
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
+ TestCompletionCallback callback1;
+ HttpNetworkTransaction trans1(session);
+
+ int rv = trans1.Start(&request, &callback1, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+ EXPECT_EQ(OK, callback1.WaitForResult());
+
+ const HttpResponseInfo* response = trans1.GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
+ EXPECT_EQ("hello world", response_data);
+
+ TestCompletionCallback callback2;
+ HttpNetworkTransaction trans2(session);
+ rv = trans2.Start(&request, &callback2, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ TestCompletionCallback callback3;
+ HttpNetworkTransaction trans3(session);
+ rv = trans3.Start(&request, &callback3, BoundNetLog());
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_EQ(OK, callback3.WaitForResult());
+
+ response = trans2.GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_TRUE(response->was_fetched_via_spdy);
+ EXPECT_TRUE(response->was_npn_negotiated);
+ ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
+ EXPECT_EQ("hello!", response_data);
+
+ response = trans3.GetResponseInfo();
+ ASSERT_TRUE(response != NULL);
+ ASSERT_TRUE(response->headers != NULL);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_TRUE(response->was_fetched_via_spdy);
+ EXPECT_TRUE(response->was_npn_negotiated);
+ ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
+ EXPECT_EQ("hello!", response_data);
+
+ HttpStreamFactory::set_next_protos("");
+ HttpStreamFactory::set_use_alternate_protocols(false);
+}
+
+TEST_F(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
+ HttpStreamFactory::set_use_alternate_protocols(true);
+ HttpStreamFactory::set_next_protos(kExpectedNPNString);
+ SessionDependencies session_deps;
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.google.com/");
+ request.load_flags = 0;
+
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.1 200 OK\r\n"),
+ MockRead(kAlternateProtocolHttpHeader),
+ MockRead("hello world"),
+ MockRead(true, OK),
+ };
+
+ StaticSocketDataProvider first_transaction(
+ data_reads, arraysize(data_reads), NULL, 0);
+ session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
+
+ SSLSocketDataProvider ssl(true, OK);
+ ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
+ ssl.next_proto = "spdy/2";
+ ssl.was_npn_negotiated = true;
+ session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
+
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ StaticSocketDataProvider hanging_alternate_protocol_socket(
+ NULL, 0, NULL, 0);
+ hanging_alternate_protocol_socket.set_connect_data(
+ never_finishing_connect);
+ session_deps.socket_factory.AddSocketDataProvider(
+ &hanging_alternate_protocol_socket);
+
+ // 2nd request is just a copy of the first one, over HTTP again.
+ session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
+
TestCompletionCallback callback;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
@@ -6697,12 +6817,11 @@ TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
ASSERT_TRUE(response != NULL);
ASSERT_TRUE(response->headers != NULL);
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
- EXPECT_TRUE(response->was_fetched_via_spdy);
- EXPECT_TRUE(response->was_npn_negotiated);
- EXPECT_TRUE(response->was_alternate_protocol_available);
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_FALSE(response->was_npn_negotiated);
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
- EXPECT_EQ("hello!", response_data);
+ EXPECT_EQ("hello world", response_data);
HttpStreamFactory::set_next_protos("");
HttpStreamFactory::set_use_alternate_protocols(false);
@@ -6807,6 +6926,14 @@ TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForTunneledNpnSpdy) {
spdy_writes, arraysize(spdy_writes)));
session_deps.socket_factory.AddSocketDataProvider(spdy_data);
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ StaticSocketDataProvider hanging_non_alternate_protocol_socket(
+ NULL, 0, NULL, 0);
+ hanging_non_alternate_protocol_socket.set_connect_data(
+ never_finishing_connect);
+ session_deps.socket_factory.AddSocketDataProvider(
+ &hanging_non_alternate_protocol_socket);
+
TestCompletionCallback callback;
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
@@ -6842,7 +6969,7 @@ TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForTunneledNpnSpdy) {
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
EXPECT_EQ("hello!", response_data);
- ASSERT_EQ(2u, capturing_proxy_resolver->resolved().size());
+ ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
EXPECT_EQ("http://www.google.com/",
capturing_proxy_resolver->resolved()[0].spec());
EXPECT_EQ("https://www.google.com/",
@@ -6924,13 +7051,16 @@ TEST_F(HttpNetworkTransactionTest,
HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
scoped_refptr<SpdySession> spdy_session =
session->spdy_session_pool()->Get(pair, BoundNetLog());
- scoped_refptr<TCPSocketParams> tcp_params(
- new TCPSocketParams("www.google.com", 443, MEDIUM, GURL(), false));
+ scoped_refptr<TransportSocketParams> transport_params(
+ new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false));
scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
EXPECT_EQ(ERR_IO_PENDING,
- connection->Init(host_port_pair.ToString(),tcp_params, LOWEST,
- &callback, session->tcp_socket_pool(),
+ connection->Init(host_port_pair.ToString(),
+ transport_params,
+ LOWEST,
+ &callback,
+ session->transport_socket_pool(),
BoundNetLog()));
EXPECT_EQ(OK, callback.WaitForResult());
@@ -6958,7 +7088,6 @@ TEST_F(HttpNetworkTransactionTest,
EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
EXPECT_TRUE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
- EXPECT_TRUE(response->was_alternate_protocol_available);
ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
EXPECT_EQ("hello!", response_data);
@@ -7412,15 +7541,15 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
// to validate that the TCP socket is not released to the pool between
// each round of multi-round authentication.
HttpNetworkSessionPeer session_peer(session);
- ClientSocketPoolHistograms tcp_pool_histograms("SmallTCP");
- TCPClientSocketPool* tcp_pool = new TCPClientSocketPool(
+ ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
+ TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
50, // Max sockets for pool
1, // Max sockets per group
- &tcp_pool_histograms,
+ &transport_pool_histograms,
session_deps.host_resolver.get(),
&session_deps.socket_factory,
session_deps.net_log);
- session_peer.SetTCPSocketPool(tcp_pool);
+ session_peer.SetTransportSocketPool(transport_pool);
scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
TestCompletionCallback callback;
@@ -7486,7 +7615,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_FALSE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
// In between rounds, another request comes in for the same domain.
// It should not be able to grab the TCP socket that trans has already
@@ -7509,7 +7638,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
// Third round of authentication.
auth_handler->SetGenerateExpectation(false, OK);
@@ -7520,7 +7649,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
// Fourth round of authentication, which completes successfully.
auth_handler->SetGenerateExpectation(false, OK);
@@ -7531,7 +7660,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
response = trans->GetResponseInfo();
ASSERT_FALSE(response == NULL);
EXPECT_TRUE(response->auth_challenge.get() == NULL);
- EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
// Read the body since the fourth round was successful. This will also
// release the socket back to the pool.
@@ -7544,7 +7673,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
EXPECT_EQ(0, rv);
// There are still 0 idle sockets, since the trans_compete transaction
// will be handed it immediately after trans releases it to the group.
- EXPECT_EQ(0, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
// The competing request can now finish. Wait for the headers and then
// read the body.
@@ -7558,7 +7687,7 @@ TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
EXPECT_EQ(0, rv);
// Finally, the socket is released to the group.
- EXPECT_EQ(1, tcp_pool->IdleSocketCountInGroup(kSocketGroup));
+ EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
}
class TLSDecompressionFailureSocketDataProvider : public SocketDataProvider {
@@ -7729,7 +7858,6 @@ TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
EXPECT_FALSE(response->was_fetched_via_spdy);
EXPECT_TRUE(response->was_npn_negotiated);
- EXPECT_FALSE(response->was_alternate_protocol_available);
HttpStreamFactory::set_next_protos("");
HttpStreamFactory::set_use_alternate_protocols(false);
@@ -7885,9 +8013,17 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
ssl.next_proto = "spdy/2";
ssl.was_npn_negotiated = true;
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ StaticSocketDataProvider hanging_non_alternate_protocol_socket(
+ NULL, 0, NULL, 0);
+ hanging_non_alternate_protocol_socket.set_connect_data(
+ never_finishing_connect);
+
session_deps.socket_factory.AddSocketDataProvider(&data_1);
session_deps.socket_factory.AddSocketDataProvider(data_2.get());
session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
+ session_deps.socket_factory.AddSocketDataProvider(
+ &hanging_non_alternate_protocol_socket);
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
// First round should work and provide the Alternate-Protocol state.
@@ -8167,15 +8303,15 @@ TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
scoped_refptr<SpdySession> spdy_session =
session->spdy_session_pool()->Get(pair, BoundNetLog());
- scoped_refptr<TCPSocketParams> tcp_params(
- new TCPSocketParams("www.google.com", 443, MEDIUM, GURL(), false));
+ scoped_refptr<TransportSocketParams> transport_params(
+ new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false));
TestCompletionCallback callback;
scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
EXPECT_EQ(ERR_IO_PENDING,
- connection->Init(host_port_pair.ToString(), tcp_params, LOWEST,
- &callback, session->tcp_socket_pool(),
- BoundNetLog()));
+ connection->Init(host_port_pair.ToString(), transport_params,
+ LOWEST, &callback,
+ session->transport_socket_pool(), BoundNetLog()));
EXPECT_EQ(OK, callback.WaitForResult());
spdy_session->InitializeWithSocket(connection.release(), false, OK);
@@ -8236,56 +8372,6 @@ TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
}
}
-// Test that the transaction is restarted in the event of an NPN misprediction.
-TEST_F(HttpNetworkTransactionTest, NPNMispredict) {
- net::HttpRequestInfo request_info;
- request_info.url = GURL("https://www.example.com/");
- request_info.method = "GET";
- request_info.load_flags = net::LOAD_NORMAL;
-
- SessionDependencies session_deps;
-
- SSLSocketDataProvider ssl_data1(true /* async */, OK);
- SSLSocketDataProvider ssl_data2(true /* async */, OK);
-
- net::MockWrite data1_writes[] = {
- net::MockWrite(true /* async */, ERR_SSL_SNAP_START_NPN_MISPREDICTION),
- };
- net::MockRead data2_reads[] = {
- net::MockRead("HTTP/1.0 200 OK\r\n\r\n"),
- net::MockRead("hello world"),
- net::MockRead(false, net::OK),
- };
- net::MockWrite data2_writes[] = {
- net::MockWrite("GET / HTTP/1.1\r\n"
- "Host: www.example.com\r\n"
- "Connection: keep-alive\r\n\r\n"),
- };
- net::StaticSocketDataProvider data1(
- NULL, 0, data1_writes, arraysize(data1_writes));
- net::StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads),
- data2_writes, arraysize(data2_writes));
-
- session_deps.socket_factory.AddSocketDataProvider(&data1);
- session_deps.socket_factory.AddSocketDataProvider(&data2);
- session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
- session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
-
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
- scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
-
- TestCompletionCallback callback;
- int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
- if (rv == net::ERR_IO_PENDING)
- rv = callback.WaitForResult();
- ASSERT_EQ(OK, rv);
-
- std::string contents;
- rv = ReadTransaction(trans.get(), &contents);
- EXPECT_EQ(net::OK, rv);
- EXPECT_EQ("hello world", contents);
-}
-
// Ensure that a client certificate is removed from the SSL client auth
// cache when:
// 1) No proxy is involved.
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index 4932da0..6cf6b78 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -212,6 +212,10 @@ int HttpProxyClientSocket::GetPeerAddress(AddressList* address) const {
return transport_->socket()->GetPeerAddress(address);
}
+int HttpProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
+ return transport_->socket()->GetLocalAddress(address);
+}
+
int HttpProxyClientSocket::PrepareForAuthRestart() {
if (!response_.headers.get())
return ERR_CONNECTION_RESET;
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h
index e4276b7..fe2069b 100644
--- a/net/http/http_proxy_client_socket.h
+++ b/net/http/http_proxy_client_socket.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "net/base/completion_callback.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_log.h"
@@ -89,6 +89,7 @@ class HttpProxyClientSocket : public ProxyClientSocket {
virtual bool SetReceiveBufferSize(int32 size);
virtual bool SetSendBufferSize(int32 size);
virtual int GetPeerAddress(AddressList* address) const;
+ virtual int GetLocalAddress(IPEndPoint* address) const;
private:
enum State {
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc
index 18b1c6d..78b9b6b 100644
--- a/net/http/http_proxy_client_socket_pool.cc
+++ b/net/http/http_proxy_client_socket_pool.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -18,7 +18,7 @@
#include "net/socket/client_socket_pool_base.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
-#include "net/socket/tcp_client_socket_pool.h"
+#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/spdy_proxy_client_socket.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
@@ -28,7 +28,7 @@
namespace net {
HttpProxySocketParams::HttpProxySocketParams(
- const scoped_refptr<TCPSocketParams>& tcp_params,
+ const scoped_refptr<TransportSocketParams>& transport_params,
const scoped_refptr<SSLSocketParams>& ssl_params,
const GURL& request_url,
const std::string& user_agent,
@@ -37,7 +37,7 @@ HttpProxySocketParams::HttpProxySocketParams(
HttpAuthHandlerFactory* http_auth_handler_factory,
SpdySessionPool* spdy_session_pool,
bool tunnel)
- : tcp_params_(tcp_params),
+ : transport_params_(transport_params),
ssl_params_(ssl_params),
spdy_session_pool_(spdy_session_pool),
request_url_(request_url),
@@ -46,6 +46,7 @@ HttpProxySocketParams::HttpProxySocketParams(
http_auth_cache_(tunnel ? http_auth_cache : NULL),
http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
tunnel_(tunnel) {
+<<<<<<< HEAD
DCHECK((tcp_params == NULL && ssl_params != NULL) ||
(tcp_params != NULL && ssl_params == NULL));
#ifdef ANDROID
@@ -54,13 +55,21 @@ HttpProxySocketParams::HttpProxySocketParams(
else
ignore_limits_ = ssl_params->ignore_limits();
#endif
+=======
+ DCHECK((transport_params == NULL && ssl_params != NULL) ||
+ (transport_params != NULL && ssl_params == NULL));
+ if (transport_params_)
+ ignore_limits_ = transport_params->ignore_limits();
+ else
+ ignore_limits_ = ssl_params->ignore_limits();
+>>>>>>> chromium.org at r12.0.742.93
}
const HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
- if (tcp_params_ == NULL)
- return ssl_params_->tcp_params()->destination();
+ if (transport_params_ == NULL)
+ return ssl_params_->transport_params()->destination();
else
- return tcp_params_->destination();
+ return transport_params_->destination();
}
HttpProxySocketParams::~HttpProxySocketParams() {}
@@ -73,7 +82,7 @@ HttpProxyConnectJob::HttpProxyConnectJob(
const std::string& group_name,
const scoped_refptr<HttpProxySocketParams>& params,
const base::TimeDelta& timeout_duration,
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
HostResolver* host_resolver,
Delegate* delegate,
@@ -81,7 +90,7 @@ HttpProxyConnectJob::HttpProxyConnectJob(
: ConnectJob(group_name, timeout_duration, delegate,
BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
params_(params),
- tcp_pool_(tcp_pool),
+ transport_pool_(transport_pool),
ssl_pool_(ssl_pool),
resolver_(host_resolver),
ALLOW_THIS_IN_INITIALIZER_LIST(
@@ -132,10 +141,10 @@ int HttpProxyConnectJob::DoLoop(int result) {
switch (state) {
case STATE_TCP_CONNECT:
DCHECK_EQ(OK, rv);
- rv = DoTCPConnect();
+ rv = DoTransportConnect();
break;
case STATE_TCP_CONNECT_COMPLETE:
- rv = DoTCPConnectComplete(rv);
+ rv = DoTransportConnectComplete(rv);
break;
case STATE_SSL_CONNECT:
DCHECK_EQ(OK, rv);
@@ -168,16 +177,19 @@ int HttpProxyConnectJob::DoLoop(int result) {
return rv;
}
-int HttpProxyConnectJob::DoTCPConnect() {
+int HttpProxyConnectJob::DoTransportConnect() {
next_state_ = STATE_TCP_CONNECT_COMPLETE;
transport_socket_handle_.reset(new ClientSocketHandle());
return transport_socket_handle_->Init(
- group_name(), params_->tcp_params(),
- params_->tcp_params()->destination().priority(), &callback_, tcp_pool_,
+ group_name(),
+ params_->transport_params(),
+ params_->transport_params()->destination().priority(),
+ &callback_,
+ transport_pool_,
net_log());
}
-int HttpProxyConnectJob::DoTCPConnectComplete(int result) {
+int HttpProxyConnectJob::DoTransportConnectComplete(int result) {
if (result != OK)
return ERR_PROXY_CONNECTION_FAILED;
@@ -205,7 +217,7 @@ int HttpProxyConnectJob::DoSSLConnect() {
transport_socket_handle_.reset(new ClientSocketHandle());
return transport_socket_handle_->Init(
group_name(), params_->ssl_params(),
- params_->ssl_params()->tcp_params()->destination().priority(),
+ params_->ssl_params()->transport_params()->destination().priority(),
&callback_, ssl_pool_, net_log());
}
@@ -343,7 +355,7 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
}
int HttpProxyConnectJob::ConnectInternal() {
- if (params_->tcp_params())
+ if (params_->transport_params())
next_state_ = STATE_TCP_CONNECT;
else
next_state_ = STATE_SSL_CONNECT;
@@ -352,17 +364,17 @@ int HttpProxyConnectJob::ConnectInternal() {
HttpProxyClientSocketPool::
HttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
HostResolver* host_resolver,
NetLog* net_log)
- : tcp_pool_(tcp_pool),
+ : transport_pool_(transport_pool),
ssl_pool_(ssl_pool),
host_resolver_(host_resolver),
net_log_(net_log) {
base::TimeDelta max_pool_timeout = base::TimeDelta();
- if (tcp_pool_)
- max_pool_timeout = tcp_pool_->ConnectionTimeout();
+ if (transport_pool_)
+ max_pool_timeout = transport_pool_->ConnectionTimeout();
if (ssl_pool_)
max_pool_timeout = std::max(max_pool_timeout,
ssl_pool_->ConnectionTimeout());
@@ -376,9 +388,14 @@ HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
const std::string& group_name,
const PoolBase::Request& request,
ConnectJob::Delegate* delegate) const {
- return new HttpProxyConnectJob(group_name, request.params(),
- ConnectionTimeout(), tcp_pool_, ssl_pool_,
- host_resolver_, delegate, net_log_);
+ return new HttpProxyConnectJob(group_name,
+ request.params(),
+ ConnectionTimeout(),
+ transport_pool_,
+ ssl_pool_,
+ host_resolver_,
+ delegate,
+ net_log_);
}
HttpProxyClientSocketPool::HttpProxyClientSocketPool(
@@ -386,16 +403,18 @@ HttpProxyClientSocketPool::HttpProxyClientSocketPool(
int max_sockets_per_group,
ClientSocketPoolHistograms* histograms,
HostResolver* host_resolver,
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
NetLog* net_log)
- : tcp_pool_(tcp_pool),
+ : transport_pool_(transport_pool),
ssl_pool_(ssl_pool),
base_(max_sockets, max_sockets_per_group, histograms,
base::TimeDelta::FromSeconds(
ClientSocketPool::unused_idle_socket_timeout()),
base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
- new HttpProxyConnectJobFactory(tcp_pool, ssl_pool, host_resolver,
+ new HttpProxyConnectJobFactory(transport_pool,
+ ssl_pool,
+ host_resolver,
net_log)) {}
HttpProxyClientSocketPool::~HttpProxyClientSocketPool() {}
@@ -464,10 +483,10 @@ DictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue(
DictionaryValue* dict = base_.GetInfoAsValue(name, type);
if (include_nested_pools) {
ListValue* list = new ListValue();
- if (tcp_pool_) {
- list->Append(tcp_pool_->GetInfoAsValue("tcp_socket_pool",
- "tcp_socket_pool",
- true));
+ if (transport_pool_) {
+ list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
+ "transport_socket_pool",
+ true));
}
if (ssl_pool_) {
list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool",
diff --git a/net/http/http_proxy_client_socket_pool.h b/net/http/http_proxy_client_socket_pool.h
index bf9b4c2..2f8b6fb 100644
--- a/net/http/http_proxy_client_socket_pool.h
+++ b/net/http/http_proxy_client_socket_pool.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,8 +9,8 @@
#include <string>
#include "base/basictypes.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "net/base/host_port_pair.h"
#include "net/http/http_auth.h"
@@ -29,27 +29,28 @@ class SSLClientSocketPool;
class SSLSocketParams;
class SpdySessionPool;
class SpdyStream;
-class TCPClientSocketPool;
-class TCPSocketParams;
+class TransportClientSocketPool;
+class TransportSocketParams;
// HttpProxySocketParams only needs the socket params for one of the proxy
// types. The other param must be NULL. When using an HTTP Proxy,
-// |tcp_params| must be set. When using an HTTPS Proxy, |ssl_params|
+// |transport_params| must be set. When using an HTTPS Proxy, |ssl_params|
// must be set.
class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
public:
- HttpProxySocketParams(const scoped_refptr<TCPSocketParams>& tcp_params,
- const scoped_refptr<SSLSocketParams>& ssl_params,
- const GURL& request_url,
- const std::string& user_agent,
- HostPortPair endpoint,
- HttpAuthCache* http_auth_cache,
- HttpAuthHandlerFactory* http_auth_handler_factory,
- SpdySessionPool* spdy_session_pool,
- bool tunnel);
-
- const scoped_refptr<TCPSocketParams>& tcp_params() const {
- return tcp_params_;
+ HttpProxySocketParams(
+ const scoped_refptr<TransportSocketParams>& transport_params,
+ const scoped_refptr<SSLSocketParams>& ssl_params,
+ const GURL& request_url,
+ const std::string& user_agent,
+ HostPortPair endpoint,
+ HttpAuthCache* http_auth_cache,
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ SpdySessionPool* spdy_session_pool,
+ bool tunnel);
+
+ const scoped_refptr<TransportSocketParams>& transport_params() const {
+ return transport_params_;
}
const scoped_refptr<SSLSocketParams>& ssl_params() const {
return ssl_params_;
@@ -66,15 +67,19 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
}
const HostResolver::RequestInfo& destination() const;
bool tunnel() const { return tunnel_; }
+<<<<<<< HEAD
#ifdef ANDROID
bool ignore_limits() const { return ignore_limits_; }
#endif
+=======
+ bool ignore_limits() const { return ignore_limits_; }
+>>>>>>> chromium.org at r12.0.742.93
private:
friend class base::RefCounted<HttpProxySocketParams>;
~HttpProxySocketParams();
- const scoped_refptr<TCPSocketParams> tcp_params_;
+ const scoped_refptr<TransportSocketParams> transport_params_;
const scoped_refptr<SSLSocketParams> ssl_params_;
SpdySessionPool* spdy_session_pool_;
const GURL request_url_;
@@ -83,9 +88,13 @@ class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
HttpAuthCache* const http_auth_cache_;
HttpAuthHandlerFactory* const http_auth_handler_factory_;
const bool tunnel_;
+<<<<<<< HEAD
#ifdef ANDROID
bool ignore_limits_;
#endif
+=======
+ bool ignore_limits_;
+>>>>>>> chromium.org at r12.0.742.93
DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
};
@@ -97,7 +106,7 @@ class HttpProxyConnectJob : public ConnectJob {
HttpProxyConnectJob(const std::string& group_name,
const scoped_refptr<HttpProxySocketParams>& params,
const base::TimeDelta& timeout_duration,
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
HostResolver* host_resolver,
Delegate* delegate,
@@ -129,8 +138,8 @@ class HttpProxyConnectJob : public ConnectJob {
int DoLoop(int result);
// Connecting to HTTP Proxy
- int DoTCPConnect();
- int DoTCPConnectComplete(int result);
+ int DoTransportConnect();
+ int DoTransportConnectComplete(int result);
// Connecting to HTTPS Proxy
int DoSSLConnect();
int DoSSLConnectComplete(int result);
@@ -151,7 +160,7 @@ class HttpProxyConnectJob : public ConnectJob {
virtual int ConnectInternal();
scoped_refptr<HttpProxySocketParams> params_;
- TCPClientSocketPool* const tcp_pool_;
+ TransportClientSocketPool* const transport_pool_;
SSLClientSocketPool* const ssl_pool_;
HostResolver* const resolver_;
@@ -175,7 +184,7 @@ class HttpProxyClientSocketPool : public ClientSocketPool {
int max_sockets_per_group,
ClientSocketPoolHistograms* histograms,
HostResolver* host_resolver,
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
NetLog* net_log);
@@ -226,7 +235,7 @@ class HttpProxyClientSocketPool : public ClientSocketPool {
class HttpProxyConnectJobFactory : public PoolBase::ConnectJobFactory {
public:
HttpProxyConnectJobFactory(
- TCPClientSocketPool* tcp_pool,
+ TransportClientSocketPool* transport_pool,
SSLClientSocketPool* ssl_pool,
HostResolver* host_resolver,
NetLog* net_log);
@@ -239,7 +248,7 @@ class HttpProxyClientSocketPool : public ClientSocketPool {
virtual base::TimeDelta ConnectionTimeout() const { return timeout_; }
private:
- TCPClientSocketPool* const tcp_pool_;
+ TransportClientSocketPool* const transport_pool_;
SSLClientSocketPool* const ssl_pool_;
HostResolver* const host_resolver_;
NetLog* net_log_;
@@ -248,7 +257,7 @@ class HttpProxyClientSocketPool : public ClientSocketPool {
DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory);
};
- TCPClientSocketPool* const tcp_pool_;
+ TransportClientSocketPool* const transport_pool_;
SSLClientSocketPool* const ssl_pool_;
PoolBase base_;
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 5830b3a..fb6bef0 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -48,13 +48,14 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
protected:
HttpProxyClientSocketPoolTest()
: ssl_config_(),
- ignored_tcp_socket_params_(new TCPSocketParams(
- HostPortPair("proxy", 80), LOWEST, GURL(), false)),
+ ignored_transport_socket_params_(new TransportSocketParams(
+ HostPortPair("proxy", 80), LOWEST, GURL(), false, false)),
ignored_ssl_socket_params_(new SSLSocketParams(
- ignored_tcp_socket_params_, NULL, NULL, ProxyServer::SCHEME_DIRECT,
- HostPortPair("www.google.com", 443), ssl_config_, 0, false, false)),
+ ignored_transport_socket_params_, NULL, NULL,
+ ProxyServer::SCHEME_DIRECT, HostPortPair("www.google.com", 443),
+ ssl_config_, 0, false, false)),
tcp_histograms_("MockTCP"),
- tcp_socket_pool_(
+ transport_socket_pool_(
kMaxSockets, kMaxSocketsPerGroup,
&tcp_histograms_,
&socket_factory_),
@@ -69,7 +70,7 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
NULL /* dns_cert_checker */,
NULL /* ssl_host_info_factory */,
&socket_factory_,
- &tcp_socket_pool_,
+ &transport_socket_pool_,
NULL,
NULL,
ssl_config_service_.get(),
@@ -83,7 +84,7 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
pool_(kMaxSockets, kMaxSocketsPerGroup,
&http_proxy_histograms_,
NULL,
- &tcp_socket_pool_,
+ &transport_socket_pool_,
&ssl_socket_pool_,
NULL) {
}
@@ -103,10 +104,10 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
"/");
}
- scoped_refptr<TCPSocketParams> GetTcpParams() {
+ scoped_refptr<TransportSocketParams> GetTcpParams() {
if (GetParam() != HTTP)
- return scoped_refptr<TCPSocketParams>();
- return ignored_tcp_socket_params_;
+ return scoped_refptr<TransportSocketParams>();
+ return ignored_transport_socket_params_;
}
scoped_refptr<SSLSocketParams> GetSslParams() {
@@ -189,11 +190,11 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam {
private:
SSLConfig ssl_config_;
- scoped_refptr<TCPSocketParams> ignored_tcp_socket_params_;
+ scoped_refptr<TransportSocketParams> ignored_transport_socket_params_;
scoped_refptr<SSLSocketParams> ignored_ssl_socket_params_;
ClientSocketPoolHistograms tcp_histograms_;
DeterministicMockClientSocketFactory socket_factory_;
- MockTCPClientSocketPool tcp_socket_pool_;
+ MockTransportClientSocketPool transport_socket_pool_;
ClientSocketPoolHistograms ssl_histograms_;
MockHostResolver host_resolver_;
CertVerifier cert_verifier_;
diff --git a/net/http/http_request_info.cc b/net/http/http_request_info.cc
index 8ab3096..18c1b84 100644
--- a/net/http/http_request_info.cc
+++ b/net/http/http_request_info.cc
@@ -9,7 +9,8 @@ namespace net {
HttpRequestInfo::HttpRequestInfo()
: load_flags(0),
priority(LOWEST),
- motivation(NORMAL_MOTIVATION) {
+ motivation(NORMAL_MOTIVATION),
+ request_id(0) {
}
HttpRequestInfo::~HttpRequestInfo() {}
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index 7c73aa6..b906cf5 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,7 +7,7 @@
#pragma once
#include <string>
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "googleurl/src/gurl.h"
#include "net/base/request_priority.h"
#include "net/base/upload_data.h"
@@ -52,6 +52,10 @@ struct 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;
};
} // namespace net
diff --git a/net/http/http_response_body_drainer.h b/net/http/http_response_body_drainer.h
index 1aa4e93..7ee1d7c 100644
--- a/net/http/http_response_body_drainer.h
+++ b/net/http/http_response_body_drainer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,8 +7,8 @@
#pragma once
#include "base/basictypes.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/timer.h"
#include "net/base/completion_callback.h"
#include "net/http/http_network_session.h"
diff --git a/net/http/http_response_body_drainer_unittest.cc b/net/http/http_response_body_drainer_unittest.cc
index 5745865..1bdecea 100644
--- a/net/http/http_response_body_drainer_unittest.cc
+++ b/net/http/http_response_body_drainer_unittest.cc
@@ -74,42 +74,48 @@ class MockHttpStream : public HttpStream {
// HttpStream implementation:
virtual int InitializeStream(const HttpRequestInfo* request_info,
const BoundNetLog& net_log,
- CompletionCallback* callback) {
+ CompletionCallback* callback) OVERRIDE {
return ERR_UNEXPECTED;
}
virtual int SendRequest(const HttpRequestHeaders& request_headers,
UploadDataStream* request_body,
HttpResponseInfo* response,
- CompletionCallback* callback) {
+ CompletionCallback* callback) OVERRIDE {
return ERR_UNEXPECTED;
}
- virtual uint64 GetUploadProgress() const { return 0; }
- virtual int ReadResponseHeaders(CompletionCallback* callback) {
+ virtual uint64 GetUploadProgress() const OVERRIDE { return 0; }
+ virtual int ReadResponseHeaders(CompletionCallback* callback) OVERRIDE {
return ERR_UNEXPECTED;
}
- virtual const HttpResponseInfo* GetResponseInfo() const { return NULL; }
+ virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
+ return NULL;
+ }
- virtual bool CanFindEndOfResponse() const { return true; }
- virtual bool IsMoreDataBuffered() const { return false; }
- virtual bool IsConnectionReused() const { return false; }
- virtual void SetConnectionReused() {}
- virtual void GetSSLInfo(SSLInfo* ssl_info) {}
- virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) {}
+ virtual bool CanFindEndOfResponse() const OVERRIDE { return true; }
+ virtual bool IsMoreDataBuffered() const OVERRIDE { return false; }
+ virtual bool IsConnectionReused() const OVERRIDE { return false; }
+ virtual void SetConnectionReused() OVERRIDE {}
+ virtual bool IsConnectionReusable() const OVERRIDE { return false; }
+ virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
+ virtual void GetSSLCertRequestInfo(
+ SSLCertRequestInfo* cert_request_info) OVERRIDE {}
// Mocked API
virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
- CompletionCallback* callback);
- virtual void Close(bool not_reusable) {
+ CompletionCallback* callback) OVERRIDE;
+ virtual void Close(bool not_reusable) OVERRIDE {
DCHECK(!closed_);
closed_ = true;
result_waiter_->set_result(not_reusable);
}
- virtual HttpStream* RenewStreamForAuth() {
+ virtual HttpStream* RenewStreamForAuth() OVERRIDE {
return NULL;
}
- virtual bool IsResponseBodyComplete() const { return is_complete_; }
+ virtual bool IsResponseBodyComplete() const OVERRIDE { return is_complete_; }
+
+ virtual bool IsSpdyHttpStream() const OVERRIDE { return false; }
// Methods to tweak/observer mock behavior:
void StallReadsForever() { stall_reads_forever_ = true; }
diff --git a/net/http/http_response_headers.h b/net/http/http_response_headers.h
index 3c2eae0..7187da5 100644
--- a/net/http/http_response_headers.h
+++ b/net/http/http_response_headers.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -11,7 +11,7 @@
#include "base/basictypes.h"
#include "base/hash_tables.h"
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "net/http/http_version.h"
class Pickle;
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc
index 9b3444a..49090e0 100644
--- a/net/http/http_response_info.cc
+++ b/net/http/http_response_info.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -22,7 +22,10 @@ namespace net {
// serialized HttpResponseInfo.
enum {
// The version of the response info used when persisting response info.
- RESPONSE_INFO_VERSION = 1,
+ RESPONSE_INFO_VERSION = 2,
+
+ // The minimum version supported for deserializing response info.
+ RESPONSE_INFO_MINIMUM_VERSION = 1,
// We reserve up to 8 bits for the version number.
RESPONSE_INFO_VERSION_MASK = 0xFF,
@@ -52,10 +55,6 @@ enum {
// This bit is set if the request was fetched via an explicit proxy.
RESPONSE_INFO_WAS_PROXY = 1 << 15,
- // This bit is set if response could use alternate protocol. However, browser
- // will ingore the alternate protocol if spdy is not enabled.
- RESPONSE_INFO_WAS_ALTERNATE_PROTOCOL_AVAILABLE = 1 << 16,
-
// TODO(darin): Add other bits to indicate alternate request methods.
// For now, we don't support storing those.
};
@@ -64,7 +63,6 @@ HttpResponseInfo::HttpResponseInfo()
: was_cached(false),
was_fetched_via_spdy(false),
was_npn_negotiated(false),
- was_alternate_protocol_available(false),
was_fetched_via_proxy(false) {
}
@@ -72,7 +70,6 @@ HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs)
: was_cached(rhs.was_cached),
was_fetched_via_spdy(rhs.was_fetched_via_spdy),
was_npn_negotiated(rhs.was_npn_negotiated),
- was_alternate_protocol_available(rhs.was_alternate_protocol_available),
was_fetched_via_proxy(rhs.was_fetched_via_proxy),
socket_address(rhs.socket_address),
request_time(rhs.request_time),
@@ -92,7 +89,6 @@ HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) {
was_cached = rhs.was_cached;
was_fetched_via_spdy = rhs.was_fetched_via_spdy;
was_npn_negotiated = rhs.was_npn_negotiated;
- was_alternate_protocol_available = rhs.was_alternate_protocol_available;
was_fetched_via_proxy = rhs.was_fetched_via_proxy;
socket_address = rhs.socket_address;
request_time = rhs.request_time;
@@ -115,7 +111,8 @@ bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
if (!pickle.ReadInt(&iter, &flags))
return false;
int version = flags & RESPONSE_INFO_VERSION_MASK;
- if (version != RESPONSE_INFO_VERSION) {
+ if (version < RESPONSE_INFO_MINIMUM_VERSION ||
+ version > RESPONSE_INFO_VERSION) {
DLOG(ERROR) << "unexpected response info version: " << version;
return false;
}
@@ -138,8 +135,12 @@ bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
// read ssl-info
if (flags & RESPONSE_INFO_HAS_CERT) {
- ssl_info.cert =
- X509Certificate::CreateFromPickle(pickle, &iter);
+ // Version 1 only serialized only the end-entity certificate,
+ // while subsequent versions include the entire chain.
+ X509Certificate::PickleType type = (version == 1) ?
+ X509Certificate::PICKLETYPE_SINGLE_CERTIFICATE :
+ X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN;
+ ssl_info.cert = X509Certificate::CreateFromPickle(pickle, &iter, type);
}
if (flags & RESPONSE_INFO_HAS_CERT_STATUS) {
int cert_status;
@@ -176,9 +177,6 @@ bool HttpResponseInfo::InitFromPickle(const Pickle& pickle,
was_npn_negotiated = (flags & RESPONSE_INFO_WAS_NPN) != 0;
- was_alternate_protocol_available =
- (flags & RESPONSE_INFO_WAS_ALTERNATE_PROTOCOL_AVAILABLE) != 0;
-
was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0;
*response_truncated = (flags & RESPONSE_INFO_TRUNCATED) ? true : false;
@@ -205,8 +203,6 @@ void HttpResponseInfo::Persist(Pickle* pickle,
flags |= RESPONSE_INFO_WAS_SPDY;
if (was_npn_negotiated)
flags |= RESPONSE_INFO_WAS_NPN;
- if (was_alternate_protocol_available)
- flags |= RESPONSE_INFO_WAS_ALTERNATE_PROTOCOL_AVAILABLE;
if (was_fetched_via_proxy)
flags |= RESPONSE_INFO_WAS_PROXY;
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h
index e13f288..c925aa9 100644
--- a/net/http/http_response_info.h
+++ b/net/http/http_response_info.h
@@ -52,10 +52,6 @@ class HttpResponseInfo {
// True if the npn was negotiated for this request.
bool was_npn_negotiated;
- // True if response could use alternate protocol. However, browser
- // will ingore the alternate protocol if spdy is not enabled.
- bool was_alternate_protocol_available;
-
// True if the request was fetched via an explicit proxy. The proxy could
// be any type of proxy, HTTP or SOCKS. Note, we do not know if a
// transparent proxy may have been involved.
diff --git a/net/http/http_stream.h b/net/http/http_stream.h
index 16f84cc..fed6465 100644
--- a/net/http/http_stream.h
+++ b/net/http/http_stream.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
//
@@ -116,6 +116,10 @@ class HttpStream {
virtual bool IsConnectionReused() const = 0;
virtual void SetConnectionReused() = 0;
+ // Checks whether the current state of the underlying connection
+ // allows it to be reused.
+ virtual bool IsConnectionReusable() const = 0;
+
// Get the SSLInfo associated with this stream's connection. This should
// only be called for streams over SSL sockets, otherwise the behavior is
// undefined.
@@ -126,6 +130,10 @@ class HttpStream {
// behavior is undefined.
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) = 0;
+ // HACK(willchan): Really, we should move the HttpResponseDrainer logic into
+ // the HttpStream implementation. This is just a quick hack.
+ virtual bool IsSpdyHttpStream() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(HttpStream);
};
diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc
index 9189e99..e5ffc26 100644
--- a/net/http/http_stream_factory.cc
+++ b/net/http/http_stream_factory.cc
@@ -108,6 +108,19 @@ void HttpStreamFactory::add_forced_spdy_exclusion(const std::string& value) {
}
// static
+bool HttpStreamFactory::HasSpdyExclusion(const HostPortPair& endpoint) {
+ std::list<HostPortPair>* exclusions = forced_spdy_exclusions_;
+ if (!exclusions)
+ return false;
+
+ std::list<HostPortPair>::const_iterator it;
+ for (it = exclusions->begin(); it != exclusions->end(); ++it)
+ if (it->Equals(endpoint))
+ return true;
+ return false;
+}
+
+// static
void HttpStreamFactory::SetHostMappingRules(const std::string& rules) {
HostMappingRules* host_mapping_rules = new HostMappingRules;
host_mapping_rules->SetRulesFromString(rules);
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h
index 3d3bada..4375f3f 100644
--- a/net/http/http_stream_factory.h
+++ b/net/http/http_stream_factory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -8,8 +8,8 @@
#include <list>
#include <string>
+#include "base/memory/ref_counted.h"
#include "base/string16.h"
-#include "base/ref_counted.h"
#include "net/base/completion_callback.h"
#include "net/base/load_states.h"
@@ -135,9 +135,6 @@ class HttpStreamRequest {
// Returns the LoadState for the request.
virtual LoadState GetLoadState() const = 0;
- // Returns true if an AlternateProtocol for this request was available.
- virtual bool was_alternate_protocol_available() const = 0;
-
// Returns true if TLS/NPN was negotiated for this stream.
virtual bool was_npn_negotiated() const = 0;
@@ -171,8 +168,8 @@ class HttpStreamFactory {
const SSLConfig& ssl_config,
const BoundNetLog& net_log) = 0;
- virtual void AddTLSIntolerantServer(const GURL& url) = 0;
- virtual bool IsTLSIntolerantServer(const GURL& url) const = 0;
+ virtual void AddTLSIntolerantServer(const HostPortPair& server) = 0;
+ virtual bool IsTLSIntolerantServer(const HostPortPair& server) const = 0;
// Static settings
static GURL ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint);
@@ -207,9 +204,8 @@ class HttpStreamFactory {
// Add a URL to exclude from forced SPDY.
static void add_forced_spdy_exclusion(const std::string& value);
- static std::list<HostPortPair>* forced_spdy_exclusions() {
- return forced_spdy_exclusions_;
- }
+ // Check if a HostPortPair is excluded from using spdy.
+ static bool HasSpdyExclusion(const HostPortPair& endpoint);
// Sets the next protocol negotiation value used during the SSL handshake.
static void set_next_protos(const std::string& value) {
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index c7b0c93..63db456 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -4,6 +4,7 @@
#include "net/http/http_stream_factory_impl.h"
+#include "base/string_number_conversions.h"
#include "base/stl_util-inl.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_log.h"
@@ -15,6 +16,21 @@
namespace net {
+namespace {
+
+GURL UpgradeUrlToHttps(const GURL& original_url) {
+ GURL::Replacements replacements;
+ // new_sheme and new_port need to be in scope here because GURL::Replacements
+ // references the memory contained by them directly.
+ const std::string new_scheme = "https";
+ const std::string new_port = base::IntToString(443);
+ replacements.SetSchemeStr(new_scheme);
+ replacements.SetPortStr(new_port);
+ return original_url.ReplaceComponents(replacements);
+}
+
+} // namespace
+
HttpStreamFactoryImpl::HttpStreamFactoryImpl(HttpNetworkSession* session)
: session_(session) {}
@@ -23,6 +39,11 @@ HttpStreamFactoryImpl::~HttpStreamFactoryImpl() {
DCHECK(spdy_session_request_map_.empty());
std::set<const Job*> tmp_job_set;
+ tmp_job_set.swap(orphaned_job_set_);
+ STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
+ DCHECK(orphaned_job_set_.empty());
+
+ tmp_job_set.clear();
tmp_job_set.swap(preconnect_job_set_);
STLDeleteContainerPointers(tmp_job_set.begin(), tmp_job_set.end());
DCHECK(preconnect_job_set_.empty());
@@ -33,10 +54,34 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStream(
const SSLConfig& ssl_config,
HttpStreamRequest::Delegate* delegate,
const BoundNetLog& net_log) {
- Job* job = new Job(this, session_);
Request* request = new Request(request_info.url, this, delegate, net_log);
+
+ GURL alternate_url;
+ bool has_alternate_protocol =
+ GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
+ Job* alternate_job = NULL;
+ if (has_alternate_protocol) {
+ HttpRequestInfo alternate_request_info = request_info;
+ alternate_request_info.url = alternate_url;
+ alternate_job =
+ new Job(this, session_, alternate_request_info, ssl_config, net_log);
+ request->AttachJob(alternate_job);
+ alternate_job->MarkAsAlternate(request_info.url);
+ }
+
+ Job* job = new Job(this, session_, request_info, ssl_config, net_log);
request->AttachJob(job);
- job->Start(request, request_info, ssl_config, net_log);
+ if (alternate_job) {
+ job->WaitFor(alternate_job);
+ // Make sure to wait until we call WaitFor(), before starting
+ // |alternate_job|, otherwise |alternate_job| will not notify |job|
+ // appropriately.
+ alternate_job->Start(request);
+ }
+ // Even if |alternate_job| has already finished, it won't have notified the
+ // request yet, since we defer that to the next iteration of the MessageLoop,
+ // so starting |job| is always safe.
+ job->Start(request);
return request;
}
@@ -45,17 +90,66 @@ void HttpStreamFactoryImpl::PreconnectStreams(
const HttpRequestInfo& request_info,
const SSLConfig& ssl_config,
const BoundNetLog& net_log) {
- Job* job = new Job(this, session_);
+ GURL alternate_url;
+ bool has_alternate_protocol =
+ GetAlternateProtocolRequestFor(request_info.url, &alternate_url);
+ Job* job = NULL;
+ if (has_alternate_protocol) {
+ HttpRequestInfo alternate_request_info = request_info;
+ alternate_request_info.url = alternate_url;
+ job = new Job(this, session_, alternate_request_info, ssl_config, net_log);
+ job->MarkAsAlternate(request_info.url);
+ } else {
+ job = new Job(this, session_, request_info, ssl_config, net_log);
+ }
preconnect_job_set_.insert(job);
- job->Preconnect(num_streams, request_info, ssl_config, net_log);
+ job->Preconnect(num_streams);
}
-void HttpStreamFactoryImpl::AddTLSIntolerantServer(const GURL& url) {
- tls_intolerant_servers_.insert(GetHostAndPort(url));
+void HttpStreamFactoryImpl::AddTLSIntolerantServer(const HostPortPair& server) {
+ tls_intolerant_servers_.insert(server);
}
-bool HttpStreamFactoryImpl::IsTLSIntolerantServer(const GURL& url) const {
- return ContainsKey(tls_intolerant_servers_, GetHostAndPort(url));
+bool HttpStreamFactoryImpl::IsTLSIntolerantServer(
+ const HostPortPair& server) const {
+ return ContainsKey(tls_intolerant_servers_, server);
+}
+
+bool HttpStreamFactoryImpl::GetAlternateProtocolRequestFor(
+ const GURL& original_url,
+ GURL* alternate_url) const {
+ if (!spdy_enabled())
+ return false;
+
+ if (!use_alternate_protocols())
+ return false;
+
+ HostPortPair origin = HostPortPair(original_url.HostNoBrackets(),
+ original_url.EffectiveIntPort());
+
+ const HttpAlternateProtocols& alternate_protocols =
+ session_->alternate_protocols();
+ if (!alternate_protocols.HasAlternateProtocolFor(origin))
+ return false;
+
+ HttpAlternateProtocols::PortProtocolPair alternate =
+ alternate_protocols.GetAlternateProtocolFor(origin);
+ if (alternate.protocol == HttpAlternateProtocols::BROKEN)
+ return false;
+
+ DCHECK_LE(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
+ DCHECK_GT(HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS,
+ alternate.protocol);
+
+ if (alternate.protocol != HttpAlternateProtocols::NPN_SPDY_2)
+ return false;
+
+ origin.set_port(alternate.port);
+ if (HttpStreamFactory::HasSpdyExclusion(origin))
+ return false;
+
+ *alternate_url = UpgradeUrlToHttps(original_url);
+ return true;
}
void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) {
@@ -74,7 +168,6 @@ void HttpStreamFactoryImpl::OnSpdySessionReady(
bool direct,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- bool was_alternate_protocol_available,
bool was_npn_negotiated,
bool using_spdy,
const NetLog::Source& source) {
@@ -91,8 +184,7 @@ void HttpStreamFactoryImpl::OnSpdySessionReady(
if (!ContainsKey(spdy_session_request_map_, spdy_session_key))
break;
Request* request = *spdy_session_request_map_[spdy_session_key].begin();
- request->Complete(was_alternate_protocol_available,
- was_npn_negotiated,
+ request->Complete(was_npn_negotiated,
using_spdy,
source);
bool use_relative_url = direct || request->url().SchemeIs("https");
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h
index 4bdbfca..93e8c57 100644
--- a/net/http/http_stream_factory_impl.h
+++ b/net/http/http_stream_factory_impl.h
@@ -7,9 +7,9 @@
#include <map>
#include <set>
-#include <string>
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/host_port_pair.h"
#include "net/http/http_stream_factory.h"
#include "net/base/net_log.h"
#include "net/proxy/proxy_server.h"
@@ -35,8 +35,8 @@ class HttpStreamFactoryImpl : public HttpStreamFactory {
const HttpRequestInfo& info,
const SSLConfig& ssl_config,
const BoundNetLog& net_log);
- virtual void AddTLSIntolerantServer(const GURL& url);
- virtual bool IsTLSIntolerantServer(const GURL& url) const;
+ virtual void AddTLSIntolerantServer(const HostPortPair& server);
+ virtual bool IsTLSIntolerantServer(const HostPortPair& server) const;
private:
class Request;
@@ -45,6 +45,9 @@ class HttpStreamFactoryImpl : public HttpStreamFactory {
typedef std::set<Request*> RequestSet;
typedef std::map<HostPortProxyPair, RequestSet> SpdySessionRequestMap;
+ bool GetAlternateProtocolRequestFor(const GURL& original_url,
+ GURL* alternate_url) const;
+
// Detaches |job| from |request|.
void OrphanJob(Job* job, const Request* request);
@@ -55,7 +58,6 @@ class HttpStreamFactoryImpl : public HttpStreamFactory {
bool direct,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
- bool was_alternate_protocol_available,
bool was_npn_negotiated,
bool using_spdy,
const NetLog::Source& source);
@@ -76,7 +78,7 @@ class HttpStreamFactoryImpl : public HttpStreamFactory {
HttpNetworkSession* const session_;
- std::set<std::string> tls_intolerant_servers_;
+ std::set<HostPortPair> tls_intolerant_servers_;
// All Requests are handed out to clients. By the time HttpStreamFactoryImpl
// is destroyed, all Requests should be deleted (which should remove them from
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index 224403b..75011e3 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -6,7 +6,6 @@
#include "base/logging.h"
#include "base/stl_util-inl.h"
-#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/values.h"
@@ -25,7 +24,6 @@
#include "net/socket/socks_client_socket_pool.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_client_socket_pool.h"
-#include "net/socket/tcp_client_socket_pool.h"
#include "net/spdy/spdy_http_stream.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
@@ -34,46 +32,38 @@ namespace net {
namespace {
-GURL UpgradeUrlToHttps(const GURL& original_url) {
- GURL::Replacements replacements;
- // new_sheme and new_port need to be in scope here because GURL::Replacements
- // references the memory contained by them directly.
- const std::string new_scheme = "https";
- const std::string new_port = base::IntToString(443);
- replacements.SetSchemeStr(new_scheme);
- replacements.SetPortStr(new_port);
- return original_url.ReplaceComponents(replacements);
-}
-
} // namespace
HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory,
- HttpNetworkSession* session)
+ HttpNetworkSession* session,
+ const HttpRequestInfo& request_info,
+ const SSLConfig& ssl_config,
+ const BoundNetLog& net_log)
: request_(NULL),
+ request_info_(request_info),
+ ssl_config_(ssl_config),
+ net_log_(BoundNetLog::Make(net_log.net_log(),
+ NetLog::SOURCE_HTTP_STREAM_JOB)),
ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)),
connection_(new ClientSocketHandle),
session_(session),
stream_factory_(stream_factory),
next_state_(STATE_NONE),
pac_request_(NULL),
+ blocking_job_(NULL),
+ dependent_job_(NULL),
using_ssl_(false),
using_spdy_(false),
force_spdy_always_(HttpStreamFactory::force_spdy_always()),
force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()),
spdy_certificate_error_(OK),
- alternate_protocol_(HttpAlternateProtocols::UNINITIALIZED),
establishing_tunnel_(false),
- was_alternate_protocol_available_(false),
was_npn_negotiated_(false),
num_streams_(0),
spdy_session_direct_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
DCHECK(stream_factory);
DCHECK(session);
- if (HttpStreamFactory::use_alternate_protocols())
- alternate_protocol_mode_ = kUnspecified;
- else
- alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
}
HttpStreamFactoryImpl::Job::~Job() {
@@ -95,22 +85,16 @@ HttpStreamFactoryImpl::Job::~Job() {
stream_->Close(true /* not reusable */);
}
-void HttpStreamFactoryImpl::Job::Start(Request* request,
- const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log) {
+void HttpStreamFactoryImpl::Job::Start(Request* request) {
DCHECK(request);
request_ = request;
- StartInternal(request_info, ssl_config, net_log);
+ StartInternal();
}
-int HttpStreamFactoryImpl::Job::Preconnect(int num_streams,
- const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log) {
+int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) {
DCHECK_GT(num_streams, 0);
num_streams_ = num_streams;
- return StartInternal(request_info, ssl_config, net_log);
+ return StartInternal();
}
int HttpStreamFactoryImpl::Job::RestartTunnelWithProxyAuth(
@@ -134,13 +118,45 @@ LoadState HttpStreamFactoryImpl::Job::GetLoadState() const {
}
}
+void HttpStreamFactoryImpl::Job::MarkAsAlternate(const GURL& original_url) {
+ DCHECK(!original_url_.get());
+ original_url_.reset(new GURL(original_url));
+}
+
+void HttpStreamFactoryImpl::Job::WaitFor(Job* job) {
+ DCHECK_EQ(STATE_NONE, next_state_);
+ DCHECK_EQ(STATE_NONE, job->next_state_);
+ DCHECK(!blocking_job_);
+ DCHECK(!job->dependent_job_);
+ blocking_job_ = job;
+ job->dependent_job_ = this;
+}
+
+void HttpStreamFactoryImpl::Job::Resume(Job* job) {
+ DCHECK_EQ(blocking_job_, job);
+ blocking_job_ = NULL;
+
+ // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE.
+ // Unblock |this|.
+ if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &HttpStreamFactoryImpl::Job::OnIOComplete, OK));
+ }
+}
+
void HttpStreamFactoryImpl::Job::Orphan(const Request* request) {
DCHECK_EQ(request_, request);
request_ = NULL;
-}
-
-bool HttpStreamFactoryImpl::Job::was_alternate_protocol_available() const {
- return was_alternate_protocol_available_;
+ // We've been orphaned, but there's a job we're blocked on. Don't bother
+ // racing, just cancel ourself.
+ if (blocking_job_) {
+ DCHECK(blocking_job_->dependent_job_);
+ blocking_job_->dependent_job_ = NULL;
+ blocking_job_ = NULL;
+ stream_factory_->OnOrphanedJobComplete(this);
+ }
}
bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const {
@@ -174,8 +190,7 @@ void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() {
if (IsOrphaned()) {
stream_factory_->OnOrphanedJobComplete(this);
} else {
- request_->Complete(was_alternate_protocol_available(),
- was_npn_negotiated(),
+ request_->Complete(was_npn_negotiated(),
using_spdy(),
net_log_.source());
request_->OnStreamReady(this, ssl_config_, proxy_info_, stream_.release());
@@ -193,8 +208,7 @@ void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() {
if (IsOrphaned()) {
stream_factory_->OnSpdySessionReady(
spdy_session, spdy_session_direct_, ssl_config_, proxy_info_,
- was_alternate_protocol_available(), was_npn_negotiated(),
- using_spdy(), net_log_.source());
+ was_npn_negotiated(), using_spdy(), net_log_.source());
stream_factory_->OnOrphanedJobComplete(this);
} else {
request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_);
@@ -260,8 +274,7 @@ void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() {
if (new_spdy_session_) {
stream_factory_->OnSpdySessionReady(
new_spdy_session_, spdy_session_direct_, ssl_config_,
- proxy_info_, was_alternate_protocol_available(),
- was_npn_negotiated(), using_spdy(), net_log_.source());
+ proxy_info_, was_npn_negotiated(), using_spdy(), net_log_.source());
}
stream_factory_->OnPreconnectsComplete(this);
// |this| may be deleted after this call.
@@ -385,6 +398,13 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) {
case STATE_RESOLVE_PROXY_COMPLETE:
rv = DoResolveProxyComplete(rv);
break;
+ case STATE_WAIT_FOR_JOB:
+ DCHECK_EQ(OK, rv);
+ rv = DoWaitForJob();
+ break;
+ case STATE_WAIT_FOR_JOB_COMPLETE:
+ rv = DoWaitForJobComplete(rv);
+ break;
case STATE_INIT_CONNECTION:
DCHECK_EQ(OK, rv);
rv = DoInitConnection();
@@ -418,18 +438,11 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) {
return rv;
}
-int HttpStreamFactoryImpl::Job::StartInternal(
- const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log) {
+int HttpStreamFactoryImpl::Job::StartInternal() {
CHECK_EQ(STATE_NONE, next_state_);
- request_info_ = request_info;
- ssl_config_ = ssl_config;
- net_log_ = BoundNetLog::Make(net_log.net_log(),
- NetLog::SOURCE_HTTP_STREAM_JOB);
net_log_.BeginEvent(NetLog::TYPE_HTTP_STREAM_JOB,
make_scoped_refptr(new NetLogStringParameter(
- "url", request_info.url.GetOrigin().spec())));
+ "url", request_info_.url.GetOrigin().spec())));
next_state_ = STATE_RESOLVE_PROXY;
int rv = RunLoop(OK);
DCHECK_EQ(ERR_IO_PENDING, rv);
@@ -441,40 +454,8 @@ int HttpStreamFactoryImpl::Job::DoResolveProxy() {
next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
- // |endpoint_| indicates the final destination endpoint.
- endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(),
- request_info_.url.EffectiveIntPort());
-
- // Extra URL we might be attempting to resolve to.
- GURL alternate_endpoint_url = request_info_.url;
-
- // Tracks whether we are using |request_.url| or |alternate_endpoint_url|.
- const GURL *curr_endpoint_url = &request_info_.url;
-
- alternate_endpoint_url =
- HttpStreamFactory::ApplyHostMappingRules(
- alternate_endpoint_url, &endpoint_);
-
- const HttpAlternateProtocols& alternate_protocols =
- session_->alternate_protocols();
- if (HttpStreamFactory::spdy_enabled() &&
- alternate_protocols.HasAlternateProtocolFor(endpoint_)) {
- was_alternate_protocol_available_ = true;
- if (alternate_protocol_mode_ == kUnspecified) {
- HttpAlternateProtocols::PortProtocolPair alternate =
- alternate_protocols.GetAlternateProtocolFor(endpoint_);
- if (alternate.protocol != HttpAlternateProtocols::BROKEN) {
- DCHECK_LE(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
- DCHECK_GT(HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS,
- alternate.protocol);
- endpoint_.set_port(alternate.port);
- alternate_protocol_ = alternate.protocol;
- alternate_protocol_mode_ = kUsingAlternateProtocol;
- alternate_endpoint_url = UpgradeUrlToHttps(*curr_endpoint_url);
- curr_endpoint_url = &alternate_endpoint_url;
- }
- }
- }
+ origin_ = HostPortPair(request_info_.url.HostNoBrackets(),
+ request_info_.url.EffectiveIntPort());
if (request_info_.load_flags & LOAD_BYPASS_PROXY) {
proxy_info_.UseDirect();
@@ -482,70 +463,73 @@ int HttpStreamFactoryImpl::Job::DoResolveProxy() {
}
return session_->proxy_service()->ResolveProxy(
- *curr_endpoint_url, &proxy_info_, &io_callback_, &pac_request_,
+ request_info_.url, &proxy_info_, &io_callback_, &pac_request_,
net_log_);
}
int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) {
pac_request_ = NULL;
- if (result != OK)
- return result;
-
- // TODO(mbelshe): consider retrying ResolveProxy if we came here via use of
- // AlternateProtocol.
-
- // Remove unsupported proxies from the list.
- proxy_info_.RemoveProxiesWithoutScheme(
- ProxyServer::SCHEME_DIRECT |
- ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS |
- ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
+ if (result == OK) {
+ // Remove unsupported proxies from the list.
+ proxy_info_.RemoveProxiesWithoutScheme(
+ ProxyServer::SCHEME_DIRECT |
+ ProxyServer::SCHEME_HTTP | ProxyServer::SCHEME_HTTPS |
+ ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5);
+
+ if (proxy_info_.is_empty()) {
+ // No proxies/direct to choose from. This happens when we don't support
+ // any of the proxies in the returned list.
+ result = ERR_NO_SUPPORTED_PROXIES;
+ }
+ }
- if (proxy_info_.is_empty()) {
- // No proxies/direct to choose from. This happens when we don't support any
- // of the proxies in the returned list.
- return ERR_NO_SUPPORTED_PROXIES;
+ if (result != OK) {
+ if (dependent_job_)
+ dependent_job_->Resume(this);
+ return result;
}
- next_state_ = STATE_INIT_CONNECTION;
+ if (blocking_job_)
+ next_state_ = STATE_WAIT_FOR_JOB;
+ else
+ next_state_ = STATE_INIT_CONNECTION;
return OK;
}
-static bool HasSpdyExclusion(const HostPortPair& endpoint) {
- std::list<HostPortPair>* exclusions =
- HttpStreamFactory::forced_spdy_exclusions();
- if (!exclusions)
- return false;
+bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() const {
+ bool rv = force_spdy_always_ && force_spdy_over_ssl_;
+ return rv && !HttpStreamFactory::HasSpdyExclusion(origin_);
+}
- std::list<HostPortPair>::const_iterator it;
- for (it = exclusions->begin(); it != exclusions->end(); it++)
- if (it->Equals(endpoint))
- return true;
- return false;
+bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() const {
+ bool rv = force_spdy_always_ && !force_spdy_over_ssl_;
+ return rv && !HttpStreamFactory::HasSpdyExclusion(origin_);
}
-bool HttpStreamFactoryImpl::Job::ShouldForceSpdySSL() {
- bool rv = force_spdy_always_ && force_spdy_over_ssl_;
- return rv && !HasSpdyExclusion(endpoint_);
+int HttpStreamFactoryImpl::Job::DoWaitForJob() {
+ DCHECK(blocking_job_);
+ next_state_ = STATE_WAIT_FOR_JOB_COMPLETE;
+ return ERR_IO_PENDING;
}
-bool HttpStreamFactoryImpl::Job::ShouldForceSpdyWithoutSSL() {
- bool rv = force_spdy_always_ && !force_spdy_over_ssl_;
- return rv && !HasSpdyExclusion(endpoint_);
+int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) {
+ DCHECK(!blocking_job_);
+ DCHECK_EQ(OK, result);
+ next_state_ = STATE_INIT_CONNECTION;
+ return OK;
}
int HttpStreamFactoryImpl::Job::DoInitConnection() {
+ DCHECK(!blocking_job_);
DCHECK(!connection_->is_initialized());
DCHECK(proxy_info_.proxy_server().is_valid());
next_state_ = STATE_INIT_CONNECTION_COMPLETE;
- bool want_spdy_over_npn =
- alternate_protocol_mode_ == kUsingAlternateProtocol &&
- alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_2;
- using_ssl_ = request_info_.url.SchemeIs("https") ||
- ShouldForceSpdySSL() || want_spdy_over_npn;
+ using_ssl_ = request_info_.url.SchemeIs("https") || ShouldForceSpdySSL();
using_spdy_ = false;
+<<<<<<< HEAD
// If spdy has been turned off on-the-fly, then there may be SpdySessions
// still active. But don't use them unless spdy is currently on.
if (HttpStreamFactory::spdy_enabled() && !HasSpdyExclusion(endpoint_)) {
@@ -668,73 +652,77 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
request_info_.priority,
request_info_.referrer);
}
+=======
+ // Check first if we have a spdy session for this group. If so, then go
+ // straight to using that.
+ HostPortProxyPair spdy_session_key;
+ if (IsHttpsProxyAndHttpUrl()) {
+ spdy_session_key =
+ HostPortProxyPair(proxy_info_.proxy_server().host_port_pair(),
+ ProxyServer::Direct());
+ } else {
+ spdy_session_key = HostPortProxyPair(origin_, proxy_info_.proxy_server());
+>>>>>>> chromium.org at r12.0.742.93
}
-
- // Deal with SSL - which layers on top of any given proxy.
- if (using_ssl_) {
- scoped_refptr<SSLSocketParams> ssl_params =
- GenerateSSLParams(tcp_params, http_proxy_params, socks_params,
- proxy_info_.proxy_server().scheme(),
- HostPortPair::FromURL(request_info_.url),
- want_spdy_over_npn);
- SSLClientSocketPool* ssl_pool = NULL;
- if (proxy_info_.is_direct())
- ssl_pool = session_->ssl_socket_pool();
- else
- ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port);
-
- if (IsPreconnecting()) {
- RequestSocketsForPool(ssl_pool, connection_group, ssl_params,
- num_streams_, net_log_);
+ if (session_->spdy_session_pool()->HasSession(spdy_session_key)) {
+ // If we're preconnecting, but we already have a SpdySession, we don't
+ // actually need to preconnect any sockets, so we're done.
+ if (IsPreconnecting())
return OK;
- }
-
- return connection_->Init(connection_group, ssl_params,
- request_info_.priority, &io_callback_, ssl_pool,
- net_log_);
+ using_spdy_ = true;
+ next_state_ = STATE_CREATE_STREAM;
+ return OK;
+ } else if (request_ && (using_ssl_ || ShouldForceSpdyWithoutSSL())) {
+ // Update the spdy session key for the request that launched this job.
+ request_->SetSpdySessionKey(spdy_session_key);
}
- // Finally, get the connection started.
- if (proxy_info_.is_http() || proxy_info_.is_https()) {
- HttpProxyClientSocketPool* pool =
- session_->GetSocketPoolForHTTPProxy(*proxy_host_port);
- if (IsPreconnecting()) {
- RequestSocketsForPool(pool, connection_group, http_proxy_params,
- num_streams_, net_log_);
- return OK;
- }
+ // OK, there's no available SPDY session. Let |dependent_job_| resume if it's
+ // paused.
- return connection_->Init(connection_group, http_proxy_params,
- request_info_.priority, &io_callback_,
- pool, net_log_);
+ if (dependent_job_) {
+ dependent_job_->Resume(this);
+ dependent_job_ = NULL;
}
- if (proxy_info_.is_socks()) {
- SOCKSClientSocketPool* pool =
- session_->GetSocketPoolForSOCKSProxy(*proxy_host_port);
- if (IsPreconnecting()) {
- RequestSocketsForPool(pool, connection_group, socks_params,
- num_streams_, net_log_);
- return OK;
- }
+ if (proxy_info_.is_http() || proxy_info_.is_https())
+ establishing_tunnel_ = using_ssl_;
- return connection_->Init(connection_group, socks_params,
- request_info_.priority, &io_callback_, pool,
- net_log_);
- }
+ bool want_spdy_over_npn = original_url_.get() ? true : false;
- DCHECK(proxy_info_.is_direct());
+ SSLConfig ssl_config_for_proxy = ssl_config_;
+ if (proxy_info_.is_https()) {
+ InitSSLConfig(proxy_info_.proxy_server().host_port_pair(),
+ &ssl_config_for_proxy);
+ }
+ if (using_ssl_) {
+ InitSSLConfig(origin_, &ssl_config_);
+ }
- TCPClientSocketPool* pool = session_->tcp_socket_pool();
if (IsPreconnecting()) {
- RequestSocketsForPool(pool, connection_group, tcp_params,
- num_streams_, net_log_);
- return OK;
+ return ClientSocketPoolManager::PreconnectSocketsForHttpRequest(
+ request_info_,
+ session_,
+ proxy_info_,
+ ShouldForceSpdySSL(),
+ want_spdy_over_npn,
+ ssl_config_,
+ ssl_config_for_proxy,
+ net_log_,
+ num_streams_);
+ } else {
+ return ClientSocketPoolManager::InitSocketHandleForHttpRequest(
+ request_info_,
+ session_,
+ proxy_info_,
+ ShouldForceSpdySSL(),
+ want_spdy_over_npn,
+ ssl_config_,
+ ssl_config_for_proxy,
+ net_log_,
+ connection_.get(),
+ &io_callback_);
}
-
- return connection_->Init(connection_group, tcp_params,
- request_info_.priority, &io_callback_,
- pool, net_log_);
}
int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
@@ -743,6 +731,13 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
return OK;
}
+ // TODO(willchan): Make this a bit more exact. Maybe there are recoverable
+ // errors, such as ignoring certificate errors for Alternate-Protocol.
+ if (result < 0 && dependent_job_) {
+ dependent_job_->Resume(this);
+ dependent_job_ = NULL;
+ }
+
// |result| may be the result of any of the stacked pools. The following
// logic is used when determining how to interpret an error.
// If |result| < 0:
@@ -791,12 +786,11 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
return result;
}
- if ((!ssl_started && result < 0 &&
- alternate_protocol_mode_ == kUsingAlternateProtocol) ||
- result == ERR_NPN_NEGOTIATION_FAILED) {
+ if (!ssl_started && result < 0 && original_url_.get()) {
// Mark the alternate protocol as broken and fallback.
- MarkBrokenAlternateProtocolAndFallback();
- return OK;
+ session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor(
+ HostPortPair::FromURL(*original_url_));
+ return result;
}
if (result < 0 && !ssl_started)
@@ -817,7 +811,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
if (using_ssl_) {
DCHECK(ssl_started);
if (IsCertificateError(result)) {
- if (using_spdy_ && request_info_.url.SchemeIs("http")) {
+ if (using_spdy_ && original_url_.get() &&
+ original_url_->SchemeIs("http")) {
// We ignore certificate errors for http over spdy.
spdy_certificate_error_ = result;
result = OK;
@@ -871,7 +866,7 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
SpdySessionPool* spdy_pool = session_->spdy_session_pool();
scoped_refptr<SpdySession> spdy_session;
- HostPortProxyPair pair(endpoint_, proxy_server);
+ HostPortProxyPair pair(origin_, proxy_server);
if (spdy_pool->HasSession(pair)) {
// We have a SPDY session to the origin server. This might be a direct
// connection, or it might be a SPDY session through an HTTP or HTTPS proxy.
@@ -975,27 +970,30 @@ void HttpStreamFactoryImpl::Job::SetSocketMotivation() {
}
bool HttpStreamFactoryImpl::Job::IsHttpsProxyAndHttpUrl() {
- return proxy_info_.is_https() && request_info_.url.SchemeIs("http");
+ if (!proxy_info_.is_https())
+ return false;
+ if (original_url_.get()) {
+ // We currently only support Alternate-Protocol where the original scheme
+ // is http.
+ DCHECK(original_url_->SchemeIs("http"));
+ return original_url_->SchemeIs("http");
+ }
+ return request_info_.url.SchemeIs("http");
}
-// Returns a newly create SSLSocketParams, and sets several
-// fields of ssl_config_.
-scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams(
- scoped_refptr<TCPSocketParams> tcp_params,
- scoped_refptr<HttpProxySocketParams> http_proxy_params,
- scoped_refptr<SOCKSSocketParams> socks_params,
- ProxyServer::Scheme proxy_scheme,
- const HostPortPair& host_and_port,
- bool want_spdy_over_npn) {
-
- if (stream_factory_->IsTLSIntolerantServer(request_info_.url)) {
+// Sets several fields of ssl_config for the given origin_server based on the
+// proxy info and other factors.
+void HttpStreamFactoryImpl::Job::InitSSLConfig(
+ const HostPortPair& origin_server,
+ SSLConfig* ssl_config) const {
+ if (stream_factory_->IsTLSIntolerantServer(origin_server)) {
LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: "
- << GetHostAndPort(request_info_.url);
- ssl_config_.ssl3_fallback = true;
- ssl_config_.tls1_enabled = false;
+ << origin_server.ToString();
+ ssl_config->ssl3_fallback = true;
+ ssl_config->tls1_enabled = false;
}
- if (proxy_info_.is_https() && ssl_config_.send_client_cert) {
+ if (proxy_info_.is_https() && ssl_config->send_client_cert) {
// When connecting through an HTTPS proxy, disable TLS False Start so
// that client authentication errors can be distinguished between those
// originating from the proxy server (ERR_PROXY_CONNECTION_FAILED) and
@@ -1004,52 +1002,17 @@ scoped_refptr<SSLSocketParams> HttpStreamFactoryImpl::Job::GenerateSSLParams(
// TODO(rch): This assumes that the HTTPS proxy will only request a
// client certificate during the initial handshake.
// http://crbug.com/59292
- ssl_config_.false_start_enabled = false;
+ ssl_config->false_start_enabled = false;
}
UMA_HISTOGRAM_ENUMERATION("Net.ConnectionUsedSSLv3Fallback",
- static_cast<int>(ssl_config_.ssl3_fallback), 2);
+ static_cast<int>(ssl_config->ssl3_fallback), 2);
- int load_flags = request_info_.load_flags;
- if (HttpStreamFactory::ignore_certificate_errors())
- load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;
if (request_info_.load_flags & LOAD_VERIFY_EV_CERT)
- ssl_config_.verify_ev_cert = true;
-
- if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTP ||
- proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_HTTPS) {
- ssl_config_.mitm_proxies_allowed = true;
- }
-
- scoped_refptr<SSLSocketParams> ssl_params(
- new SSLSocketParams(tcp_params, socks_params, http_proxy_params,
- proxy_scheme, host_and_port,
- ssl_config_, load_flags,
- ShouldForceSpdySSL(),
- want_spdy_over_npn));
-
- return ssl_params;
+ ssl_config->verify_ev_cert = true;
}
-void HttpStreamFactoryImpl::Job::MarkBrokenAlternateProtocolAndFallback() {
- // We have to:
- // * Reset the endpoint to be the unmodified URL specified destination.
- // * Mark the endpoint as broken so we don't try again.
- // * Set the alternate protocol mode to kDoNotUseAlternateProtocol so we
- // ignore future Alternate-Protocol headers from the HostPortPair.
- // * Reset the connection and go back to STATE_INIT_CONNECTION.
-
- endpoint_ = HostPortPair(request_info_.url.HostNoBrackets(),
- request_info_.url.EffectiveIntPort());
-
- session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor(
- endpoint_);
-
- alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
- ReturnToStateInitConnection(false /* close connection */);
-}
-
int HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError(int error) {
DCHECK(!pac_request_);
@@ -1129,7 +1092,7 @@ int HttpStreamFactoryImpl::Job::HandleCertificateError(int error) {
ssl_socket->GetSSLInfo(&ssl_info_);
// Add the bad certificate to the set of allowed certificates in the
- // SSL info object. This data structure will be consulted after calling
+ // SSL config object. This data structure will be consulted after calling
// RestartIgnoringLastError(). And the user will be asked interactively
// before RestartIgnoringLastError() is ever called.
SSLConfig::CertAndStatus bad_cert;
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h
index b466640..a12d108 100644
--- a/net/http/http_stream_factory_impl_job.h
+++ b/net/http/http_stream_factory_impl_job.h
@@ -5,8 +5,8 @@
#ifndef NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_JOB_H_
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/task.h"
#include "net/base/completion_callback.h"
#include "net/base/net_log.h"
@@ -28,38 +28,47 @@ class HttpProxySocketParams;
class HttpStream;
class SOCKSSocketParams;
class SSLSocketParams;
-class TCPSocketParams;
+class TransportSocketParams;
// An HttpStreamRequestImpl exists for each stream which is in progress of being
// created for the StreamFactory.
class HttpStreamFactoryImpl::Job {
public:
Job(HttpStreamFactoryImpl* stream_factory,
- HttpNetworkSession* session);
+ HttpNetworkSession* session,
+ const HttpRequestInfo& request_info,
+ const SSLConfig& ssl_config,
+ const BoundNetLog& net_log);
~Job();
- // Start initiates the process of creating a new HttpStream.
- // 3 parameters are passed in by reference. The caller asserts that the
- // lifecycle of these parameters will remain valid until the stream is
- // created, failed, or destroyed. In the first two cases, the delegate will
- // be called to notify completion of the request.
- void Start(Request* request,
- const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log);
-
- int Preconnect(int num_streams,
- const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log);
+ // Start initiates the process of creating a new HttpStream. |request| will be
+ // notified upon completion if the Job has not been Orphan()'d.
+ void Start(Request* request);
+
+ // Preconnect will attempt to request |num_streams| sockets from the
+ // appropriate ClientSocketPool.
+ int Preconnect(int num_streams);
int RestartTunnelWithProxyAuth(const string16& username,
const string16& password);
LoadState GetLoadState() const;
+ // Marks this Job as the "alternate" job, from Alternate-Protocol. Tracks the
+ // original url so we can mark the Alternate-Protocol as broken if
+ // we fail to connect.
+ void MarkAsAlternate(const GURL& original_url);
+
+ // Tells |this| to wait for |job| to resume it.
+ void WaitFor(Job* job);
+
+ // Tells |this| that |job| has determined it still needs to continue
+ // connecting, so allow |this| to continue. If this is not called, then
+ // |request_| is expected to cancel |this| by deleting it.
+ void Resume(Job* job);
+
+ // Used to detach the Job from |request|.
void Orphan(const Request* request);
- bool was_alternate_protocol_available() const;
bool was_npn_negotiated() const;
bool using_spdy() const;
const BoundNetLog& net_log() const { return net_log_; }
@@ -74,15 +83,28 @@ class HttpStreamFactoryImpl::Job {
bool IsOrphaned() const;
private:
- enum AlternateProtocolMode {
- kUnspecified, // Unspecified, check HttpAlternateProtocols
- kUsingAlternateProtocol, // Using an alternate protocol
- kDoNotUseAlternateProtocol, // Failed to connect once, do not try again.
- };
-
enum State {
STATE_RESOLVE_PROXY,
STATE_RESOLVE_PROXY_COMPLETE,
+
+ // Note that when Alternate-Protocol says we can connect to an alternate
+ // port using a different protocol, we have the choice of communicating over
+ // the original protocol, or speaking the alternate protocol (currently,
+ // only npn-spdy) over an alternate port. For a cold page load, the http
+ // connection that delivers the http response that has the
+ // Alternate-Protocol header will already be warm. So, blocking the next
+ // http request on establishing a new npn-spdy connection would incur extra
+ // latency. Even if the http connection was not reused, establishing a new
+ // http connection is typically faster than npn-spdy, since npn-spdy
+ // requires a SSL handshake. Therefore, we start both the http and the
+ // npn-spdy jobs in parallel. In order not to unnecessarily waste sockets,
+ // we have the http job block on the npn-spdy job after proxy resolution.
+ // The npn-spdy job will Resume() the http job if, in
+ // STATE_INIT_CONNECTION_COMPLETE, it detects an error or does not find an
+ // existing SpdySession. In that case, the http and npn-spdy jobs will race.
+ STATE_WAIT_FOR_JOB,
+ STATE_WAIT_FOR_JOB_COMPLETE,
+
STATE_INIT_CONNECTION,
STATE_INIT_CONNECTION_COMPLETE,
STATE_WAITING_USER_ACTION,
@@ -110,9 +132,7 @@ class HttpStreamFactoryImpl::Job {
void OnIOComplete(int result);
int RunLoop(int result);
int DoLoop(int result);
- int StartInternal(const HttpRequestInfo& request_info,
- const SSLConfig& ssl_config,
- const BoundNetLog& net_log);
+ int StartInternal();
// Each of these methods corresponds to a State value. Those with an input
// argument receive the result from the previous state. If a method returns
@@ -120,6 +140,8 @@ class HttpStreamFactoryImpl::Job {
// next state method as the result arg.
int DoResolveProxy();
int DoResolveProxyComplete(int result);
+ int DoWaitForJob();
+ int DoWaitForJobComplete(int result);
int DoInitConnection();
int DoInitConnectionComplete(int result);
int DoWaitingUserAction(int result);
@@ -136,15 +158,10 @@ class HttpStreamFactoryImpl::Job {
bool IsHttpsProxyAndHttpUrl();
- // Returns a newly create SSLSocketParams, and sets several
- // fields of ssl_config_.
- scoped_refptr<SSLSocketParams> GenerateSSLParams(
- scoped_refptr<TCPSocketParams> tcp_params,
- scoped_refptr<HttpProxySocketParams> http_proxy_params,
- scoped_refptr<SOCKSSocketParams> socks_params,
- ProxyServer::Scheme proxy_scheme,
- const HostPortPair& host_and_port,
- bool want_spdy_over_npn);
+// Sets several fields of ssl_config for the given origin_server based on the
+// proxy info and other factors.
+ void InitSSLConfig(const HostPortPair& origin_server,
+ SSLConfig* ssl_config) const;
// AlternateProtocol API
void MarkBrokenAlternateProtocolAndFallback();
@@ -174,31 +191,42 @@ class HttpStreamFactoryImpl::Job {
void SwitchToSpdyMode();
// Should we force SPDY to run over SSL for this stream request.
- bool ShouldForceSpdySSL();
+ bool ShouldForceSpdySSL() const;
// Should we force SPDY to run without SSL for this stream request.
- bool ShouldForceSpdyWithoutSSL();
+ bool ShouldForceSpdyWithoutSSL() const;
// Record histograms of latency until Connect() completes.
static void LogHttpConnectedMetrics(const ClientSocketHandle& handle);
Request* request_;
- HttpRequestInfo request_info_;
+ const HttpRequestInfo request_info_;
ProxyInfo proxy_info_;
SSLConfig ssl_config_;
+ const BoundNetLog net_log_;
CompletionCallbackImpl<Job> io_callback_;
scoped_ptr<ClientSocketHandle> connection_;
HttpNetworkSession* const session_;
HttpStreamFactoryImpl* const stream_factory_;
- BoundNetLog net_log_;
State next_state_;
ProxyService::PacRequest* pac_request_;
SSLInfo ssl_info_;
- // The hostname and port of the endpoint. This is not necessarily the one
- // specified by the URL, due to Alternate-Protocol or fixed testing ports.
- HostPortPair endpoint_;
+
+ // The origin server we're trying to reach.
+ HostPortPair origin_;
+
+ // If this is a Job for an "Alternate-Protocol", then this will be non-NULL
+ // and will specify the original URL.
+ scoped_ptr<GURL> original_url_;
+
+ // This is the Job we're dependent on. It will notify us if/when it's OK to
+ // proceed.
+ Job* blocking_job_;
+
+ // |dependent_job_| is dependent on |this|. Notify it when it's ok to proceed.
+ Job* dependent_job_;
// True if handling a HTTPS request, or using SPDY with SSL
bool using_ssl_;
@@ -218,21 +246,12 @@ class HttpStreamFactoryImpl::Job {
scoped_refptr<HttpAuthController>
auth_controllers_[HttpAuth::AUTH_NUM_TARGETS];
- AlternateProtocolMode alternate_protocol_mode_;
-
- // Only valid if |alternate_protocol_mode_| == kUsingAlternateProtocol.
- HttpAlternateProtocols::Protocol alternate_protocol_;
-
// True when the tunnel is in the process of being established - we can't
// read from the socket until the tunnel is done.
bool establishing_tunnel_;
scoped_ptr<HttpStream> stream_;
- // True if finding the connection for this request found an alternate
- // protocol was available.
- bool was_alternate_protocol_available_;
-
// True if we negotiated NPN.
bool was_npn_negotiated_;
diff --git a/net/http/http_stream_factory_impl_request.cc b/net/http/http_stream_factory_impl_request.cc
index b9e0cee..d8bb09f 100644
--- a/net/http/http_stream_factory_impl_request.cc
+++ b/net/http/http_stream_factory_impl_request.cc
@@ -21,7 +21,6 @@ HttpStreamFactoryImpl::Request::Request(const GURL& url,
delegate_(delegate),
net_log_(net_log),
completed_(false),
- was_alternate_protocol_available_(false),
was_npn_negotiated_(false),
using_spdy_(false) {
DCHECK(factory_);
@@ -63,13 +62,11 @@ void HttpStreamFactoryImpl::Request::AttachJob(Job* job) {
}
void HttpStreamFactoryImpl::Request::Complete(
- bool was_alternate_protocol_available,
bool was_npn_negotiated,
bool using_spdy,
const NetLog::Source& job_source) {
DCHECK(!completed_);
completed_ = true;
- was_alternate_protocol_available_ = was_alternate_protocol_available;
was_npn_negotiated_ = was_npn_negotiated;
using_spdy_ = using_spdy;
net_log_.AddEvent(
@@ -114,10 +111,23 @@ void HttpStreamFactoryImpl::Request::OnStreamFailed(
int status,
const SSLConfig& used_ssl_config) {
DCHECK_NE(OK, status);
- if (!bound_job_.get())
- OrphanJobsExcept(job);
- else
+ if (!bound_job_.get()) {
+ // Hey, we've got other jobs! Maybe one of them will succeed, let's just
+ // ignore this failure.
+ if (jobs_.size() > 1) {
+ jobs_.erase(job);
+ factory_->request_map_.erase(job);
+ delete job;
+ return;
+ } else {
+ bound_job_.reset(job);
+ jobs_.erase(job);
+ DCHECK(jobs_.empty());
+ factory_->request_map_.erase(job);
+ }
+ } else {
DCHECK(jobs_.empty());
+ }
delegate_->OnStreamFailed(status, used_ssl_config);
}
@@ -189,11 +199,6 @@ LoadState HttpStreamFactoryImpl::Request::GetLoadState() const {
return (*jobs_.begin())->GetLoadState();
}
-bool HttpStreamFactoryImpl::Request::was_alternate_protocol_available() const {
- DCHECK(completed_);
- return was_alternate_protocol_available_;
-}
-
bool HttpStreamFactoryImpl::Request::was_npn_negotiated() const {
DCHECK(completed_);
return was_npn_negotiated_;
@@ -238,14 +243,11 @@ void HttpStreamFactoryImpl::Request::OnSpdySessionReady(
// Cache these values in case the job gets deleted.
const SSLConfig used_ssl_config = job->ssl_config();
const ProxyInfo used_proxy_info = job->proxy_info();
- const bool was_alternate_protocol_available =
- job->was_alternate_protocol_available();
const bool was_npn_negotiated = job->was_npn_negotiated();
const bool using_spdy = job->using_spdy();
const NetLog::Source source = job->net_log().source();
- Complete(was_alternate_protocol_available,
- was_npn_negotiated,
+ Complete(was_npn_negotiated,
using_spdy,
source);
@@ -260,7 +262,7 @@ void HttpStreamFactoryImpl::Request::OnSpdySessionReady(
// |this| may be deleted after this point.
factory->OnSpdySessionReady(
spdy_session, direct, used_ssl_config, used_proxy_info,
- was_alternate_protocol_available, was_npn_negotiated, using_spdy, source);
+ was_npn_negotiated, using_spdy, source);
}
void HttpStreamFactoryImpl::Request::OrphanJobsExcept(Job* job) {
diff --git a/net/http/http_stream_factory_impl_request.h b/net/http/http_stream_factory_impl_request.h
index 3c1b996..4a7ace4 100644
--- a/net/http/http_stream_factory_impl_request.h
+++ b/net/http/http_stream_factory_impl_request.h
@@ -6,7 +6,7 @@
#define NET_HTTP_HTTP_STREAM_FACTORY_IMPL_REQUEST_H_
#include <set>
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_log.h"
#include "net/http/http_stream_factory_impl.h"
@@ -37,8 +37,7 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
// Marks completion of the request. Must be called before OnStreamReady().
// |source| is the NetLog::Source generated by the Job that fulfilled this
// request.
- void Complete(bool was_alternate_protocol_available,
- bool was_npn_negotiated,
+ void Complete(bool was_npn_negotiated,
bool using_spdy,
const NetLog::Source& source);
@@ -83,7 +82,6 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
virtual int RestartTunnelWithProxyAuth(const string16& username,
const string16& password);
virtual LoadState GetLoadState() const;
- virtual bool was_alternate_protocol_available() const;
virtual bool was_npn_negotiated() const;
virtual bool using_spdy() const;
@@ -106,7 +104,6 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest {
scoped_ptr<const HostPortProxyPair> spdy_session_key_;
bool completed_;
- bool was_alternate_protocol_available_;
bool was_npn_negotiated_;
bool using_spdy_;
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index f316251..b37c173 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -183,8 +183,8 @@ class CapturePreconnectsSocketPool : public ParentPool {
int last_num_streams_;
};
-typedef CapturePreconnectsSocketPool<TCPClientSocketPool>
-CapturePreconnectsTCPSocketPool;
+typedef CapturePreconnectsSocketPool<TransportClientSocketPool>
+CapturePreconnectsTransportSocketPool;
typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool>
CapturePreconnectsHttpProxySocketPool;
typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool>
@@ -216,11 +216,11 @@ TEST(HttpStreamFactoryTest, PreconnectDirect) {
SessionDependencies session_deps(ProxyService::CreateDirect());
scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
HttpNetworkSessionPeer peer(session);
- CapturePreconnectsTCPSocketPool* tcp_conn_pool =
- new CapturePreconnectsTCPSocketPool(
+ CapturePreconnectsTransportSocketPool* transport_conn_pool =
+ new CapturePreconnectsTransportSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- peer.SetTCPSocketPool(tcp_conn_pool);
+ peer.SetTransportSocketPool(transport_conn_pool);
CapturePreconnectsSSLSocketPool* ssl_conn_pool =
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
@@ -230,7 +230,7 @@ TEST(HttpStreamFactoryTest, PreconnectDirect) {
if (kTests[i].ssl)
EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams());
else
- EXPECT_EQ(kTests[i].num_streams, tcp_conn_pool->last_num_streams());
+ EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
}
}
@@ -295,11 +295,11 @@ TEST(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
scoped_refptr<SpdySession> spdy_session =
session->spdy_session_pool()->Get(pair, BoundNetLog());
- CapturePreconnectsTCPSocketPool* tcp_conn_pool =
- new CapturePreconnectsTCPSocketPool(
+ CapturePreconnectsTransportSocketPool* transport_conn_pool =
+ new CapturePreconnectsTransportSocketPool(
session_deps.host_resolver.get(),
session_deps.cert_verifier.get());
- peer.SetTCPSocketPool(tcp_conn_pool);
+ peer.SetTransportSocketPool(transport_conn_pool);
CapturePreconnectsSSLSocketPool* ssl_conn_pool =
new CapturePreconnectsSSLSocketPool(
session_deps.host_resolver.get(),
@@ -311,7 +311,7 @@ TEST(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) {
if (kTests[i].ssl)
EXPECT_EQ(-1, ssl_conn_pool->last_num_streams());
else
- EXPECT_EQ(kTests[i].num_streams, tcp_conn_pool->last_num_streams());
+ EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams());
}
}
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index eb1ed35..0649bce 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -700,6 +700,10 @@ void HttpStreamParser::SetConnectionReused() {
connection_->set_is_reused(true);
}
+bool HttpStreamParser::IsConnectionReusable() const {
+ return connection_->socket() && connection_->socket()->IsConnectedAndIdle();
+}
+
void HttpStreamParser::GetSSLInfo(SSLInfo* ssl_info) {
if (request_->url.SchemeIs("https") && connection_->socket()) {
SSLClientSocket* ssl_socket =
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index d9241a6..2192eff 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -67,6 +67,8 @@ class HttpStreamParser : public ChunkCallback {
void SetConnectionReused();
+ bool IsConnectionReusable() const;
+
void GetSSLInfo(SSLInfo* ssl_info);
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
diff --git a/net/http/http_transaction_factory.h b/net/http/http_transaction_factory.h
index 0d0f642..e457828 100644
--- a/net/http/http_transaction_factory.h
+++ b/net/http/http_transaction_factory.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,7 +6,7 @@
#define NET_HTTP_HTTP_TRANSACTION_FACTORY_H__
#pragma once
-#include "base/scoped_ptr.h"
+#include "base/memory/scoped_ptr.h"
namespace net {
diff --git a/net/http/http_util.cc b/net/http/http_util.cc
index fed74b6..f654a99 100644
--- a/net/http/http_util.cc
+++ b/net/http/http_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,12 +14,6 @@
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_util.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_util.h"
-#include "net/base/upload_data_stream.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_auth_controller.h"
using std::string;
@@ -636,95 +630,6 @@ HttpUtil::HeadersIterator::HeadersIterator(string::const_iterator headers_begin,
: lines_(headers_begin, headers_end, line_delimiter) {
}
-namespace {
-
-bool HaveAuth(const scoped_refptr<HttpAuthController> auth_controllers[],
- HttpAuth::Target target) {
- return auth_controllers[target].get() &&
- auth_controllers[target]->HaveAuth();
-}
-
-} // namespace
-
-void HttpUtil::BuildRequestHeaders(const HttpRequestInfo* request_info,
- const UploadDataStream* upload_data_stream,
- const scoped_refptr<HttpAuthController>
- auth_controllers[],
- bool should_apply_server_auth,
- bool should_apply_proxy_auth,
- bool using_proxy,
- HttpRequestHeaders* request_headers) {
- request_headers->SetHeader(HttpRequestHeaders::kHost,
- GetHostAndOptionalPort(request_info->url));
-
- // For compat with HTTP/1.0 servers and proxies:
- if (using_proxy) {
- request_headers->SetHeader(HttpRequestHeaders::kProxyConnection,
- "keep-alive");
- } else {
- request_headers->SetHeader(HttpRequestHeaders::kConnection, "keep-alive");
- }
-
- // Our consumer should have made sure that this is a safe referrer. See for
- // instance WebCore::FrameLoader::HideReferrer.
- if (request_info->referrer.is_valid()) {
- request_headers->SetHeader(HttpRequestHeaders::kReferer,
- request_info->referrer.spec());
- }
-
- // Add a content length header?
- if (upload_data_stream) {
- if (upload_data_stream->is_chunked()) {
- request_headers->SetHeader(
- HttpRequestHeaders::kTransferEncoding, "chunked");
- } else {
- request_headers->SetHeader(
- HttpRequestHeaders::kContentLength,
- base::Uint64ToString(upload_data_stream->size()));
- }
- } else if (request_info->method == "POST" || request_info->method == "PUT" ||
- request_info->method == "HEAD") {
- // An empty POST/PUT request still needs a content length. As for HEAD,
- // IE and Safari also add a content length header. Presumably it is to
- // support sending a HEAD request to an URL that only expects to be sent a
- // POST or some other method that normally would have a message body.
- request_headers->SetHeader(HttpRequestHeaders::kContentLength, "0");
- }
-
- // Honor load flags that impact proxy caches.
- if (request_info->load_flags & LOAD_BYPASS_CACHE) {
- request_headers->SetHeader(HttpRequestHeaders::kPragma, "no-cache");
- request_headers->SetHeader(HttpRequestHeaders::kCacheControl, "no-cache");
- } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) {
- request_headers->SetHeader(HttpRequestHeaders::kCacheControl, "max-age=0");
- }
-
- if (should_apply_proxy_auth &&
- HaveAuth(auth_controllers, HttpAuth::AUTH_PROXY))
- auth_controllers[HttpAuth::AUTH_PROXY]->AddAuthorizationHeader(
- request_headers);
- if (should_apply_server_auth &&
- HaveAuth(auth_controllers, HttpAuth::AUTH_SERVER))
- auth_controllers[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader(
- request_headers);
-
- // Headers that will be stripped from request_info->extra_headers to prevent,
- // e.g., plugins from overriding headers that are controlled using other
- // means. Otherwise a plugin could set a referrer although sending the
- // referrer is inhibited.
- // TODO(jochen): check whether also other headers should be stripped.
- static const char* const kExtraHeadersToBeStripped[] = {
- "Referer"
- };
-
- HttpRequestHeaders stripped_extra_headers;
- stripped_extra_headers.CopyFrom(request_info->extra_headers);
- for (size_t i = 0; i < arraysize(kExtraHeadersToBeStripped); ++i)
- stripped_extra_headers.RemoveHeader(kExtraHeadersToBeStripped[i]);
- request_headers->MergeFrom(stripped_extra_headers);
-}
-
-
HttpUtil::HeadersIterator::~HeadersIterator() {
}
diff --git a/net/http/http_util.h b/net/http/http_util.h
index 3da1635..91ea9c3 100644
--- a/net/http/http_util.h
+++ b/net/http/http_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -9,7 +9,7 @@
#include <string>
#include <vector>
-#include "base/ref_counted.h"
+#include "base/memory/ref_counted.h"
#include "base/string_tokenizer.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_byte_range.h"
@@ -20,10 +20,6 @@
namespace net {
-class HttpAuthController;
-struct HttpRequestInfo;
-class HttpRequestHeaders;
-class HttpStream;
class UploadDataStream;
class HttpUtil {
@@ -164,19 +160,6 @@ class HttpUtil {
const std::string& header_value,
std::string* headers);
- // Constructs |request_headers| from the information contained in
- // |request_info|. The correct server and proxy auth headers will
- // be populated from |auth_controllers| if |enable_server_auth| or
- // |enable_proxy_auth| is true.
- static void BuildRequestHeaders(const HttpRequestInfo* request_info,
- const UploadDataStream* upload_data_stream,
- const scoped_refptr<HttpAuthController>
- auth_controllers[],
- bool enable_server_auth,
- bool enable_proxy_auth,
- bool enable_full_url,
- HttpRequestHeaders* request_headers);
-
// Used to iterate over the name/value pairs of HTTP headers. To iterate
// over the values in a multi-value header, use ValuesIterator.
// See AssembleRawHeaders for joining line continuations (this iterator
diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc
index c1f448e..d76d689 100644
--- a/net/http/partial_data.cc
+++ b/net/http/partial_data.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -273,6 +273,9 @@ bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers,
return true;
}
+ if (!headers->HasStrongValidators())
+ return false;
+
int64 length_value = headers->GetContentLength();
if (length_value <= 0)
return false; // We must have stored the resource length.
diff --git a/net/http/url_security_manager.h b/net/http/url_security_manager.h
index 119d6bd..2692252 100644
--- a/net/http/url_security_manager.h
+++ b/net/http/url_security_manager.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -6,8 +6,8 @@
#define NET_HTTP_URL_SECURITY_MANAGER_H_
#pragma once
-#include "base/scoped_ptr.h"
#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
class GURL;
diff --git a/net/http/url_security_manager_win.cc b/net/http/url_security_manager_win.cc
index 1770a19..858cc50 100644
--- a/net/http/url_security_manager_win.cc
+++ b/net/http/url_security_manager_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,9 +7,9 @@
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
-#include "base/scoped_comptr_win.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "base/win/scoped_comptr.h"
#include "googleurl/src/gurl.h"
#include "net/http/http_auth_filter.h"
@@ -37,7 +37,7 @@ class URLSecurityManagerWin : public URLSecurityManager {
private:
bool EnsureSystemSecurityManager();
- ScopedComPtr<IInternetSecurityManager> security_manager_;
+ base::win::ScopedComPtr<IInternetSecurityManager> security_manager_;
scoped_ptr<const HttpAuthFilter> whitelist_delegate_;
DISALLOW_COPY_AND_ASSIGN(URLSecurityManagerWin);