Index: net/url_request/url_request_unittest.cc |
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc |
deleted file mode 100644 |
index 5937464aae17550f829f7274a8b647b39d62dc07..0000000000000000000000000000000000000000 |
--- a/net/url_request/url_request_unittest.cc |
+++ /dev/null |
@@ -1,8824 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "build/build_config.h" |
- |
-#if defined(OS_WIN) |
-#include <windows.h> |
-#include <shlobj.h> |
-#endif |
- |
-#include <algorithm> |
- |
-#include "base/basictypes.h" |
-#include "base/bind.h" |
-#include "base/compiler_specific.h" |
-#include "base/files/file_util.h" |
-#include "base/files/scoped_temp_dir.h" |
-#include "base/format_macros.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/memory/weak_ptr.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/message_loop/message_loop_proxy.h" |
-#include "base/path_service.h" |
-#include "base/run_loop.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_piece.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "net/base/capturing_net_log.h" |
-#include "net/base/chunked_upload_data_stream.h" |
-#include "net/base/elements_upload_data_stream.h" |
-#include "net/base/load_flags.h" |
-#include "net/base/load_timing_info.h" |
-#include "net/base/load_timing_info_test_util.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/net_log.h" |
-#include "net/base/net_log_unittest.h" |
-#include "net/base/net_module.h" |
-#include "net/base/net_util.h" |
-#include "net/base/request_priority.h" |
-#include "net/base/test_data_directory.h" |
-#include "net/base/upload_bytes_element_reader.h" |
-#include "net/base/upload_data_stream.h" |
-#include "net/base/upload_file_element_reader.h" |
-#include "net/cert/ev_root_ca_metadata.h" |
-#include "net/cert/mock_cert_verifier.h" |
-#include "net/cert/test_root_certs.h" |
-#include "net/cookies/cookie_monster.h" |
-#include "net/cookies/cookie_store_test_helpers.h" |
-#include "net/disk_cache/disk_cache.h" |
-#include "net/dns/mock_host_resolver.h" |
-#include "net/ftp/ftp_network_layer.h" |
-#include "net/http/http_byte_range.h" |
-#include "net/http/http_cache.h" |
-#include "net/http/http_network_layer.h" |
-#include "net/http/http_network_session.h" |
-#include "net/http/http_request_headers.h" |
-#include "net/http/http_response_headers.h" |
-#include "net/http/http_util.h" |
-#include "net/ocsp/nss_ocsp.h" |
-#include "net/proxy/proxy_service.h" |
-#include "net/socket/ssl_client_socket.h" |
-#include "net/ssl/ssl_cipher_suite_names.h" |
-#include "net/ssl/ssl_connection_status_flags.h" |
-#include "net/test/cert_test_util.h" |
-#include "net/test/spawned_test_server/spawned_test_server.h" |
-#include "net/url_request/data_protocol_handler.h" |
-#include "net/url_request/static_http_user_agent_settings.h" |
-#include "net/url_request/url_request.h" |
-#include "net/url_request/url_request_http_job.h" |
-#include "net/url_request/url_request_intercepting_job_factory.h" |
-#include "net/url_request/url_request_interceptor.h" |
-#include "net/url_request/url_request_job_factory_impl.h" |
-#include "net/url_request/url_request_redirect_job.h" |
-#include "net/url_request/url_request_test_job.h" |
-#include "net/url_request/url_request_test_util.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
-#include "testing/platform_test.h" |
- |
-#if !defined(DISABLE_FILE_SUPPORT) |
-#include "net/base/filename_util.h" |
-#include "net/url_request/file_protocol_handler.h" |
-#include "net/url_request/url_request_file_dir_job.h" |
-#endif |
- |
-#if !defined(DISABLE_FTP_SUPPORT) |
-#include "net/url_request/ftp_protocol_handler.h" |
-#endif |
- |
-#if defined(OS_WIN) |
-#include "base/win/scoped_com_initializer.h" |
-#include "base/win/scoped_comptr.h" |
-#include "base/win/windows_version.h" |
-#endif |
- |
-using base::ASCIIToUTF16; |
-using base::Time; |
-using std::string; |
- |
-namespace net { |
- |
-namespace { |
- |
-const base::string16 kChrome(ASCIIToUTF16("chrome")); |
-const base::string16 kSecret(ASCIIToUTF16("secret")); |
-const base::string16 kUser(ASCIIToUTF16("user")); |
- |
-// Tests load timing information in the case a fresh connection was used, with |
-// no proxy. |
-void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info, |
- int connect_timing_flags) { |
- EXPECT_FALSE(load_timing_info.socket_reused); |
- EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
- |
- EXPECT_FALSE(load_timing_info.request_start_time.is_null()); |
- EXPECT_FALSE(load_timing_info.request_start.is_null()); |
- |
- EXPECT_LE(load_timing_info.request_start, |
- load_timing_info.connect_timing.connect_start); |
- ExpectConnectTimingHasTimes(load_timing_info.connect_timing, |
- connect_timing_flags); |
- EXPECT_LE(load_timing_info.connect_timing.connect_end, |
- load_timing_info.send_start); |
- EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); |
- EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); |
- |
- EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); |
- EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); |
-} |
- |
-// Same as above, but with proxy times. |
-void TestLoadTimingNotReusedWithProxy( |
- const LoadTimingInfo& load_timing_info, |
- int connect_timing_flags) { |
- EXPECT_FALSE(load_timing_info.socket_reused); |
- EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
- |
- EXPECT_FALSE(load_timing_info.request_start_time.is_null()); |
- EXPECT_FALSE(load_timing_info.request_start.is_null()); |
- |
- EXPECT_LE(load_timing_info.request_start, |
- load_timing_info.proxy_resolve_start); |
- EXPECT_LE(load_timing_info.proxy_resolve_start, |
- load_timing_info.proxy_resolve_end); |
- EXPECT_LE(load_timing_info.proxy_resolve_end, |
- load_timing_info.connect_timing.connect_start); |
- ExpectConnectTimingHasTimes(load_timing_info.connect_timing, |
- connect_timing_flags); |
- EXPECT_LE(load_timing_info.connect_timing.connect_end, |
- load_timing_info.send_start); |
- EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); |
- EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); |
-} |
- |
-// Same as above, but with a reused socket and proxy times. |
-void TestLoadTimingReusedWithProxy( |
- const LoadTimingInfo& load_timing_info) { |
- EXPECT_TRUE(load_timing_info.socket_reused); |
- EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
- |
- EXPECT_FALSE(load_timing_info.request_start_time.is_null()); |
- EXPECT_FALSE(load_timing_info.request_start.is_null()); |
- |
- ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); |
- |
- EXPECT_LE(load_timing_info.request_start, |
- load_timing_info.proxy_resolve_start); |
- EXPECT_LE(load_timing_info.proxy_resolve_start, |
- load_timing_info.proxy_resolve_end); |
- EXPECT_LE(load_timing_info.proxy_resolve_end, |
- load_timing_info.send_start); |
- EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); |
- EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); |
-} |
- |
-// Tests load timing information in the case of a cache hit, when no cache |
-// validation request was sent over the wire. |
-base::StringPiece TestNetResourceProvider(int key) { |
- return "header"; |
-} |
- |
-void FillBuffer(char* buffer, size_t len) { |
- static bool called = false; |
- if (!called) { |
- called = true; |
- int seed = static_cast<int>(Time::Now().ToInternalValue()); |
- srand(seed); |
- } |
- |
- for (size_t i = 0; i < len; i++) { |
- buffer[i] = static_cast<char>(rand()); |
- if (!buffer[i]) |
- buffer[i] = 'g'; |
- } |
-} |
- |
-#if !defined(OS_IOS) |
-void TestLoadTimingCacheHitNoNetwork( |
- const LoadTimingInfo& load_timing_info) { |
- EXPECT_FALSE(load_timing_info.socket_reused); |
- EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
- |
- EXPECT_FALSE(load_timing_info.request_start_time.is_null()); |
- EXPECT_FALSE(load_timing_info.request_start.is_null()); |
- |
- ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); |
- EXPECT_LE(load_timing_info.request_start, load_timing_info.send_start); |
- EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); |
- EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); |
- |
- EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); |
- EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); |
-} |
- |
-// Tests load timing in the case that there is no HTTP response. This can be |
-// used to test in the case of errors or non-HTTP requests. |
-void TestLoadTimingNoHttpResponse( |
- const LoadTimingInfo& load_timing_info) { |
- EXPECT_FALSE(load_timing_info.socket_reused); |
- EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); |
- |
- // Only the request times should be non-null. |
- EXPECT_FALSE(load_timing_info.request_start_time.is_null()); |
- EXPECT_FALSE(load_timing_info.request_start.is_null()); |
- |
- ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); |
- |
- EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); |
- EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); |
- EXPECT_TRUE(load_timing_info.send_start.is_null()); |
- EXPECT_TRUE(load_timing_info.send_end.is_null()); |
- EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); |
-} |
- |
-// Do a case-insensitive search through |haystack| for |needle|. |
-bool ContainsString(const std::string& haystack, const char* needle) { |
- std::string::const_iterator it = |
- std::search(haystack.begin(), |
- haystack.end(), |
- needle, |
- needle + strlen(needle), |
- base::CaseInsensitiveCompare<char>()); |
- return it != haystack.end(); |
-} |
- |
-scoped_ptr<UploadDataStream> CreateSimpleUploadData(const char* data) { |
- scoped_ptr<UploadElementReader> reader( |
- new UploadBytesElementReader(data, strlen(data))); |
- return ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0); |
-} |
- |
-// Verify that the SSLInfo of a successful SSL connection has valid values. |
-void CheckSSLInfo(const SSLInfo& ssl_info) { |
- // -1 means unknown. 0 means no encryption. |
- EXPECT_GT(ssl_info.security_bits, 0); |
- |
- // The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated. |
- uint16 cipher_suite = SSLConnectionStatusToCipherSuite( |
- ssl_info.connection_status); |
- EXPECT_NE(0U, cipher_suite); |
-} |
- |
-void CheckFullRequestHeaders(const HttpRequestHeaders& headers, |
- const GURL& host_url) { |
- std::string sent_value; |
- |
- EXPECT_TRUE(headers.GetHeader("Host", &sent_value)); |
- EXPECT_EQ(GetHostAndOptionalPort(host_url), sent_value); |
- |
- EXPECT_TRUE(headers.GetHeader("Connection", &sent_value)); |
- EXPECT_EQ("keep-alive", sent_value); |
-} |
- |
-bool FingerprintsEqual(const HashValueVector& a, const HashValueVector& b) { |
- size_t size = a.size(); |
- |
- if (size != b.size()) |
- return false; |
- |
- for (size_t i = 0; i < size; ++i) { |
- if (!a[i].Equals(b[i])) |
- return false; |
- } |
- |
- return true; |
-} |
-#endif // !defined(OS_IOS) |
- |
-// A network delegate that allows the user to choose a subset of request stages |
-// to block in. When blocking, the delegate can do one of the following: |
-// * synchronously return a pre-specified error code, or |
-// * asynchronously return that value via an automatically called callback, |
-// or |
-// * block and wait for the user to do a callback. |
-// Additionally, the user may also specify a redirect URL -- then each request |
-// with the current URL different from the redirect target will be redirected |
-// to that target, in the on-before-URL-request stage, independent of whether |
-// the delegate blocks in ON_BEFORE_URL_REQUEST or not. |
-class BlockingNetworkDelegate : public TestNetworkDelegate { |
- public: |
- // Stages in which the delegate can block. |
- enum Stage { |
- NOT_BLOCKED = 0, |
- ON_BEFORE_URL_REQUEST = 1 << 0, |
- ON_BEFORE_SEND_HEADERS = 1 << 1, |
- ON_HEADERS_RECEIVED = 1 << 2, |
- ON_AUTH_REQUIRED = 1 << 3 |
- }; |
- |
- // Behavior during blocked stages. During other stages, just |
- // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION. |
- enum BlockMode { |
- SYNCHRONOUS, // No callback, returns specified return values. |
- AUTO_CALLBACK, // |this| posts a task to run the callback using the |
- // specified return codes. |
- USER_CALLBACK, // User takes care of doing a callback. |retval_| and |
- // |auth_retval_| are ignored. In every blocking stage the |
- // message loop is quit. |
- }; |
- |
- // Creates a delegate which does not block at all. |
- explicit BlockingNetworkDelegate(BlockMode block_mode); |
- |
- // For users to trigger a callback returning |response|. |
- // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks. |
- // Only call if |block_mode_| == USER_CALLBACK. |
- void DoCallback(int response); |
- void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response); |
- |
- // Setters. |
- void set_retval(int retval) { |
- ASSERT_NE(USER_CALLBACK, block_mode_); |
- ASSERT_NE(ERR_IO_PENDING, retval); |
- ASSERT_NE(OK, retval); |
- retval_ = retval; |
- } |
- |
- // If |auth_retval| == AUTH_REQUIRED_RESPONSE_SET_AUTH, then |
- // |auth_credentials_| will be passed with the response. |
- void set_auth_retval(AuthRequiredResponse auth_retval) { |
- ASSERT_NE(USER_CALLBACK, block_mode_); |
- ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval); |
- auth_retval_ = auth_retval; |
- } |
- void set_auth_credentials(const AuthCredentials& auth_credentials) { |
- auth_credentials_ = auth_credentials; |
- } |
- |
- void set_redirect_url(const GURL& url) { |
- redirect_url_ = url; |
- } |
- |
- void set_block_on(int block_on) { |
- block_on_ = block_on; |
- } |
- |
- // Allows the user to check in which state did we block. |
- Stage stage_blocked_for_callback() const { |
- EXPECT_EQ(USER_CALLBACK, block_mode_); |
- return stage_blocked_for_callback_; |
- } |
- |
- private: |
- void RunCallback(int response, const CompletionCallback& callback); |
- void RunAuthCallback(AuthRequiredResponse response, |
- const AuthCallback& callback); |
- |
- // TestNetworkDelegate implementation. |
- int OnBeforeURLRequest(URLRequest* request, |
- const CompletionCallback& callback, |
- GURL* new_url) override; |
- |
- int OnBeforeSendHeaders(URLRequest* request, |
- const CompletionCallback& callback, |
- HttpRequestHeaders* headers) override; |
- |
- int OnHeadersReceived( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- const HttpResponseHeaders* original_response_headers, |
- scoped_refptr<HttpResponseHeaders>* override_response_headers, |
- GURL* allowed_unsafe_redirect_url) override; |
- |
- NetworkDelegate::AuthRequiredResponse OnAuthRequired( |
- URLRequest* request, |
- const AuthChallengeInfo& auth_info, |
- const AuthCallback& callback, |
- AuthCredentials* credentials) override; |
- |
- // Resets the callbacks and |stage_blocked_for_callback_|. |
- void Reset(); |
- |
- // Checks whether we should block in |stage|. If yes, returns an error code |
- // and optionally sets up callback based on |block_mode_|. If no, returns OK. |
- int MaybeBlockStage(Stage stage, const CompletionCallback& callback); |
- |
- // Configuration parameters, can be adjusted by public methods: |
- const BlockMode block_mode_; |
- |
- // Values returned on blocking stages when mode is SYNCHRONOUS or |
- // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. |
- int retval_; // To be returned in non-auth stages. |
- AuthRequiredResponse auth_retval_; |
- |
- GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. |
- int block_on_; // Bit mask: in which stages to block. |
- |
- // |auth_credentials_| will be copied to |*target_auth_credential_| on |
- // callback. |
- AuthCredentials auth_credentials_; |
- AuthCredentials* target_auth_credentials_; |
- |
- // Internal variables, not set by not the user: |
- // Last blocked stage waiting for user callback (unused if |block_mode_| != |
- // USER_CALLBACK). |
- Stage stage_blocked_for_callback_; |
- |
- // Callback objects stored during blocking stages. |
- CompletionCallback callback_; |
- AuthCallback auth_callback_; |
- |
- base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate); |
-}; |
- |
-BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode) |
- : block_mode_(block_mode), |
- retval_(OK), |
- auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION), |
- block_on_(0), |
- target_auth_credentials_(NULL), |
- stage_blocked_for_callback_(NOT_BLOCKED), |
- weak_factory_(this) { |
-} |
- |
-void BlockingNetworkDelegate::DoCallback(int response) { |
- ASSERT_EQ(USER_CALLBACK, block_mode_); |
- ASSERT_NE(NOT_BLOCKED, stage_blocked_for_callback_); |
- ASSERT_NE(ON_AUTH_REQUIRED, stage_blocked_for_callback_); |
- CompletionCallback callback = callback_; |
- Reset(); |
- RunCallback(response, callback); |
-} |
- |
-void BlockingNetworkDelegate::DoAuthCallback( |
- NetworkDelegate::AuthRequiredResponse response) { |
- ASSERT_EQ(USER_CALLBACK, block_mode_); |
- ASSERT_EQ(ON_AUTH_REQUIRED, stage_blocked_for_callback_); |
- AuthCallback auth_callback = auth_callback_; |
- Reset(); |
- RunAuthCallback(response, auth_callback); |
-} |
- |
-void BlockingNetworkDelegate::RunCallback(int response, |
- const CompletionCallback& callback) { |
- callback.Run(response); |
-} |
- |
-void BlockingNetworkDelegate::RunAuthCallback(AuthRequiredResponse response, |
- const AuthCallback& callback) { |
- if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) { |
- ASSERT_TRUE(target_auth_credentials_ != NULL); |
- *target_auth_credentials_ = auth_credentials_; |
- } |
- callback.Run(response); |
-} |
- |
-int BlockingNetworkDelegate::OnBeforeURLRequest( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- GURL* new_url) { |
- if (redirect_url_ == request->url()) |
- return OK; // We've already seen this request and redirected elsewhere. |
- |
- TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); |
- |
- if (!redirect_url_.is_empty()) |
- *new_url = redirect_url_; |
- |
- return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback); |
-} |
- |
-int BlockingNetworkDelegate::OnBeforeSendHeaders( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- HttpRequestHeaders* headers) { |
- TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers); |
- |
- return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback); |
-} |
- |
-int BlockingNetworkDelegate::OnHeadersReceived( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- const HttpResponseHeaders* original_response_headers, |
- scoped_refptr<HttpResponseHeaders>* override_response_headers, |
- GURL* allowed_unsafe_redirect_url) { |
- TestNetworkDelegate::OnHeadersReceived(request, |
- callback, |
- original_response_headers, |
- override_response_headers, |
- allowed_unsafe_redirect_url); |
- |
- return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); |
-} |
- |
-NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( |
- URLRequest* request, |
- const AuthChallengeInfo& auth_info, |
- const AuthCallback& callback, |
- AuthCredentials* credentials) { |
- TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, |
- credentials); |
- // Check that the user has provided callback for the previous blocked stage. |
- EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); |
- |
- if ((block_on_ & ON_AUTH_REQUIRED) == 0) { |
- return AUTH_REQUIRED_RESPONSE_NO_ACTION; |
- } |
- |
- target_auth_credentials_ = credentials; |
- |
- switch (block_mode_) { |
- case SYNCHRONOUS: |
- if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) |
- *target_auth_credentials_ = auth_credentials_; |
- return auth_retval_; |
- |
- case AUTO_CALLBACK: |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&BlockingNetworkDelegate::RunAuthCallback, |
- weak_factory_.GetWeakPtr(), auth_retval_, callback)); |
- return AUTH_REQUIRED_RESPONSE_IO_PENDING; |
- |
- case USER_CALLBACK: |
- auth_callback_ = callback; |
- stage_blocked_for_callback_ = ON_AUTH_REQUIRED; |
- base::MessageLoop::current()->PostTask(FROM_HERE, |
- base::MessageLoop::QuitClosure()); |
- return AUTH_REQUIRED_RESPONSE_IO_PENDING; |
- } |
- NOTREACHED(); |
- return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value. |
-} |
- |
-void BlockingNetworkDelegate::Reset() { |
- EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_); |
- stage_blocked_for_callback_ = NOT_BLOCKED; |
- callback_.Reset(); |
- auth_callback_.Reset(); |
-} |
- |
-int BlockingNetworkDelegate::MaybeBlockStage( |
- BlockingNetworkDelegate::Stage stage, |
- const CompletionCallback& callback) { |
- // Check that the user has provided callback for the previous blocked stage. |
- EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); |
- |
- if ((block_on_ & stage) == 0) { |
- return OK; |
- } |
- |
- switch (block_mode_) { |
- case SYNCHRONOUS: |
- EXPECT_NE(OK, retval_); |
- return retval_; |
- |
- case AUTO_CALLBACK: |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&BlockingNetworkDelegate::RunCallback, |
- weak_factory_.GetWeakPtr(), retval_, callback)); |
- return ERR_IO_PENDING; |
- |
- case USER_CALLBACK: |
- callback_ = callback; |
- stage_blocked_for_callback_ = stage; |
- base::MessageLoop::current()->PostTask(FROM_HERE, |
- base::MessageLoop::QuitClosure()); |
- return ERR_IO_PENDING; |
- } |
- NOTREACHED(); |
- return 0; |
-} |
- |
-class TestURLRequestContextWithProxy : public TestURLRequestContext { |
- public: |
- // Does not own |delegate|. |
- TestURLRequestContextWithProxy(const std::string& proxy, |
- NetworkDelegate* delegate) |
- : TestURLRequestContext(true) { |
- context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy)); |
- set_network_delegate(delegate); |
- Init(); |
- } |
- ~TestURLRequestContextWithProxy() override {} |
-}; |
- |
-} // namespace |
- |
-// Inherit PlatformTest since we require the autorelease pool on Mac OS X. |
-class URLRequestTest : public PlatformTest { |
- public: |
- URLRequestTest() : default_context_(true) { |
- default_context_.set_network_delegate(&default_network_delegate_); |
- default_context_.set_net_log(&net_log_); |
- job_factory_impl_ = new URLRequestJobFactoryImpl(); |
- job_factory_.reset(job_factory_impl_); |
- } |
- |
- ~URLRequestTest() override { |
- // URLRequestJobs may post clean-up tasks on destruction. |
- base::RunLoop().RunUntilIdle(); |
- } |
- |
- void SetUp() override { |
- SetUpFactory(); |
- default_context_.set_job_factory(job_factory_.get()); |
- default_context_.Init(); |
- PlatformTest::SetUp(); |
- } |
- |
- virtual void SetUpFactory() { |
- job_factory_impl_->SetProtocolHandler("data", new DataProtocolHandler); |
-#if !defined(DISABLE_FILE_SUPPORT) |
- job_factory_impl_->SetProtocolHandler( |
- "file", new FileProtocolHandler(base::MessageLoopProxy::current())); |
-#endif |
- } |
- |
- TestNetworkDelegate* default_network_delegate() { |
- return &default_network_delegate_; |
- } |
- |
- const TestURLRequestContext& default_context() const { |
- return default_context_; |
- } |
- |
- |
- // Adds the TestJobInterceptor to the default context. |
- TestJobInterceptor* AddTestInterceptor() { |
- TestJobInterceptor* protocol_handler_ = new TestJobInterceptor(); |
- job_factory_impl_->SetProtocolHandler("http", NULL); |
- job_factory_impl_->SetProtocolHandler("http", protocol_handler_); |
- return protocol_handler_; |
- } |
- |
- protected: |
- CapturingNetLog net_log_; |
- TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. |
- URLRequestJobFactoryImpl* job_factory_impl_; |
- scoped_ptr<URLRequestJobFactory> job_factory_; |
- TestURLRequestContext default_context_; |
-}; |
- |
-TEST_F(URLRequestTest, AboutBlankTest) { |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- GURL("about:blank"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), 0); |
- EXPECT_EQ("", r->GetSocketAddress().host()); |
- EXPECT_EQ(0, r->GetSocketAddress().port()); |
- |
- HttpRequestHeaders headers; |
- EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DataURLImageTest) { |
- TestDelegate d; |
- { |
- // Use our nice little Chrome logo. |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- GURL( |
- "data:image/png;base64," |
- "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3" |
- "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD" |
- "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t" |
- "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9" |
- "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1" |
- "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z" |
- "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW" |
- "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW" |
- "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb" |
- "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5" |
- "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV" |
- "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq" |
- "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F" |
- "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB" |
- "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM" |
- "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm" |
- "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En" |
- "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="), |
- DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), 911); |
- EXPECT_EQ("", r->GetSocketAddress().host()); |
- EXPECT_EQ(0, r->GetSocketAddress().port()); |
- |
- HttpRequestHeaders headers; |
- EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); |
- } |
-} |
- |
-#if !defined(DISABLE_FILE_SUPPORT) |
-TEST_F(URLRequestTest, FileTest) { |
- base::FilePath app_path; |
- PathService::Get(base::FILE_EXE, &app_path); |
- GURL app_url = FilePathToFileURL(app_path); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- app_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = -1; |
- EXPECT_TRUE(base::GetFileSize(app_path, &file_size)); |
- |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
- EXPECT_EQ("", r->GetSocketAddress().host()); |
- EXPECT_EQ(0, r->GetSocketAddress().port()); |
- |
- HttpRequestHeaders headers; |
- EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); |
- } |
-} |
- |
-TEST_F(URLRequestTest, FileTestCancel) { |
- base::FilePath app_path; |
- PathService::Get(base::FILE_EXE, &app_path); |
- GURL app_url = FilePathToFileURL(app_path); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- app_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- r->Cancel(); |
- } |
- // Async cancellation should be safe even when URLRequest has been already |
- // destroyed. |
- base::RunLoop().RunUntilIdle(); |
-} |
- |
-TEST_F(URLRequestTest, FileTestFullSpecifiedRange) { |
- const size_t buffer_size = 4000; |
- scoped_ptr<char[]> buffer(new char[buffer_size]); |
- FillBuffer(buffer.get(), buffer_size); |
- |
- base::FilePath temp_path; |
- EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); |
- GURL temp_url = FilePathToFileURL(temp_path); |
- EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); |
- |
- int64 file_size; |
- EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); |
- |
- const size_t first_byte_position = 500; |
- const size_t last_byte_position = buffer_size - first_byte_position; |
- const size_t content_length = last_byte_position - first_byte_position + 1; |
- std::string partial_buffer_string(buffer.get() + first_byte_position, |
- buffer.get() + last_byte_position + 1); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- temp_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- HttpRequestHeaders headers; |
- headers.SetHeader( |
- HttpRequestHeaders::kRange, |
- HttpByteRange::Bounded( |
- first_byte_position, last_byte_position).GetHeaderValue()); |
- r->SetExtraRequestHeaders(headers); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); |
- // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. |
- EXPECT_TRUE(partial_buffer_string == d.data_received()); |
- } |
- |
- EXPECT_TRUE(base::DeleteFile(temp_path, false)); |
-} |
- |
-TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) { |
- const size_t buffer_size = 4000; |
- scoped_ptr<char[]> buffer(new char[buffer_size]); |
- FillBuffer(buffer.get(), buffer_size); |
- |
- base::FilePath temp_path; |
- EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); |
- GURL temp_url = FilePathToFileURL(temp_path); |
- EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); |
- |
- int64 file_size; |
- EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); |
- |
- const size_t first_byte_position = 500; |
- const size_t last_byte_position = buffer_size - 1; |
- const size_t content_length = last_byte_position - first_byte_position + 1; |
- std::string partial_buffer_string(buffer.get() + first_byte_position, |
- buffer.get() + last_byte_position + 1); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- temp_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kRange, |
- HttpByteRange::RightUnbounded( |
- first_byte_position).GetHeaderValue()); |
- r->SetExtraRequestHeaders(headers); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); |
- // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. |
- EXPECT_TRUE(partial_buffer_string == d.data_received()); |
- } |
- |
- EXPECT_TRUE(base::DeleteFile(temp_path, false)); |
-} |
- |
-TEST_F(URLRequestTest, FileTestMultipleRanges) { |
- const size_t buffer_size = 400000; |
- scoped_ptr<char[]> buffer(new char[buffer_size]); |
- FillBuffer(buffer.get(), buffer_size); |
- |
- base::FilePath temp_path; |
- EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); |
- GURL temp_url = FilePathToFileURL(temp_path); |
- EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); |
- |
- int64 file_size; |
- EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- temp_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kRange, "bytes=0-0,10-200,200-300"); |
- r->SetExtraRequestHeaders(headers); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- EXPECT_TRUE(d.request_failed()); |
- } |
- |
- EXPECT_TRUE(base::DeleteFile(temp_path, false)); |
-} |
- |
-TEST_F(URLRequestTest, AllowFileURLs) { |
- base::ScopedTempDir temp_dir; |
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
- base::FilePath test_file; |
- ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &test_file)); |
- std::string test_data("monkey"); |
- base::WriteFile(test_file, test_data.data(), test_data.size()); |
- GURL test_file_url = FilePathToFileURL(test_file); |
- |
- { |
- TestDelegate d; |
- TestNetworkDelegate network_delegate; |
- network_delegate.set_can_access_files(true); |
- default_context_.set_network_delegate(&network_delegate); |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_file_url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_FALSE(d.request_failed()); |
- EXPECT_EQ(test_data, d.data_received()); |
- } |
- |
- { |
- TestDelegate d; |
- TestNetworkDelegate network_delegate; |
- network_delegate.set_can_access_files(false); |
- default_context_.set_network_delegate(&network_delegate); |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_file_url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_TRUE(d.request_failed()); |
- EXPECT_EQ("", d.data_received()); |
- } |
-} |
- |
- |
-TEST_F(URLRequestTest, FileDirCancelTest) { |
- // Put in mock resource provider. |
- NetModule::SetResourceProvider(TestNetResourceProvider); |
- |
- TestDelegate d; |
- { |
- base::FilePath file_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &file_path); |
- file_path = file_path.Append(FILE_PATH_LITERAL("net")); |
- file_path = file_path.Append(FILE_PATH_LITERAL("data")); |
- |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- FilePathToFileURL(file_path), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- EXPECT_TRUE(req->is_pending()); |
- |
- d.set_cancel_in_received_data_pending(true); |
- |
- base::RunLoop().Run(); |
- } |
- |
- // Take out mock resource provider. |
- NetModule::SetResourceProvider(NULL); |
-} |
- |
-TEST_F(URLRequestTest, FileDirOutputSanity) { |
- // Verify the general sanity of the the output of the file: |
- // directory lister by checking for the output of a known existing |
- // file. |
- const char sentinel_name[] = "filedir-sentinel"; |
- |
- base::FilePath path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &path); |
- path = path.Append(FILE_PATH_LITERAL("net")); |
- path = path.Append(FILE_PATH_LITERAL("data")); |
- path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Generate entry for the sentinel file. |
- base::FilePath sentinel_path = path.AppendASCII(sentinel_name); |
- base::File::Info info; |
- EXPECT_TRUE(base::GetFileInfo(sentinel_path, &info)); |
- EXPECT_GT(info.size, 0); |
- std::string sentinel_output = GetDirectoryListingEntry( |
- base::string16(sentinel_name, sentinel_name + strlen(sentinel_name)), |
- std::string(sentinel_name), |
- false /* is_dir */, |
- info.size, |
- info.last_modified); |
- |
- ASSERT_LT(0, d.bytes_received()); |
- ASSERT_FALSE(d.request_failed()); |
- ASSERT_TRUE(req->status().is_success()); |
- // Check for the entry generated for the "sentinel" file. |
- const std::string& data = d.data_received(); |
- ASSERT_NE(data.find(sentinel_output), std::string::npos); |
-} |
- |
-TEST_F(URLRequestTest, FileDirRedirectNoCrash) { |
- // There is an implicit redirect when loading a file path that matches a |
- // directory and does not end with a slash. Ensure that following such |
- // redirects does not crash. See http://crbug.com/18686. |
- |
- base::FilePath path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &path); |
- path = path.Append(FILE_PATH_LITERAL("net")); |
- path = path.Append(FILE_PATH_LITERAL("data")); |
- path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- ASSERT_EQ(1, d.received_redirect_count()); |
- ASSERT_LT(0, d.bytes_received()); |
- ASSERT_FALSE(d.request_failed()); |
- ASSERT_TRUE(req->status().is_success()); |
-} |
- |
-#if defined(OS_WIN) |
-// Don't accept the url "file:///" on windows. See http://crbug.com/1474. |
-TEST_F(URLRequestTest, FileDirRedirectSingleSlash) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("file:///"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- ASSERT_EQ(1, d.received_redirect_count()); |
- ASSERT_FALSE(req->status().is_success()); |
-} |
-#endif // defined(OS_WIN) |
- |
-#endif // !defined(DISABLE_FILE_SUPPORT) |
- |
-TEST_F(URLRequestTest, InvalidUrlTest) { |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- GURL("invalid url"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- EXPECT_TRUE(d.request_failed()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, InvalidReferrerTest) { |
- TestURLRequestContext context; |
- TestNetworkDelegate network_delegate; |
- network_delegate.set_cancel_request_with_policy_violating_referrer(true); |
- context.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://localhost/"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetReferrer("https://somewhere.com/"); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_TRUE(d.request_failed()); |
-} |
- |
-#if defined(OS_WIN) |
-TEST_F(URLRequestTest, ResolveShortcutTest) { |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("net"); |
- app_path = app_path.AppendASCII("data"); |
- app_path = app_path.AppendASCII("url_request_unittest"); |
- app_path = app_path.AppendASCII("with-headers.html"); |
- |
- std::wstring lnk_path = app_path.value() + L".lnk"; |
- |
- base::win::ScopedCOMInitializer com_initializer; |
- |
- // Temporarily create a shortcut for test |
- { |
- base::win::ScopedComPtr<IShellLink> shell; |
- ASSERT_TRUE(SUCCEEDED(shell.CreateInstance(CLSID_ShellLink, NULL, |
- CLSCTX_INPROC_SERVER))); |
- base::win::ScopedComPtr<IPersistFile> persist; |
- ASSERT_TRUE(SUCCEEDED(shell.QueryInterface(persist.Receive()))); |
- EXPECT_TRUE(SUCCEEDED(shell->SetPath(app_path.value().c_str()))); |
- EXPECT_TRUE(SUCCEEDED(shell->SetDescription(L"ResolveShortcutTest"))); |
- EXPECT_TRUE(SUCCEEDED(persist->Save(lnk_path.c_str(), TRUE))); |
- } |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- FilePathToFileURL(base::FilePath(lnk_path)), DEFAULT_PRIORITY, &d, |
- NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- WIN32_FILE_ATTRIBUTE_DATA data; |
- GetFileAttributesEx(app_path.value().c_str(), |
- GetFileExInfoStandard, &data); |
- HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ, |
- FILE_SHARE_READ, NULL, OPEN_EXISTING, |
- FILE_ATTRIBUTE_NORMAL, NULL); |
- EXPECT_NE(INVALID_HANDLE_VALUE, file); |
- scoped_ptr<char[]> buffer(new char[data.nFileSizeLow]); |
- DWORD read_size; |
- BOOL result; |
- result = ReadFile(file, buffer.get(), data.nFileSizeLow, |
- &read_size, NULL); |
- std::string content(buffer.get(), read_size); |
- CloseHandle(file); |
- |
- EXPECT_TRUE(!r->is_pending()); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(content, d.data_received()); |
- } |
- |
- // Clean the shortcut |
- DeleteFile(lnk_path.c_str()); |
-} |
-#endif // defined(OS_WIN) |
- |
-// Custom URLRequestJobs for use with interceptor tests |
-class RestartTestJob : public URLRequestTestJob { |
- public: |
- RestartTestJob(URLRequest* request, NetworkDelegate* network_delegate) |
- : URLRequestTestJob(request, network_delegate, true) {} |
- protected: |
- void StartAsync() override { this->NotifyRestartRequired(); } |
- private: |
- ~RestartTestJob() override {} |
-}; |
- |
-class CancelTestJob : public URLRequestTestJob { |
- public: |
- explicit CancelTestJob(URLRequest* request, NetworkDelegate* network_delegate) |
- : URLRequestTestJob(request, network_delegate, true) {} |
- protected: |
- void StartAsync() override { request_->Cancel(); } |
- private: |
- ~CancelTestJob() override {} |
-}; |
- |
-class CancelThenRestartTestJob : public URLRequestTestJob { |
- public: |
- explicit CancelThenRestartTestJob(URLRequest* request, |
- NetworkDelegate* network_delegate) |
- : URLRequestTestJob(request, network_delegate, true) { |
- } |
- protected: |
- void StartAsync() override { |
- request_->Cancel(); |
- this->NotifyRestartRequired(); |
- } |
- private: |
- ~CancelThenRestartTestJob() override {} |
-}; |
- |
-// An Interceptor for use with interceptor tests. |
-class MockURLRequestInterceptor : public URLRequestInterceptor { |
- public: |
- // Static getters for canned response header and data strings. |
- static std::string ok_data() { |
- return URLRequestTestJob::test_data_1(); |
- } |
- |
- static std::string ok_headers() { |
- return URLRequestTestJob::test_headers(); |
- } |
- |
- static std::string redirect_data() { |
- return std::string(); |
- } |
- |
- static std::string redirect_headers() { |
- return URLRequestTestJob::test_redirect_headers(); |
- } |
- |
- static std::string error_data() { |
- return std::string("ohhh nooooo mr. bill!"); |
- } |
- |
- static std::string error_headers() { |
- return URLRequestTestJob::test_error_headers(); |
- } |
- |
- MockURLRequestInterceptor() |
- : intercept_main_request_(false), restart_main_request_(false), |
- cancel_main_request_(false), cancel_then_restart_main_request_(false), |
- simulate_main_network_error_(false), |
- intercept_redirect_(false), cancel_redirect_request_(false), |
- intercept_final_response_(false), cancel_final_request_(false), |
- use_url_request_http_job_(false), |
- did_intercept_main_(false), did_restart_main_(false), |
- did_cancel_main_(false), did_cancel_then_restart_main_(false), |
- did_simulate_error_main_(false), |
- did_intercept_redirect_(false), did_cancel_redirect_(false), |
- did_intercept_final_(false), did_cancel_final_(false) { |
- } |
- |
- ~MockURLRequestInterceptor() override { |
- } |
- |
- // URLRequestInterceptor implementation: |
- URLRequestJob* MaybeInterceptRequest( |
- URLRequest* request, |
- NetworkDelegate* network_delegate) const override { |
- if (restart_main_request_) { |
- restart_main_request_ = false; |
- did_restart_main_ = true; |
- return new RestartTestJob(request, network_delegate); |
- } |
- if (cancel_main_request_) { |
- cancel_main_request_ = false; |
- did_cancel_main_ = true; |
- return new CancelTestJob(request, network_delegate); |
- } |
- if (cancel_then_restart_main_request_) { |
- cancel_then_restart_main_request_ = false; |
- did_cancel_then_restart_main_ = true; |
- return new CancelThenRestartTestJob(request, network_delegate); |
- } |
- if (simulate_main_network_error_) { |
- simulate_main_network_error_ = false; |
- did_simulate_error_main_ = true; |
- if (use_url_request_http_job_) { |
- return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
- } |
- // This job will result in error since the requested URL is not one of the |
- // URLs supported by these tests. |
- return new URLRequestTestJob(request, network_delegate, true); |
- } |
- if (!intercept_main_request_) |
- return nullptr; |
- intercept_main_request_ = false; |
- did_intercept_main_ = true; |
- URLRequestTestJob* job = new URLRequestTestJob(request, |
- network_delegate, |
- main_headers_, |
- main_data_, |
- true); |
- job->set_load_timing_info(main_request_load_timing_info_); |
- return job; |
- } |
- |
- URLRequestJob* MaybeInterceptRedirect(URLRequest* request, |
- NetworkDelegate* network_delegate, |
- const GURL& location) const override { |
- if (cancel_redirect_request_) { |
- cancel_redirect_request_ = false; |
- did_cancel_redirect_ = true; |
- return new CancelTestJob(request, network_delegate); |
- } |
- if (!intercept_redirect_) |
- return nullptr; |
- intercept_redirect_ = false; |
- did_intercept_redirect_ = true; |
- if (use_url_request_http_job_) { |
- return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
- } |
- return new URLRequestTestJob(request, |
- network_delegate, |
- redirect_headers_, |
- redirect_data_, |
- true); |
- } |
- |
- URLRequestJob* MaybeInterceptResponse( |
- URLRequest* request, |
- NetworkDelegate* network_delegate) const override { |
- if (cancel_final_request_) { |
- cancel_final_request_ = false; |
- did_cancel_final_ = true; |
- return new CancelTestJob(request, network_delegate); |
- } |
- if (!intercept_final_response_) |
- return nullptr; |
- intercept_final_response_ = false; |
- did_intercept_final_ = true; |
- if (use_url_request_http_job_) { |
- return URLRequestHttpJob::Factory(request, network_delegate, "http"); |
- } |
- return new URLRequestTestJob(request, |
- network_delegate, |
- final_headers_, |
- final_data_, |
- true); |
- } |
- |
- void set_intercept_main_request(bool intercept_main_request) { |
- intercept_main_request_ = intercept_main_request; |
- } |
- |
- void set_main_headers(const std::string& main_headers) { |
- main_headers_ = main_headers; |
- } |
- |
- void set_main_data(const std::string& main_data) { |
- main_data_ = main_data; |
- } |
- |
- void set_main_request_load_timing_info( |
- const LoadTimingInfo& main_request_load_timing_info) { |
- main_request_load_timing_info_ = main_request_load_timing_info; |
- } |
- |
- void set_restart_main_request(bool restart_main_request) { |
- restart_main_request_ = restart_main_request; |
- } |
- |
- void set_cancel_main_request(bool cancel_main_request) { |
- cancel_main_request_ = cancel_main_request; |
- } |
- |
- void set_cancel_then_restart_main_request( |
- bool cancel_then_restart_main_request) { |
- cancel_then_restart_main_request_ = cancel_then_restart_main_request; |
- } |
- |
- void set_simulate_main_network_error(bool simulate_main_network_error) { |
- simulate_main_network_error_ = simulate_main_network_error; |
- } |
- |
- void set_intercept_redirect(bool intercept_redirect) { |
- intercept_redirect_ = intercept_redirect; |
- } |
- |
- void set_redirect_headers(const std::string& redirect_headers) { |
- redirect_headers_ = redirect_headers; |
- } |
- |
- void set_redirect_data(const std::string& redirect_data) { |
- redirect_data_ = redirect_data; |
- } |
- |
- void set_cancel_redirect_request(bool cancel_redirect_request) { |
- cancel_redirect_request_ = cancel_redirect_request; |
- } |
- |
- void set_intercept_final_response(bool intercept_final_response) { |
- intercept_final_response_ = intercept_final_response; |
- } |
- |
- void set_final_headers(const std::string& final_headers) { |
- final_headers_ = final_headers; |
- } |
- |
- void set_final_data(const std::string& final_data) { |
- final_data_ = final_data; |
- } |
- |
- void set_cancel_final_request(bool cancel_final_request) { |
- cancel_final_request_ = cancel_final_request; |
- } |
- |
- void set_use_url_request_http_job(bool use_url_request_http_job) { |
- use_url_request_http_job_ = use_url_request_http_job; |
- } |
- |
- bool did_intercept_main() const { |
- return did_intercept_main_; |
- } |
- |
- bool did_restart_main() const { |
- return did_restart_main_; |
- } |
- |
- bool did_cancel_main() const { |
- return did_cancel_main_; |
- } |
- |
- bool did_cancel_then_restart_main() const { |
- return did_cancel_then_restart_main_; |
- } |
- |
- bool did_simulate_error_main() const { |
- return did_simulate_error_main_; |
- } |
- |
- bool did_intercept_redirect() const { |
- return did_intercept_redirect_; |
- } |
- |
- bool did_cancel_redirect() const { |
- return did_cancel_redirect_; |
- } |
- |
- bool did_intercept_final() const { |
- return did_intercept_final_; |
- } |
- |
- bool did_cancel_final() const { |
- return did_cancel_final_; |
- } |
- |
- private: |
- // Indicate whether to intercept the main request, and if so specify the |
- // response to return and the LoadTimingInfo to use. |
- mutable bool intercept_main_request_; |
- mutable std::string main_headers_; |
- mutable std::string main_data_; |
- mutable LoadTimingInfo main_request_load_timing_info_; |
- |
- // These indicate actions that can be taken within MaybeInterceptRequest. |
- mutable bool restart_main_request_; |
- mutable bool cancel_main_request_; |
- mutable bool cancel_then_restart_main_request_; |
- mutable bool simulate_main_network_error_; |
- |
- // Indicate whether to intercept redirects, and if so specify the response to |
- // return. |
- mutable bool intercept_redirect_; |
- mutable std::string redirect_headers_; |
- mutable std::string redirect_data_; |
- |
- // Cancel the request within MaybeInterceptRedirect. |
- mutable bool cancel_redirect_request_; |
- |
- // Indicate whether to intercept the final response, and if so specify the |
- // response to return. |
- mutable bool intercept_final_response_; |
- mutable std::string final_headers_; |
- mutable std::string final_data_; |
- |
- // Cancel the final request within MaybeInterceptResponse. |
- mutable bool cancel_final_request_; |
- |
- // Instruct the interceptor to use a real URLRequestHTTPJob. |
- mutable bool use_url_request_http_job_; |
- |
- // These indicate if the interceptor did something or not. |
- mutable bool did_intercept_main_; |
- mutable bool did_restart_main_; |
- mutable bool did_cancel_main_; |
- mutable bool did_cancel_then_restart_main_; |
- mutable bool did_simulate_error_main_; |
- mutable bool did_intercept_redirect_; |
- mutable bool did_cancel_redirect_; |
- mutable bool did_intercept_final_; |
- mutable bool did_cancel_final_; |
-}; |
- |
-// Inherit PlatformTest since we require the autorelease pool on Mac OS X. |
-class URLRequestInterceptorTest : public URLRequestTest { |
- public: |
- URLRequestInterceptorTest() : URLRequestTest(), interceptor_(NULL) { |
- } |
- |
- ~URLRequestInterceptorTest() override { |
- // URLRequestJobs may post clean-up tasks on destruction. |
- base::RunLoop().RunUntilIdle(); |
- } |
- |
- void SetUpFactory() override { |
- interceptor_ = new MockURLRequestInterceptor(); |
- job_factory_.reset(new URLRequestInterceptingJobFactory( |
- job_factory_.Pass(), make_scoped_ptr(interceptor_))); |
- } |
- |
- MockURLRequestInterceptor* interceptor() const { |
- return interceptor_; |
- } |
- |
- private: |
- MockURLRequestInterceptor* interceptor_; |
-}; |
- |
-TEST_F(URLRequestInterceptorTest, Intercept) { |
- // Intercept the main request and respond with a simple response. |
- interceptor()->set_intercept_main_request(true); |
- interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_main_data(MockURLRequestInterceptor::ok_data()); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data(); |
- base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data(); |
- base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data(); |
- req->SetUserData(nullptr, user_data0); |
- req->SetUserData(&user_data1, user_data1); |
- req->SetUserData(&user_data2, user_data2); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Make sure we can retrieve our specific user data. |
- EXPECT_EQ(user_data0, req->GetUserData(nullptr)); |
- EXPECT_EQ(user_data1, req->GetUserData(&user_data1)); |
- EXPECT_EQ(user_data2, req->GetUserData(&user_data2)); |
- |
- // Check that we got one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRedirect) { |
- // Intercept the main request and respond with a redirect. |
- interceptor()->set_intercept_main_request(true); |
- interceptor()->set_main_headers( |
- MockURLRequestInterceptor::redirect_headers()); |
- interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data()); |
- |
- // Intercept that redirect and respond with a final OK response. |
- interceptor()->set_intercept_redirect(true); |
- interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_intercept_main()); |
- EXPECT_TRUE(interceptor()->did_intercept_redirect()); |
- |
- // Check that we got one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- if (req->status().is_success()) |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptServerError) { |
- // Intercept the main request to generate a server error response. |
- interceptor()->set_intercept_main_request(true); |
- interceptor()->set_main_headers(MockURLRequestInterceptor::error_headers()); |
- interceptor()->set_main_data(MockURLRequestInterceptor::error_data()); |
- |
- // Intercept that error and respond with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_intercept_main()); |
- EXPECT_TRUE(interceptor()->did_intercept_final()); |
- |
- // Check that we got one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptNetworkError) { |
- // Intercept the main request to simulate a network error. |
- interceptor()->set_simulate_main_network_error(true); |
- |
- // Intercept that error and respond with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_simulate_error_main()); |
- EXPECT_TRUE(interceptor()->did_intercept_final()); |
- |
- // Check that we received one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRestartRequired) { |
- // Restart the main request. |
- interceptor()->set_restart_main_request(true); |
- |
- // then intercept the new main request and respond with an OK response |
- interceptor()->set_intercept_main_request(true); |
- interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_main_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_restart_main()); |
- EXPECT_TRUE(interceptor()->did_intercept_main()); |
- |
- // Check that we received one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- if (req->status().is_success()) |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelMain) { |
- // Intercept the main request and cancel from within the restarted job. |
- interceptor()->set_cancel_main_request(true); |
- |
- // Set up to intercept the final response and override it with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_cancel_main()); |
- EXPECT_FALSE(interceptor()->did_intercept_final()); |
- |
- // Check that we see a canceled request. |
- EXPECT_FALSE(req->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelRedirect) { |
- // Intercept the main request and respond with a redirect. |
- interceptor()->set_intercept_main_request(true); |
- interceptor()->set_main_headers( |
- MockURLRequestInterceptor::redirect_headers()); |
- interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data()); |
- |
- // Intercept the redirect and cancel from within that job. |
- interceptor()->set_cancel_redirect_request(true); |
- |
- // Set up to intercept the final response and override it with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_intercept_main()); |
- EXPECT_TRUE(interceptor()->did_cancel_redirect()); |
- EXPECT_FALSE(interceptor()->did_intercept_final()); |
- |
- // Check that we see a canceled request. |
- EXPECT_FALSE(req->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelFinal) { |
- // Intercept the main request to simulate a network error. |
- interceptor()->set_simulate_main_network_error(true); |
- |
- // Set up to intercept final the response and cancel from within that job. |
- interceptor()->set_cancel_final_request(true); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_simulate_error_main()); |
- EXPECT_TRUE(interceptor()->did_cancel_final()); |
- |
- // Check that we see a canceled request. |
- EXPECT_FALSE(req->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
-} |
- |
-TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelInRestart) { |
- // Intercept the main request and cancel then restart from within that job. |
- interceptor()->set_cancel_then_restart_main_request(true); |
- |
- // Set up to intercept the final response and override it with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check that the interceptor got called as expected. |
- EXPECT_TRUE(interceptor()->did_cancel_then_restart_main()); |
- EXPECT_FALSE(interceptor()->did_intercept_final()); |
- |
- // Check that we see a canceled request. |
- EXPECT_FALSE(req->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
-} |
- |
-// "Normal" LoadTimingInfo as returned by a job. Everything is in order, not |
-// reused. |connect_time_flags| is used to indicate if there should be dns |
-// or SSL times, and |used_proxy| is used for proxy times. |
-LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now, |
- int connect_time_flags, |
- bool used_proxy) { |
- LoadTimingInfo load_timing; |
- load_timing.socket_log_id = 1; |
- |
- if (used_proxy) { |
- load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
- load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
- } |
- |
- LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing; |
- if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) { |
- connect_timing.dns_start = now + base::TimeDelta::FromDays(3); |
- connect_timing.dns_end = now + base::TimeDelta::FromDays(4); |
- } |
- connect_timing.connect_start = now + base::TimeDelta::FromDays(5); |
- if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) { |
- connect_timing.ssl_start = now + base::TimeDelta::FromDays(6); |
- connect_timing.ssl_end = now + base::TimeDelta::FromDays(7); |
- } |
- connect_timing.connect_end = now + base::TimeDelta::FromDays(8); |
- |
- load_timing.send_start = now + base::TimeDelta::FromDays(9); |
- load_timing.send_end = now + base::TimeDelta::FromDays(10); |
- load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
- return load_timing; |
-} |
- |
-// Same as above, but in the case of a reused socket. |
-LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now, |
- bool used_proxy) { |
- LoadTimingInfo load_timing; |
- load_timing.socket_log_id = 1; |
- load_timing.socket_reused = true; |
- |
- if (used_proxy) { |
- load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); |
- load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); |
- } |
- |
- load_timing.send_start = now + base::TimeDelta::FromDays(9); |
- load_timing.send_end = now + base::TimeDelta::FromDays(10); |
- load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); |
- return load_timing; |
-} |
- |
-LoadTimingInfo RunURLRequestInterceptorLoadTimingTest( |
- const LoadTimingInfo& job_load_timing, |
- const URLRequestContext& context, |
- MockURLRequestInterceptor* interceptor) { |
- interceptor->set_intercept_main_request(true); |
- interceptor->set_main_request_load_timing_info(job_load_timing); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- LoadTimingInfo resulting_load_timing; |
- req->GetLoadTimingInfo(&resulting_load_timing); |
- |
- // None of these should be modified by the URLRequest. |
- EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused); |
- EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id); |
- EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start); |
- EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end); |
- EXPECT_EQ(job_load_timing.receive_headers_end, |
- resulting_load_timing.receive_headers_end); |
- |
- return resulting_load_timing; |
-} |
- |
-// Basic test that the intercept + load timing tests work. |
-TEST_F(URLRequestInterceptorTest, InterceptLoadTiming) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = |
- NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Nothing should have been changed by the URLRequest. |
- EXPECT_EQ(job_load_timing.proxy_resolve_start, |
- load_timing_result.proxy_resolve_start); |
- EXPECT_EQ(job_load_timing.proxy_resolve_end, |
- load_timing_result.proxy_resolve_end); |
- EXPECT_EQ(job_load_timing.connect_timing.dns_start, |
- load_timing_result.connect_timing.dns_start); |
- EXPECT_EQ(job_load_timing.connect_timing.dns_end, |
- load_timing_result.connect_timing.dns_end); |
- EXPECT_EQ(job_load_timing.connect_timing.connect_start, |
- load_timing_result.connect_timing.connect_start); |
- EXPECT_EQ(job_load_timing.connect_timing.connect_end, |
- load_timing_result.connect_timing.connect_end); |
- EXPECT_EQ(job_load_timing.connect_timing.ssl_start, |
- load_timing_result.connect_timing.ssl_start); |
- EXPECT_EQ(job_load_timing.connect_timing.ssl_end, |
- load_timing_result.connect_timing.ssl_end); |
- |
- // Redundant sanity check. |
- TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_DNS_TIMES); |
-} |
- |
-// Another basic test, with proxy and SSL times, but no DNS times. |
-TEST_F(URLRequestInterceptorTest, InterceptLoadTimingProxy) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = |
- NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Nothing should have been changed by the URLRequest. |
- EXPECT_EQ(job_load_timing.proxy_resolve_start, |
- load_timing_result.proxy_resolve_start); |
- EXPECT_EQ(job_load_timing.proxy_resolve_end, |
- load_timing_result.proxy_resolve_end); |
- EXPECT_EQ(job_load_timing.connect_timing.dns_start, |
- load_timing_result.connect_timing.dns_start); |
- EXPECT_EQ(job_load_timing.connect_timing.dns_end, |
- load_timing_result.connect_timing.dns_end); |
- EXPECT_EQ(job_load_timing.connect_timing.connect_start, |
- load_timing_result.connect_timing.connect_start); |
- EXPECT_EQ(job_load_timing.connect_timing.connect_end, |
- load_timing_result.connect_timing.connect_end); |
- EXPECT_EQ(job_load_timing.connect_timing.ssl_start, |
- load_timing_result.connect_timing.ssl_start); |
- EXPECT_EQ(job_load_timing.connect_timing.ssl_end, |
- load_timing_result.connect_timing.ssl_end); |
- |
- // Redundant sanity check. |
- TestLoadTimingNotReusedWithProxy(load_timing_result, |
- CONNECT_TIMING_HAS_SSL_TIMES); |
-} |
- |
-// Make sure that URLRequest correctly adjusts proxy times when they're before |
-// |request_start|, due to already having a connected socket. This happens in |
-// the case of reusing a SPDY session. The connected socket is not considered |
-// reused in this test (May be a preconnect). |
-// |
-// To mix things up from the test above, assumes DNS times but no SSL times. |
-TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyProxyResolution) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = |
- NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true); |
- job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(6); |
- job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(5); |
- job_load_timing.connect_timing.dns_start = now - base::TimeDelta::FromDays(4); |
- job_load_timing.connect_timing.dns_end = now - base::TimeDelta::FromDays(3); |
- job_load_timing.connect_timing.connect_start = |
- now - base::TimeDelta::FromDays(2); |
- job_load_timing.connect_timing.connect_end = |
- now - base::TimeDelta::FromDays(1); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Proxy times, connect times, and DNS times should all be replaced with |
- // request_start. |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.proxy_resolve_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.proxy_resolve_end); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.dns_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.dns_end); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.connect_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.connect_end); |
- |
- // Other times should have been left null. |
- TestLoadTimingNotReusedWithProxy(load_timing_result, |
- CONNECT_TIMING_HAS_DNS_TIMES); |
-} |
- |
-// Same as above, but in the reused case. |
-TEST_F(URLRequestInterceptorTest, |
- InterceptLoadTimingEarlyProxyResolutionReused) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true); |
- job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4); |
- job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Proxy times and connect times should all be replaced with request_start. |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.proxy_resolve_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.proxy_resolve_end); |
- |
- // Other times should have been left null. |
- TestLoadTimingReusedWithProxy(load_timing_result); |
-} |
- |
-// Make sure that URLRequest correctly adjusts connect times when they're before |
-// |request_start|, due to reusing a connected socket. The connected socket is |
-// not considered reused in this test (May be a preconnect). |
-// |
-// To mix things up, the request has SSL times, but no DNS times. |
-TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnect) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = |
- NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false); |
- job_load_timing.connect_timing.connect_start = |
- now - base::TimeDelta::FromDays(1); |
- job_load_timing.connect_timing.ssl_start = now - base::TimeDelta::FromDays(2); |
- job_load_timing.connect_timing.ssl_end = now - base::TimeDelta::FromDays(3); |
- job_load_timing.connect_timing.connect_end = |
- now - base::TimeDelta::FromDays(4); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Connect times, and SSL times should be replaced with request_start. |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.connect_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.ssl_start); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.ssl_end); |
- EXPECT_EQ(load_timing_result.request_start, |
- load_timing_result.connect_timing.connect_end); |
- |
- // Other times should have been left null. |
- TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_SSL_TIMES); |
-} |
- |
-// Make sure that URLRequest correctly adjusts connect times when they're before |
-// |request_start|, due to reusing a connected socket in the case that there |
-// are also proxy times. The connected socket is not considered reused in this |
-// test (May be a preconnect). |
-// |
-// In this test, there are no SSL or DNS times. |
-TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnectWithProxy) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- LoadTimingInfo job_load_timing = |
- NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true); |
- job_load_timing.connect_timing.connect_start = |
- now - base::TimeDelta::FromDays(1); |
- job_load_timing.connect_timing.connect_end = |
- now - base::TimeDelta::FromDays(2); |
- |
- LoadTimingInfo load_timing_result = |
- RunURLRequestInterceptorLoadTimingTest( |
- job_load_timing, default_context(), interceptor()); |
- |
- // Connect times should be replaced with proxy_resolve_end. |
- EXPECT_EQ(load_timing_result.proxy_resolve_end, |
- load_timing_result.connect_timing.connect_start); |
- EXPECT_EQ(load_timing_result.proxy_resolve_end, |
- load_timing_result.connect_timing.connect_end); |
- |
- // Other times should have been left null. |
- TestLoadTimingNotReusedWithProxy(load_timing_result, |
- CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); |
-} |
- |
-// Check that two different URL requests have different identifiers. |
-TEST_F(URLRequestTest, Identifiers) { |
- TestDelegate d; |
- TestURLRequestContext context; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); |
- scoped_ptr<URLRequest> other_req(context.CreateRequest( |
- GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- ASSERT_NE(req->identifier(), other_req->identifier()); |
-} |
- |
-// Check that a failure to connect to the proxy is reported to the network |
-// delegate. |
-TEST_F(URLRequestTest, NetworkDelegateProxyError) { |
- MockHostResolver host_resolver; |
- host_resolver.rules()->AddSimulatedFailure("*"); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequests. |
- TestURLRequestContextWithProxy context("myproxy:70", &network_delegate); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); |
- req->set_method("GET"); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- // Check we see a failed request. |
- EXPECT_FALSE(req->status().is_success()); |
- // The proxy server is not set before failure. |
- EXPECT_TRUE(req->proxy_server().IsEmpty()); |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, req->status().error()); |
- |
- EXPECT_EQ(1, network_delegate.error_count()); |
- EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_error()); |
- EXPECT_EQ(1, network_delegate.completed_requests()); |
-} |
- |
-// Make sure that NetworkDelegate::NotifyCompleted is called if |
-// content is empty. |
-TEST_F(URLRequestTest, RequestCompletionForEmptyResponse) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("data:,"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ("", d.data_received()); |
- EXPECT_EQ(1, default_network_delegate_.completed_requests()); |
-} |
- |
-// Make sure that SetPriority actually sets the URLRequest's priority |
-// correctly, both before and after start. |
-TEST_F(URLRequestTest, SetPriorityBasic) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
- EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); |
- |
- req->SetPriority(LOW); |
- EXPECT_EQ(LOW, req->priority()); |
- |
- req->Start(); |
- EXPECT_EQ(LOW, req->priority()); |
- |
- req->SetPriority(MEDIUM); |
- EXPECT_EQ(MEDIUM, req->priority()); |
-} |
- |
-// Make sure that URLRequest calls SetPriority on a job before calling |
-// Start on it. |
-TEST_F(URLRequestTest, SetJobPriorityBeforeJobStart) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
- EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); |
- |
- scoped_refptr<URLRequestTestJob> job = |
- new URLRequestTestJob(req.get(), &default_network_delegate_); |
- AddTestInterceptor()->set_main_intercept_job(job.get()); |
- EXPECT_EQ(DEFAULT_PRIORITY, job->priority()); |
- |
- req->SetPriority(LOW); |
- |
- req->Start(); |
- EXPECT_EQ(LOW, job->priority()); |
-} |
- |
-// Make sure that URLRequest passes on its priority updates to its |
-// job. |
-TEST_F(URLRequestTest, SetJobPriority) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- scoped_refptr<URLRequestTestJob> job = |
- new URLRequestTestJob(req.get(), &default_network_delegate_); |
- AddTestInterceptor()->set_main_intercept_job(job.get()); |
- |
- req->SetPriority(LOW); |
- req->Start(); |
- EXPECT_EQ(LOW, job->priority()); |
- |
- req->SetPriority(MEDIUM); |
- EXPECT_EQ(MEDIUM, req->priority()); |
- EXPECT_EQ(MEDIUM, job->priority()); |
-} |
- |
-// Setting the IGNORE_LIMITS load flag should be okay if the priority |
-// is MAXIMUM_PRIORITY. |
-TEST_F(URLRequestTest, PriorityIgnoreLimits) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- GURL("http://test_intercept/foo"), MAXIMUM_PRIORITY, &d, NULL)); |
- EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); |
- |
- scoped_refptr<URLRequestTestJob> job = |
- new URLRequestTestJob(req.get(), &default_network_delegate_); |
- AddTestInterceptor()->set_main_intercept_job(job.get()); |
- |
- req->SetLoadFlags(LOAD_IGNORE_LIMITS); |
- EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); |
- |
- req->SetPriority(MAXIMUM_PRIORITY); |
- EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); |
- |
- req->Start(); |
- EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); |
- EXPECT_EQ(MAXIMUM_PRIORITY, job->priority()); |
-} |
- |
-// TODO(droger): Support SpawnedTestServer on iOS (see http://crbug.com/148666). |
-#if !defined(OS_IOS) |
-// A subclass of SpawnedTestServer that uses a statically-configured hostname. |
-// This is to work around mysterious failures in chrome_frame_net_tests. See: |
-// http://crbug.com/114369 |
-// TODO(erikwright): remove or update as needed; see http://crbug.com/334634. |
-class LocalHttpTestServer : public SpawnedTestServer { |
- public: |
- explicit LocalHttpTestServer(const base::FilePath& document_root) |
- : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP, |
- ScopedCustomUrlRequestTestHttpHost::value(), |
- document_root) {} |
- LocalHttpTestServer() |
- : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP, |
- ScopedCustomUrlRequestTestHttpHost::value(), |
- base::FilePath()) {} |
-}; |
- |
-TEST_F(URLRequestTest, DelayedCookieCallback) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- TestURLRequestContext context; |
- scoped_refptr<DelayedCookieMonster> delayed_cm = |
- new DelayedCookieMonster(); |
- scoped_refptr<CookieStore> cookie_store = delayed_cm; |
- context.set_cookie_store(delayed_cm.get()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- context.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- EXPECT_EQ(1, network_delegate.set_cookie_count()); |
- } |
- |
- // Verify that the cookie is set. |
- { |
- TestNetworkDelegate network_delegate; |
- context.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") |
- != std::string::npos); |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSendCookies) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie is set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") |
- != std::string::npos); |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") |
- == std::string::npos); |
- |
- // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies. |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSaveCookies) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- EXPECT_EQ(1, network_delegate.set_cookie_count()); |
- } |
- |
- // Try to set-up another cookie and update the previous cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES); |
- req->Start(); |
- |
- base::RunLoop().Run(); |
- |
- // LOAD_DO_NOT_SAVE_COOKIES does not trigger OnSetCookie. |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- EXPECT_EQ(0, network_delegate.set_cookie_count()); |
- } |
- |
- // Verify the cookies weren't saved or updated. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") |
- == std::string::npos); |
- EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") |
- != std::string::npos); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- EXPECT_EQ(0, network_delegate.set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie is set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") |
- != std::string::npos); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie isn't sent. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") |
- == std::string::npos); |
- |
- EXPECT_EQ(1, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Try to set-up another cookie and update the previous cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(2, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify the cookies weren't saved or updated. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") |
- == std::string::npos); |
- EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") |
- != std::string::npos); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSaveEmptyCookies) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up an empty cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- EXPECT_EQ(0, network_delegate.set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie is set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") |
- != std::string::npos); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify that the cookie isn't sent. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") |
- == std::string::npos); |
- |
- EXPECT_EQ(1, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up a cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, |
- &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Try to set-up another cookie and update the previous cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(2, network_delegate.blocked_set_cookie_count()); |
- } |
- |
- // Verify the cookies weren't saved or updated. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") |
- == std::string::npos); |
- EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") |
- != std::string::npos); |
- |
- EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); |
- EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); |
- } |
-} |
- |
-// FixedDateNetworkDelegate swaps out the server's HTTP Date response header |
-// value for the |fixed_date| argument given to the constructor. |
-class FixedDateNetworkDelegate : public TestNetworkDelegate { |
- public: |
- explicit FixedDateNetworkDelegate(const std::string& fixed_date) |
- : fixed_date_(fixed_date) {} |
- ~FixedDateNetworkDelegate() override {} |
- |
- // NetworkDelegate implementation |
- int OnHeadersReceived( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- const HttpResponseHeaders* original_response_headers, |
- scoped_refptr<HttpResponseHeaders>* override_response_headers, |
- GURL* allowed_unsafe_redirect_url) override; |
- |
- private: |
- std::string fixed_date_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FixedDateNetworkDelegate); |
-}; |
- |
-int FixedDateNetworkDelegate::OnHeadersReceived( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- const HttpResponseHeaders* original_response_headers, |
- scoped_refptr<HttpResponseHeaders>* override_response_headers, |
- GURL* allowed_unsafe_redirect_url) { |
- HttpResponseHeaders* new_response_headers = |
- new HttpResponseHeaders(original_response_headers->raw_headers()); |
- |
- new_response_headers->RemoveHeader("Date"); |
- new_response_headers->AddHeader("Date: " + fixed_date_); |
- |
- *override_response_headers = new_response_headers; |
- return TestNetworkDelegate::OnHeadersReceived(request, |
- callback, |
- original_response_headers, |
- override_response_headers, |
- allowed_unsafe_redirect_url); |
-} |
- |
-// Test that cookie expiration times are adjusted for server/client clock |
-// skew and that we handle incorrect timezone specifier "UTC" in HTTP Date |
-// headers by defaulting to GMT. (crbug.com/135131) |
-TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Set up an expired cookie. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL( |
- "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- } |
- // Verify that the cookie is not set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("StillGood=1") == std::string::npos); |
- } |
- // Set up a cookie with clock skew and "UTC" HTTP Date timezone specifier. |
- { |
- FixedDateNetworkDelegate network_delegate("18-Apr-1977 22:49:13 UTC"); |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL( |
- "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- } |
- // Verify that the cookie is set. |
- { |
- TestNetworkDelegate network_delegate; |
- default_context_.set_network_delegate(&network_delegate); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("StillGood=1") != std::string::npos); |
- } |
-} |
- |
- |
-// Check that it is impossible to change the referrer in the extra headers of |
-// an URLRequest. |
-TEST_F(URLRequestTest, DoNotOverrideReferrer) { |
- LocalHttpTestServer test_server; |
- ASSERT_TRUE(test_server.Start()); |
- |
- // If extra headers contain referer and the request contains a referer, |
- // only the latter shall be respected. |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetReferrer("http://foo.com/"); |
- |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/"); |
- req->SetExtraRequestHeaders(headers); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ("http://foo.com/", d.data_received()); |
- } |
- |
- // If extra headers contain a referer but the request does not, no referer |
- // shall be sent in the header. |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/"); |
- req->SetExtraRequestHeaders(headers); |
- req->SetLoadFlags(LOAD_VALIDATE_CACHE); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ("None", d.data_received()); |
- } |
-} |
- |
-class URLRequestTestHTTP : public URLRequestTest { |
- public: |
- URLRequestTestHTTP() |
- : test_server_(base::FilePath(FILE_PATH_LITERAL( |
- "net/data/url_request_unittest"))) { |
- } |
- |
- protected: |
- // Requests |redirect_url|, which must return a HTTP 3xx redirect. |
- // |request_method| is the method to use for the initial request. |
- // |redirect_method| is the method that is expected to be used for the second |
- // request, after redirection. |
- // If |include_data| is true, data is uploaded with the request. The |
- // response body is expected to match it exactly, if and only if |
- // |request_method| == |redirect_method|. |
- void HTTPRedirectMethodTest(const GURL& redirect_url, |
- const std::string& request_method, |
- const std::string& redirect_method, |
- bool include_data) { |
- static const char kData[] = "hello world"; |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- redirect_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->set_method(request_method); |
- if (include_data) { |
- req->set_upload(CreateSimpleUploadData(kData)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kContentLength, |
- base::UintToString(arraysize(kData) - 1)); |
- req->SetExtraRequestHeaders(headers); |
- } |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(redirect_method, req->method()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- EXPECT_EQ(OK, req->status().error()); |
- if (include_data) { |
- if (request_method == redirect_method) { |
- EXPECT_EQ(kData, d.data_received()); |
- } else { |
- EXPECT_NE(kData, d.data_received()); |
- } |
- } |
- if (HasFailure()) |
- LOG(WARNING) << "Request method was: " << request_method; |
- } |
- |
- void HTTPUploadDataOperationTest(const std::string& method) { |
- const int kMsgSize = 20000; // multiple of 10 |
- const int kIterations = 50; |
- char* uploadBytes = new char[kMsgSize+1]; |
- char* ptr = uploadBytes; |
- char marker = 'a'; |
- for (int idx = 0; idx < kMsgSize/10; idx++) { |
- memcpy(ptr, "----------", 10); |
- ptr += 10; |
- if (idx % 100 == 0) { |
- ptr--; |
- *ptr++ = marker; |
- if (++marker > 'z') |
- marker = 'a'; |
- } |
- } |
- uploadBytes[kMsgSize] = '\0'; |
- |
- for (int i = 0; i < kIterations; ++i) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->set_method(method.c_str()); |
- |
- r->set_upload(CreateSimpleUploadData(uploadBytes)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- ASSERT_EQ(1, d.response_started_count()) |
- << "request failed: " << r->status().status() |
- << ", os error: " << r->status().error(); |
- |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(uploadBytes, d.data_received()); |
- } |
- delete[] uploadBytes; |
- } |
- |
- void AddChunksToUpload(URLRequest* r) { |
- r->AppendChunkToUpload("a", 1, false); |
- r->AppendChunkToUpload("bcd", 3, false); |
- r->AppendChunkToUpload("this is a longer chunk than before.", 35, false); |
- r->AppendChunkToUpload("\r\n\r\n", 4, false); |
- r->AppendChunkToUpload("0", 1, false); |
- r->AppendChunkToUpload("2323", 4, true); |
- } |
- |
- void VerifyReceivedDataMatchesChunks(URLRequest* r, TestDelegate* d) { |
- // This should match the chunks sent by AddChunksToUpload(). |
- const std::string expected_data = |
- "abcdthis is a longer chunk than before.\r\n\r\n02323"; |
- |
- ASSERT_EQ(1, d->response_started_count()) |
- << "request failed: " << r->status().status() |
- << ", os error: " << r->status().error(); |
- |
- EXPECT_FALSE(d->received_data_before_response()); |
- |
- EXPECT_EQ(expected_data.size(), static_cast<size_t>(d->bytes_received())); |
- EXPECT_EQ(expected_data, d->data_received()); |
- } |
- |
- bool DoManyCookiesRequest(int num_cookies) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("set-many-cookies?" + |
- base::IntToString(num_cookies)), |
- DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- bool is_success = r->status().is_success(); |
- |
- if (!is_success) { |
- EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG); |
- // The test server appears to be unable to handle subsequent requests |
- // after this error is triggered. Force it to restart. |
- EXPECT_TRUE(test_server_.Stop()); |
- EXPECT_TRUE(test_server_.Start()); |
- } |
- |
- return is_success; |
- } |
- |
- LocalHttpTestServer* test_server() { |
- return &test_server_; |
- } |
- |
- protected: |
- LocalHttpTestServer test_server_; |
-}; |
- |
-// In this unit test, we're using the HTTPTestServer as a proxy server and |
-// issuing a CONNECT request with the magic host name "www.redirect.com". |
-// The HTTPTestServer will return a 302 response, which we should not |
-// follow. |
-TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- // The proxy server is not set before failure. |
- EXPECT_TRUE(r->proxy_server().IsEmpty()); |
- EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); |
- EXPECT_EQ(1, d.response_started_count()); |
- // We should not have followed the redirect. |
- EXPECT_EQ(0, d.received_redirect_count()); |
- } |
-} |
- |
-// This is the same as the previous test, but checks that the network delegate |
-// registers the error. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- // The proxy server is not set before failure. |
- EXPECT_TRUE(r->proxy_server().IsEmpty()); |
- EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); |
- EXPECT_EQ(1, d.response_started_count()); |
- // We should not have followed the redirect. |
- EXPECT_EQ(0, d.received_redirect_count()); |
- |
- EXPECT_EQ(1, network_delegate.error_count()); |
- EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, network_delegate.last_error()); |
- } |
-} |
- |
-// Tests that we can block and asynchronously return OK in various stages. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) { |
- static const BlockingNetworkDelegate::Stage blocking_stages[] = { |
- BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, |
- BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, |
- BlockingNetworkDelegate::ON_HEADERS_RECEIVED |
- }; |
- static const size_t blocking_stages_length = arraysize(blocking_stages); |
- |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::USER_CALLBACK); |
- network_delegate.set_block_on( |
- BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST | |
- BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS | |
- BlockingNetworkDelegate::ON_HEADERS_RECEIVED); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- for (size_t i = 0; i < blocking_stages_length; ++i) { |
- base::RunLoop().Run(); |
- EXPECT_EQ(blocking_stages[i], |
- network_delegate.stage_blocked_for_callback()); |
- network_delegate.DoCallback(OK); |
- } |
- base::RunLoop().Run(); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can block and cancel a request. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); |
- network_delegate.set_retval(ERR_EMPTY_RESPONSE); |
- |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- // The proxy server is not set before cancellation. |
- EXPECT_TRUE(r->proxy_server().IsEmpty()); |
- EXPECT_EQ(ERR_EMPTY_RESPONSE, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Helper function for NetworkDelegateCancelRequestAsynchronously and |
-// NetworkDelegateCancelRequestSynchronously. Sets up a blocking network |
-// delegate operating in |block_mode| and a request for |url|. It blocks the |
-// request in |stage| and cancels it with ERR_BLOCKED_BY_CLIENT. |
-void NetworkDelegateCancelRequest(BlockingNetworkDelegate::BlockMode block_mode, |
- BlockingNetworkDelegate::Stage stage, |
- const GURL& url) { |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate(block_mode); |
- network_delegate.set_retval(ERR_BLOCKED_BY_CLIENT); |
- network_delegate.set_block_on(stage); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- // The proxy server is not set before cancellation. |
- EXPECT_TRUE(r->proxy_server().IsEmpty()); |
- EXPECT_EQ(ERR_BLOCKED_BY_CLIENT, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// The following 3 tests check that the network delegate can cancel a request |
-// synchronously in various stages of the request. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously1) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, |
- BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, |
- test_server_.GetURL(std::string())); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously2) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, |
- BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, |
- test_server_.GetURL(std::string())); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously3) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, |
- BlockingNetworkDelegate::ON_HEADERS_RECEIVED, |
- test_server_.GetURL(std::string())); |
-} |
- |
-// The following 3 tests check that the network delegate can cancel a request |
-// asynchronously in various stages of the request. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously1) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, |
- BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, |
- test_server_.GetURL(std::string())); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously2) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, |
- BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, |
- test_server_.GetURL(std::string())); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously3) { |
- ASSERT_TRUE(test_server_.Start()); |
- NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, |
- BlockingNetworkDelegate::ON_HEADERS_RECEIVED, |
- test_server_.GetURL(std::string())); |
-} |
- |
-// Tests that the network delegate can block and redirect a request to a new |
-// URL. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); |
- GURL redirect_url(test_server_.GetURL("simple.html")); |
- network_delegate.set_redirect_url(redirect_url); |
- |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- { |
- GURL original_url(test_server_.GetURL("empty.html")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- // Quit after hitting the redirect, so can check the headers. |
- d.set_quit_on_redirect(true); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- // Check headers from URLRequestJob. |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(307, r->GetResponseCode()); |
- EXPECT_EQ(307, r->response_headers()->response_code()); |
- std::string location; |
- ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", |
- &location)); |
- EXPECT_EQ(redirect_url, GURL(location)); |
- |
- // Let the request finish. |
- r->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); |
- EXPECT_EQ( |
- 1, network_delegate.observed_before_proxy_headers_sent_callbacks()); |
- EXPECT_TRUE( |
- network_delegate.last_observed_proxy().Equals( |
- test_server_.host_port_pair())); |
- |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(redirect_url, r->url()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can block and redirect a request to a new |
-// URL by setting a redirect_url and returning in OnBeforeURLRequest directly. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- GURL redirect_url(test_server_.GetURL("simple.html")); |
- network_delegate.set_redirect_url(redirect_url); |
- |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- { |
- GURL original_url(test_server_.GetURL("empty.html")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- // Quit after hitting the redirect, so can check the headers. |
- d.set_quit_on_redirect(true); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- // Check headers from URLRequestJob. |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(307, r->GetResponseCode()); |
- EXPECT_EQ(307, r->response_headers()->response_code()); |
- std::string location; |
- ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", |
- &location)); |
- EXPECT_EQ(redirect_url, GURL(location)); |
- |
- // Let the request finish. |
- r->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); |
- EXPECT_EQ( |
- 1, network_delegate.observed_before_proxy_headers_sent_callbacks()); |
- EXPECT_TRUE( |
- network_delegate.last_observed_proxy().Equals( |
- test_server_.host_port_pair())); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(redirect_url, r->url()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that redirects caused by the network delegate preserve POST data. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const char kData[] = "hello world"; |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); |
- GURL redirect_url(test_server_.GetURL("echo")); |
- network_delegate.set_redirect_url(redirect_url); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL original_url(test_server_.GetURL("empty.html")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- r->set_method("POST"); |
- r->set_upload(CreateSimpleUploadData(kData)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kContentLength, |
- base::UintToString(arraysize(kData) - 1)); |
- r->SetExtraRequestHeaders(headers); |
- |
- // Quit after hitting the redirect, so can check the headers. |
- d.set_quit_on_redirect(true); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- // Check headers from URLRequestJob. |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(307, r->GetResponseCode()); |
- EXPECT_EQ(307, r->response_headers()->response_code()); |
- std::string location; |
- ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", |
- &location)); |
- EXPECT_EQ(redirect_url, GURL(location)); |
- |
- // Let the request finish. |
- r->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(redirect_url, r->url()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- EXPECT_EQ("POST", r->method()); |
- EXPECT_EQ(kData, d.data_received()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can block and redirect a request to a new |
-// URL during OnHeadersReceived. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); |
- GURL redirect_url(test_server_.GetURL("simple.html")); |
- network_delegate.set_redirect_on_headers_received_url(redirect_url); |
- |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- { |
- GURL original_url(test_server_.GetURL("empty.html")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); |
- EXPECT_EQ( |
- 2, network_delegate.observed_before_proxy_headers_sent_callbacks()); |
- EXPECT_TRUE( |
- network_delegate.last_observed_proxy().Equals( |
- test_server_.host_port_pair())); |
- |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(redirect_url, r->url()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(2, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can synchronously complete OnAuthRequired |
-// by taking no action. This indicates that the NetworkDelegate does not want to |
-// handle the challenge, and is passing the buck along to the |
-// URLRequest::Delegate. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_TRUE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, |
- NetworkDelegateOnAuthRequiredSyncNoAction_GetFullRequestHeaders) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- { |
- HttpRequestHeaders headers; |
- EXPECT_TRUE(r->GetFullRequestHeaders(&headers)); |
- EXPECT_FALSE(headers.HasHeader("Authorization")); |
- } |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_TRUE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can synchronously complete OnAuthRequired |
-// by setting credentials. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- network_delegate.set_auth_retval( |
- NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); |
- |
- network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret)); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_FALSE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Same as above, but also tests that GetFullRequestHeaders returns the proper |
-// headers (for the first or second request) when called at the proper times. |
-TEST_F(URLRequestTestHTTP, |
- NetworkDelegateOnAuthRequiredSyncSetAuth_GetFullRequestHeaders) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- network_delegate.set_auth_retval( |
- NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); |
- |
- network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret)); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_FALSE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- |
- { |
- HttpRequestHeaders headers; |
- EXPECT_TRUE(r->GetFullRequestHeaders(&headers)); |
- EXPECT_TRUE(headers.HasHeader("Authorization")); |
- } |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can synchronously complete OnAuthRequired |
-// by cancelling authentication. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::SYNCHRONOUS); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- network_delegate.set_auth_retval( |
- NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(401, r->GetResponseCode()); |
- EXPECT_FALSE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can asynchronously complete OnAuthRequired |
-// by taking no action. This indicates that the NetworkDelegate does not want |
-// to handle the challenge, and is passing the buck along to the |
-// URLRequest::Delegate. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_TRUE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can asynchronously complete OnAuthRequired |
-// by setting credentials. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- network_delegate.set_auth_retval( |
- NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); |
- |
- AuthCredentials auth_credentials(kUser, kSecret); |
- network_delegate.set_auth_credentials(auth_credentials); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(0, r->status().error()); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_FALSE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that the network delegate can asynchronously complete OnAuthRequired |
-// by cancelling authentication. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::AUTO_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- network_delegate.set_auth_retval( |
- NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- GURL url(test_server_.GetURL("auth-basic")); |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(401, r->GetResponseCode()); |
- EXPECT_FALSE(d.auth_required_called()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that we can handle when a network request was canceled while we were |
-// waiting for the network delegate. |
-// Part 1: Request is cancelled while waiting for OnBeforeURLRequest callback. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::USER_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, |
- network_delegate.stage_blocked_for_callback()); |
- EXPECT_EQ(0, network_delegate.completed_requests()); |
- // Cancel before callback. |
- r->Cancel(); |
- // Ensure that network delegate is notified. |
- EXPECT_EQ(1, network_delegate.completed_requests()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- EXPECT_EQ(ERR_ABORTED, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that we can handle when a network request was canceled while we were |
-// waiting for the network delegate. |
-// Part 2: Request is cancelled while waiting for OnBeforeSendHeaders callback. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::USER_CALLBACK); |
- network_delegate.set_block_on( |
- BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, |
- network_delegate.stage_blocked_for_callback()); |
- EXPECT_EQ(0, network_delegate.completed_requests()); |
- // Cancel before callback. |
- r->Cancel(); |
- // Ensure that network delegate is notified. |
- EXPECT_EQ(1, network_delegate.completed_requests()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- EXPECT_EQ(ERR_ABORTED, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that we can handle when a network request was canceled while we were |
-// waiting for the network delegate. |
-// Part 3: Request is cancelled while waiting for OnHeadersReceived callback. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::USER_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(BlockingNetworkDelegate::ON_HEADERS_RECEIVED, |
- network_delegate.stage_blocked_for_callback()); |
- EXPECT_EQ(0, network_delegate.completed_requests()); |
- // Cancel before callback. |
- r->Cancel(); |
- // Ensure that network delegate is notified. |
- EXPECT_EQ(1, network_delegate.completed_requests()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- EXPECT_EQ(ERR_ABORTED, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// Tests that we can handle when a network request was canceled while we were |
-// waiting for the network delegate. |
-// Part 4: Request is cancelled while waiting for OnAuthRequired callback. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- BlockingNetworkDelegate network_delegate( |
- BlockingNetworkDelegate::USER_CALLBACK); |
- network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); |
- |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(BlockingNetworkDelegate::ON_AUTH_REQUIRED, |
- network_delegate.stage_blocked_for_callback()); |
- EXPECT_EQ(0, network_delegate.completed_requests()); |
- // Cancel before callback. |
- r->Cancel(); |
- // Ensure that network delegate is notified. |
- EXPECT_EQ(1, network_delegate.completed_requests()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- EXPECT_EQ(ERR_ABORTED, r->status().error()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
-} |
- |
-// In this unit test, we're using the HTTPTestServer as a proxy server and |
-// issuing a CONNECT request with the magic host name "www.server-auth.com". |
-// The HTTPTestServer will return a 401 response, which we should balk at. |
-TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContextWithProxy context( |
- test_server_.host_port_pair().ToString(), &network_delegate); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- GURL("https://www.server-auth.com/"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- // The proxy server is not set before failure. |
- EXPECT_TRUE(r->proxy_server().IsEmpty()); |
- EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, GetTest_NoCache) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- |
- // TODO(eroman): Add back the NetLog tests... |
- } |
-} |
- |
-// This test has the server send a large number of cookies to the client. |
-// To ensure that no number of cookies causes a crash, a galloping binary |
-// search is used to estimate that maximum number of cookies that are accepted |
-// by the browser. Beyond the maximum number, the request will fail with |
-// ERR_RESPONSE_HEADERS_TOO_BIG. |
-#if defined(OS_WIN) |
-// http://crbug.com/177916 |
-#define MAYBE_GetTest_ManyCookies DISABLED_GetTest_ManyCookies |
-#else |
-#define MAYBE_GetTest_ManyCookies GetTest_ManyCookies |
-#endif // defined(OS_WIN) |
-TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- int lower_bound = 0; |
- int upper_bound = 1; |
- |
- // Double the number of cookies until the response header limits are |
- // exceeded. |
- while (DoManyCookiesRequest(upper_bound)) { |
- lower_bound = upper_bound; |
- upper_bound *= 2; |
- ASSERT_LT(upper_bound, 1000000); |
- } |
- |
- int tolerance = static_cast<int>(upper_bound * 0.005); |
- if (tolerance < 2) |
- tolerance = 2; |
- |
- // Perform a binary search to find the highest possible number of cookies, |
- // within the desired tolerance. |
- while (upper_bound - lower_bound >= tolerance) { |
- int num_cookies = (lower_bound + upper_bound) / 2; |
- |
- if (DoManyCookiesRequest(num_cookies)) |
- lower_bound = num_cookies; |
- else |
- upper_bound = num_cookies; |
- } |
- // Success: the test did not crash. |
-} |
- |
-TEST_F(URLRequestTestHTTP, GetTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- GURL test_url(test_server_.GetURL(std::string())); |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- HttpRequestHeaders headers; |
- EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- |
- EXPECT_TRUE(d.have_full_request_headers()); |
- CheckFullRequestHeaders(d.full_request_headers(), test_url); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, GetTestLoadTiming) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- LoadTimingInfo load_timing_info; |
- r->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, GetZippedTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- // Parameter that specifies the Content-Length field in the response: |
- // C - Compressed length. |
- // U - Uncompressed length. |
- // L - Large length (larger than both C & U). |
- // M - Medium length (between C & U). |
- // S - Small length (smaller than both C & U). |
- const char test_parameters[] = "CULMS"; |
- const int num_tests = arraysize(test_parameters)- 1; // Skip NULL. |
- // C & U should be OK. |
- // L & M are larger than the data sent, and show an error. |
- // S has too little data, but we seem to accept it. |
- const bool test_expect_success[num_tests] = |
- { true, true, false, false, true }; |
- |
- for (int i = 0; i < num_tests ; i++) { |
- TestDelegate d; |
- { |
- std::string test_file = |
- base::StringPrintf("compressedfiles/BullRunSpeech.txt?%c", |
- test_parameters[i]); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL(test_file), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- VLOG(1) << " Received " << d.bytes_received() << " bytes" |
- << " status = " << r->status().status() |
- << " error = " << r->status().error(); |
- if (test_expect_success[i]) { |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()) |
- << " Parameter = \"" << test_file << "\""; |
- } else { |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, r->status().error()) |
- << " Parameter = \"" << test_file << "\""; |
- } |
- } |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, RedirectLoadTiming) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL destination_url = test_server_.GetURL(std::string()); |
- GURL original_url = |
- test_server_.GetURL("server-redirect?" + destination_url.spec()); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(destination_url, req->url()); |
- EXPECT_EQ(original_url, req->original_url()); |
- ASSERT_EQ(2U, req->url_chain().size()); |
- EXPECT_EQ(original_url, req->url_chain()[0]); |
- EXPECT_EQ(destination_url, req->url_chain()[1]); |
- |
- LoadTimingInfo load_timing_info_before_redirect; |
- EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeRedirect( |
- &load_timing_info_before_redirect)); |
- TestLoadTimingNotReused(load_timing_info_before_redirect, |
- CONNECT_TIMING_HAS_DNS_TIMES); |
- |
- LoadTimingInfo load_timing_info; |
- req->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- |
- // Check that a new socket was used on redirect, since the server does not |
- // supposed keep-alive sockets, and that the times before the redirect are |
- // before the ones recorded for the second request. |
- EXPECT_NE(load_timing_info_before_redirect.socket_log_id, |
- load_timing_info.socket_log_id); |
- EXPECT_LE(load_timing_info_before_redirect.receive_headers_end, |
- load_timing_info.connect_timing.connect_start); |
-} |
- |
-TEST_F(URLRequestTestHTTP, MultipleRedirectTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL destination_url = test_server_.GetURL(std::string()); |
- GURL middle_redirect_url = |
- test_server_.GetURL("server-redirect?" + destination_url.spec()); |
- GURL original_url = test_server_.GetURL( |
- "server-redirect?" + middle_redirect_url.spec()); |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(2, d.received_redirect_count()); |
- EXPECT_EQ(destination_url, req->url()); |
- EXPECT_EQ(original_url, req->original_url()); |
- ASSERT_EQ(3U, req->url_chain().size()); |
- EXPECT_EQ(original_url, req->url_chain()[0]); |
- EXPECT_EQ(middle_redirect_url, req->url_chain()[1]); |
- EXPECT_EQ(destination_url, req->url_chain()[2]); |
-} |
- |
-// First and second pieces of information logged by delegates to URLRequests. |
-const char kFirstDelegateInfo[] = "Wonderful delegate"; |
-const char kSecondDelegateInfo[] = "Exciting delegate"; |
- |
-// Logs delegate information to a URLRequest. The first string is logged |
-// synchronously on Start(), using DELEGATE_INFO_DEBUG_ONLY. The second is |
-// logged asynchronously, using DELEGATE_INFO_DISPLAY_TO_USER. Then |
-// another asynchronous call is used to clear the delegate information |
-// before calling a callback. The object then deletes itself. |
-class AsyncDelegateLogger : public base::RefCounted<AsyncDelegateLogger> { |
- public: |
- typedef base::Callback<void()> Callback; |
- |
- // Each time delegate information is added to the URLRequest, the resulting |
- // load state is checked. The expected load state after each request is |
- // passed in as an argument. |
- static void Run(URLRequest* url_request, |
- LoadState expected_first_load_state, |
- LoadState expected_second_load_state, |
- LoadState expected_third_load_state, |
- const Callback& callback) { |
- AsyncDelegateLogger* logger = new AsyncDelegateLogger( |
- url_request, |
- expected_first_load_state, |
- expected_second_load_state, |
- expected_third_load_state, |
- callback); |
- logger->Start(); |
- } |
- |
- // Checks that the log entries, starting with log_position, contain the |
- // DELEGATE_INFO NetLog events that an AsyncDelegateLogger should have |
- // recorded. Returns the index of entry after the expected number of |
- // events this logged, or entries.size() if there aren't enough entries. |
- static size_t CheckDelegateInfo( |
- const CapturingNetLog::CapturedEntryList& entries, size_t log_position) { |
- // There should be 4 DELEGATE_INFO events: Two begins and two ends. |
- if (log_position + 3 >= entries.size()) { |
- ADD_FAILURE() << "Not enough log entries"; |
- return entries.size(); |
- } |
- std::string delegate_info; |
- EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase); |
- EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info", |
- &delegate_info)); |
- EXPECT_EQ(kFirstDelegateInfo, delegate_info); |
- |
- ++log_position; |
- EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- ++log_position; |
- EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase); |
- EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info", |
- &delegate_info)); |
- EXPECT_EQ(kSecondDelegateInfo, delegate_info); |
- |
- ++log_position; |
- EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- return log_position + 1; |
- } |
- |
- // Find delegate request begin and end messages for OnBeforeNetworkStart. |
- // Returns the position of the end message. |
- static size_t ExpectBeforeNetworkEvents( |
- const CapturingNetLog::CapturedEntryList& entries, |
- size_t log_position) { |
- log_position = |
- ExpectLogContainsSomewhereAfter(entries, |
- log_position, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, |
- entries[log_position + 1].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position + 1].phase); |
- return log_position + 1; |
- } |
- |
- private: |
- friend class base::RefCounted<AsyncDelegateLogger>; |
- |
- AsyncDelegateLogger(URLRequest* url_request, |
- LoadState expected_first_load_state, |
- LoadState expected_second_load_state, |
- LoadState expected_third_load_state, |
- const Callback& callback) |
- : url_request_(url_request), |
- expected_first_load_state_(expected_first_load_state), |
- expected_second_load_state_(expected_second_load_state), |
- expected_third_load_state_(expected_third_load_state), |
- callback_(callback) { |
- } |
- |
- ~AsyncDelegateLogger() {} |
- |
- void Start() { |
- url_request_->LogBlockedBy(kFirstDelegateInfo); |
- LoadStateWithParam load_state = url_request_->GetLoadState(); |
- EXPECT_EQ(expected_first_load_state_, load_state.state); |
- EXPECT_NE(ASCIIToUTF16(kFirstDelegateInfo), load_state.param); |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&AsyncDelegateLogger::LogSecondDelegate, this)); |
- } |
- |
- void LogSecondDelegate() { |
- url_request_->LogAndReportBlockedBy(kSecondDelegateInfo); |
- LoadStateWithParam load_state = url_request_->GetLoadState(); |
- EXPECT_EQ(expected_second_load_state_, load_state.state); |
- if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) { |
- EXPECT_EQ(ASCIIToUTF16(kSecondDelegateInfo), load_state.param); |
- } else { |
- EXPECT_NE(ASCIIToUTF16(kSecondDelegateInfo), load_state.param); |
- } |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&AsyncDelegateLogger::LogComplete, this)); |
- } |
- |
- void LogComplete() { |
- url_request_->LogUnblocked(); |
- LoadStateWithParam load_state = url_request_->GetLoadState(); |
- EXPECT_EQ(expected_third_load_state_, load_state.state); |
- if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) |
- EXPECT_EQ(base::string16(), load_state.param); |
- callback_.Run(); |
- } |
- |
- URLRequest* url_request_; |
- const int expected_first_load_state_; |
- const int expected_second_load_state_; |
- const int expected_third_load_state_; |
- const Callback callback_; |
- |
- DISALLOW_COPY_AND_ASSIGN(AsyncDelegateLogger); |
-}; |
- |
-// NetworkDelegate that logs delegate information before a request is started, |
-// before headers are sent, when headers are read, and when auth information |
-// is requested. Uses AsyncDelegateLogger. |
-class AsyncLoggingNetworkDelegate : public TestNetworkDelegate { |
- public: |
- AsyncLoggingNetworkDelegate() {} |
- ~AsyncLoggingNetworkDelegate() override {} |
- |
- // NetworkDelegate implementation. |
- int OnBeforeURLRequest(URLRequest* request, |
- const CompletionCallback& callback, |
- GURL* new_url) override { |
- TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); |
- return RunCallbackAsynchronously(request, callback); |
- } |
- |
- int OnBeforeSendHeaders(URLRequest* request, |
- const CompletionCallback& callback, |
- HttpRequestHeaders* headers) override { |
- TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers); |
- return RunCallbackAsynchronously(request, callback); |
- } |
- |
- int OnHeadersReceived( |
- URLRequest* request, |
- const CompletionCallback& callback, |
- const HttpResponseHeaders* original_response_headers, |
- scoped_refptr<HttpResponseHeaders>* override_response_headers, |
- GURL* allowed_unsafe_redirect_url) override { |
- TestNetworkDelegate::OnHeadersReceived(request, |
- callback, |
- original_response_headers, |
- override_response_headers, |
- allowed_unsafe_redirect_url); |
- return RunCallbackAsynchronously(request, callback); |
- } |
- |
- NetworkDelegate::AuthRequiredResponse OnAuthRequired( |
- URLRequest* request, |
- const AuthChallengeInfo& auth_info, |
- const AuthCallback& callback, |
- AuthCredentials* credentials) override { |
- AsyncDelegateLogger::Run( |
- request, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- base::Bind(&AsyncLoggingNetworkDelegate::SetAuthAndResume, |
- callback, credentials)); |
- return AUTH_REQUIRED_RESPONSE_IO_PENDING; |
- } |
- |
- private: |
- static int RunCallbackAsynchronously( |
- URLRequest* request, |
- const CompletionCallback& callback) { |
- AsyncDelegateLogger::Run( |
- request, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- base::Bind(callback, OK)); |
- return ERR_IO_PENDING; |
- } |
- |
- static void SetAuthAndResume(const AuthCallback& callback, |
- AuthCredentials* credentials) { |
- *credentials = AuthCredentials(kUser, kSecret); |
- callback.Run(NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); |
- } |
- |
- DISALLOW_COPY_AND_ASSIGN(AsyncLoggingNetworkDelegate); |
-}; |
- |
-// URLRequest::Delegate that logs delegate information when the headers |
-// are received, when each read completes, and during redirects. Uses |
-// AsyncDelegateLogger. Can optionally cancel a request in any phase. |
-// |
-// Inherits from TestDelegate to reuse the TestDelegate code to handle |
-// advancing to the next step in most cases, as well as cancellation. |
-class AsyncLoggingUrlRequestDelegate : public TestDelegate { |
- public: |
- enum CancelStage { |
- NO_CANCEL = 0, |
- CANCEL_ON_RECEIVED_REDIRECT, |
- CANCEL_ON_RESPONSE_STARTED, |
- CANCEL_ON_READ_COMPLETED |
- }; |
- |
- explicit AsyncLoggingUrlRequestDelegate(CancelStage cancel_stage) |
- : cancel_stage_(cancel_stage) { |
- if (cancel_stage == CANCEL_ON_RECEIVED_REDIRECT) |
- set_cancel_in_received_redirect(true); |
- else if (cancel_stage == CANCEL_ON_RESPONSE_STARTED) |
- set_cancel_in_response_started(true); |
- else if (cancel_stage == CANCEL_ON_READ_COMPLETED) |
- set_cancel_in_received_data(true); |
- } |
- ~AsyncLoggingUrlRequestDelegate() override {} |
- |
- // URLRequest::Delegate implementation: |
- void OnReceivedRedirect(URLRequest* request, |
- const RedirectInfo& redirect_info, |
- bool* defer_redirect) override { |
- *defer_redirect = true; |
- AsyncDelegateLogger::Run( |
- request, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- base::Bind( |
- &AsyncLoggingUrlRequestDelegate::OnReceivedRedirectLoggingComplete, |
- base::Unretained(this), request, redirect_info)); |
- } |
- |
- void OnResponseStarted(URLRequest* request) override { |
- AsyncDelegateLogger::Run( |
- request, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- base::Bind( |
- &AsyncLoggingUrlRequestDelegate::OnResponseStartedLoggingComplete, |
- base::Unretained(this), request)); |
- } |
- |
- void OnReadCompleted(URLRequest* request, int bytes_read) override { |
- AsyncDelegateLogger::Run( |
- request, |
- LOAD_STATE_IDLE, |
- LOAD_STATE_IDLE, |
- LOAD_STATE_IDLE, |
- base::Bind( |
- &AsyncLoggingUrlRequestDelegate::AfterReadCompletedLoggingComplete, |
- base::Unretained(this), request, bytes_read)); |
- } |
- |
- private: |
- void OnReceivedRedirectLoggingComplete(URLRequest* request, |
- const RedirectInfo& redirect_info) { |
- bool defer_redirect = false; |
- TestDelegate::OnReceivedRedirect(request, redirect_info, &defer_redirect); |
- // FollowDeferredRedirect should not be called after cancellation. |
- if (cancel_stage_ == CANCEL_ON_RECEIVED_REDIRECT) |
- return; |
- if (!defer_redirect) |
- request->FollowDeferredRedirect(); |
- } |
- |
- void OnResponseStartedLoggingComplete(URLRequest* request) { |
- // The parent class continues the request. |
- TestDelegate::OnResponseStarted(request); |
- } |
- |
- void AfterReadCompletedLoggingComplete(URLRequest* request, int bytes_read) { |
- // The parent class continues the request. |
- TestDelegate::OnReadCompleted(request, bytes_read); |
- } |
- |
- const CancelStage cancel_stage_; |
- |
- DISALLOW_COPY_AND_ASSIGN(AsyncLoggingUrlRequestDelegate); |
-}; |
- |
-// Tests handling of delegate info before a request starts. |
-TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate request_delegate; |
- TestURLRequestContext context(true); |
- context.set_network_delegate(NULL); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &request_delegate, |
- NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); |
- EXPECT_EQ(base::string16(), load_state.param); |
- |
- AsyncDelegateLogger::Run( |
- r.get(), |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_WAITING_FOR_DELEGATE, |
- LOAD_STATE_IDLE, |
- base::Bind(&URLRequest::Start, base::Unretained(r.get()))); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- } |
- |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- size_t log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- 0, |
- NetLog::TYPE_DELEGATE_INFO, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, log_position); |
- |
- // Nothing else should add any delegate info to the request. |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
-} |
- |
-// Tests handling of delegate info from a network delegate. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate request_delegate; |
- AsyncLoggingNetworkDelegate network_delegate; |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("simple.html"), DEFAULT_PRIORITY, &request_delegate, |
- NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); |
- EXPECT_EQ(base::string16(), load_state.param); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
- |
- size_t log_position = 0; |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- for (size_t i = 0; i < 3; ++i) { |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- if (i == 1) { |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position + 1); |
- } |
- } |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
-} |
- |
-// Tests handling of delegate info from a network delegate in the case of an |
-// HTTP redirect. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate request_delegate; |
- AsyncLoggingNetworkDelegate network_delegate; |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, |
- &request_delegate, NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); |
- EXPECT_EQ(base::string16(), load_state.param); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(2, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
- |
- size_t log_position = 0; |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- // The NetworkDelegate logged information in OnBeforeURLRequest, |
- // OnBeforeSendHeaders, and OnHeadersReceived. |
- for (size_t i = 0; i < 3; ++i) { |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- if (i == 1) { |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position + 1); |
- } |
- } |
- |
- // The URLRequest::Delegate then gets informed about the redirect. |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- // The NetworkDelegate logged information in the same three events as before. |
- for (size_t i = 0; i < 3; ++i) { |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- } |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
-} |
- |
-// Tests handling of delegate info from a network delegate in the case of HTTP |
-// AUTH. |
-TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate request_delegate; |
- AsyncLoggingNetworkDelegate network_delegate; |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &request_delegate, |
- NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); |
- EXPECT_EQ(base::string16(), load_state.param); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(1, network_delegate.created_requests()); |
- EXPECT_EQ(0, network_delegate.destroyed_requests()); |
- } |
- EXPECT_EQ(1, network_delegate.destroyed_requests()); |
- |
- size_t log_position = 0; |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- // The NetworkDelegate should have logged information in OnBeforeURLRequest, |
- // OnBeforeSendHeaders, OnHeadersReceived, OnAuthRequired, and then again in |
- // OnBeforeURLRequest and OnBeforeSendHeaders. |
- for (size_t i = 0; i < 6; ++i) { |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- if (i == 1) { |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position + 1); |
- } |
- } |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
-} |
- |
-// Tests handling of delegate info from a URLRequest::Delegate. |
-TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- AsyncLoggingUrlRequestDelegate request_delegate( |
- AsyncLoggingUrlRequestDelegate::NO_CANCEL); |
- TestURLRequestContext context(true); |
- context.set_network_delegate(NULL); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- // A chunked response with delays between chunks is used to make sure that |
- // attempts by the URLRequest delegate to log information while reading the |
- // body are ignored. Since they are ignored, this test is robust against |
- // the possibility of multiple reads being combined in the unlikely event |
- // that it occurs. |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY, |
- &request_delegate, NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- } |
- |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- |
- size_t log_position = 0; |
- |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position); |
- |
- // The delegate info should only have been logged on header complete. Other |
- // times it should silently be ignored. |
- log_position = |
- ExpectLogContainsSomewhereAfter(entries, |
- log_position + 1, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); |
-} |
- |
-// Tests handling of delegate info from a URLRequest::Delegate in the case of |
-// an HTTP redirect. |
-TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- AsyncLoggingUrlRequestDelegate request_delegate( |
- AsyncLoggingUrlRequestDelegate::NO_CANCEL); |
- TestURLRequestContext context(true); |
- context.set_network_delegate(NULL); |
- context.set_net_log(&net_log_); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, |
- &request_delegate, NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(200, r->GetResponseCode()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- } |
- |
- CapturingNetLog::CapturedEntryList entries; |
- net_log_.GetEntries(&entries); |
- |
- // Delegate info should only have been logged in OnReceivedRedirect and |
- // OnResponseStarted. |
- size_t log_position = 0; |
- for (int i = 0; i < 2; ++i) { |
- if (i == 0) { |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position) + 1; |
- } |
- |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- } |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); |
-} |
- |
-// Tests handling of delegate info from a URLRequest::Delegate in the case of |
-// an HTTP redirect, with cancellation at various points. |
-TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const AsyncLoggingUrlRequestDelegate::CancelStage kCancelStages[] = { |
- AsyncLoggingUrlRequestDelegate::CANCEL_ON_RECEIVED_REDIRECT, |
- AsyncLoggingUrlRequestDelegate::CANCEL_ON_RESPONSE_STARTED, |
- AsyncLoggingUrlRequestDelegate::CANCEL_ON_READ_COMPLETED, |
- }; |
- |
- for (size_t test_case = 0; test_case < arraysize(kCancelStages); |
- ++test_case) { |
- AsyncLoggingUrlRequestDelegate request_delegate(kCancelStages[test_case]); |
- TestURLRequestContext context(true); |
- CapturingNetLog net_log; |
- context.set_network_delegate(NULL); |
- context.set_net_log(&net_log); |
- context.Init(); |
- |
- { |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, |
- &request_delegate, NULL)); |
- LoadStateWithParam load_state = r->GetLoadState(); |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- } |
- |
- CapturingNetLog::CapturedEntryList entries; |
- net_log.GetEntries(&entries); |
- |
- // Delegate info is always logged in both OnReceivedRedirect and |
- // OnResponseStarted. In the CANCEL_ON_RECEIVED_REDIRECT, the |
- // OnResponseStarted delegate call is after cancellation, but logging is |
- // still currently supported in that call. |
- size_t log_position = 0; |
- for (int i = 0; i < 2; ++i) { |
- if (i == 0) { |
- log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( |
- entries, log_position) + 1; |
- } |
- |
- log_position = ExpectLogContainsSomewhereAfter( |
- entries, |
- log_position, |
- NetLog::TYPE_URL_REQUEST_DELEGATE, |
- NetLog::PHASE_BEGIN); |
- |
- log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, |
- log_position + 1); |
- |
- ASSERT_LT(log_position, entries.size()); |
- EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); |
- EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); |
- } |
- |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); |
- EXPECT_FALSE(LogContainsEntryWithTypeAfter( |
- entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); |
- } |
-} |
- |
-namespace { |
- |
-const char kExtraHeader[] = "Allow-Snafu"; |
-const char kExtraValue[] = "fubar"; |
- |
-class RedirectWithAdditionalHeadersDelegate : public TestDelegate { |
- void OnReceivedRedirect(URLRequest* request, |
- const RedirectInfo& redirect_info, |
- bool* defer_redirect) override { |
- TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect); |
- request->SetExtraRequestHeaderByName(kExtraHeader, kExtraValue, false); |
- } |
-}; |
- |
-} // namespace |
- |
-TEST_F(URLRequestTestHTTP, RedirectWithAdditionalHeadersTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL destination_url = test_server_.GetURL( |
- "echoheader?" + std::string(kExtraHeader)); |
- GURL original_url = test_server_.GetURL( |
- "server-redirect?" + destination_url.spec()); |
- RedirectWithAdditionalHeadersDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- std::string value; |
- const HttpRequestHeaders& headers = req->extra_request_headers(); |
- EXPECT_TRUE(headers.GetHeader(kExtraHeader, &value)); |
- EXPECT_EQ(kExtraValue, value); |
- EXPECT_FALSE(req->is_pending()); |
- EXPECT_FALSE(req->is_redirecting()); |
- EXPECT_EQ(kExtraValue, d.data_received()); |
-} |
- |
-namespace { |
- |
-const char kExtraHeaderToRemove[] = "To-Be-Removed"; |
- |
-class RedirectWithHeaderRemovalDelegate : public TestDelegate { |
- void OnReceivedRedirect(URLRequest* request, |
- const RedirectInfo& redirect_info, |
- bool* defer_redirect) override { |
- TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect); |
- request->RemoveRequestHeaderByName(kExtraHeaderToRemove); |
- } |
-}; |
- |
-} // namespace |
- |
-TEST_F(URLRequestTestHTTP, RedirectWithHeaderRemovalTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL destination_url = test_server_.GetURL( |
- "echoheader?" + std::string(kExtraHeaderToRemove)); |
- GURL original_url = test_server_.GetURL( |
- "server-redirect?" + destination_url.spec()); |
- RedirectWithHeaderRemovalDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->SetExtraRequestHeaderByName(kExtraHeaderToRemove, "dummy", false); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- std::string value; |
- const HttpRequestHeaders& headers = req->extra_request_headers(); |
- EXPECT_FALSE(headers.GetHeader(kExtraHeaderToRemove, &value)); |
- EXPECT_FALSE(req->is_pending()); |
- EXPECT_FALSE(req->is_redirecting()); |
- EXPECT_EQ("None", d.data_received()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelTest) { |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- GURL("http://www.google.com/"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- r->Cancel(); |
- |
- base::RunLoop().Run(); |
- |
- // We expect to receive OnResponseStarted even though the request has been |
- // cancelled. |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelTest2) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- d.set_cancel_in_response_started(true); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelTest3) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- d.set_cancel_in_received_data(true); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- // There is no guarantee about how much data was received |
- // before the cancel was issued. It could have been 0 bytes, |
- // or it could have been all the bytes. |
- // EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelTest4) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- // The request will be implicitly canceled when it is destroyed. The |
- // test delegate must not post a quit message when this happens because |
- // this test doesn't actually have a message loop. The quit message would |
- // get put on this thread's message queue and the next test would exit |
- // early, causing problems. |
- d.set_quit_on_complete(false); |
- } |
- // expect things to just cleanup properly. |
- |
- // we won't actually get a received reponse here because we've never run the |
- // message loop |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(0, d.bytes_received()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelTest5) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- // populate cache |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- } |
- |
- // cancel read from cache (see bug 990242) |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- r->Cancel(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, PostTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- HTTPUploadDataOperationTest("POST"); |
-} |
- |
-TEST_F(URLRequestTestHTTP, PutTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- HTTPUploadDataOperationTest("PUT"); |
-} |
- |
-TEST_F(URLRequestTestHTTP, PostEmptyTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->set_method("POST"); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- ASSERT_EQ(1, d.response_started_count()) |
- << "request failed: " << r->status().status() |
- << ", error: " << r->status().error(); |
- |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_TRUE(d.data_received().empty()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, PostFileTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->set_method("POST"); |
- |
- base::FilePath dir; |
- PathService::Get(base::DIR_EXE, &dir); |
- base::SetCurrentDirectory(dir); |
- |
- ScopedVector<UploadElementReader> element_readers; |
- |
- base::FilePath path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &path); |
- path = path.Append(FILE_PATH_LITERAL("net")); |
- path = path.Append(FILE_PATH_LITERAL("data")); |
- path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
- path = path.Append(FILE_PATH_LITERAL("with-headers.html")); |
- element_readers.push_back( |
- new UploadFileElementReader(base::MessageLoopProxy::current().get(), |
- path, |
- 0, |
- kuint64max, |
- base::Time())); |
- r->set_upload(make_scoped_ptr<UploadDataStream>( |
- new ElementsUploadDataStream(element_readers.Pass(), 0))); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 size64 = 0; |
- ASSERT_EQ(true, base::GetFileSize(path, &size64)); |
- ASSERT_LE(size64, std::numeric_limits<int>::max()); |
- int size = static_cast<int>(size64); |
- scoped_ptr<char[]> buf(new char[size]); |
- |
- ASSERT_EQ(size, base::ReadFile(path, buf.get(), size)); |
- |
- ASSERT_EQ(1, d.response_started_count()) |
- << "request failed: " << r->status().status() |
- << ", error: " << r->status().error(); |
- |
- EXPECT_FALSE(d.received_data_before_response()); |
- |
- EXPECT_EQ(size, d.bytes_received()); |
- EXPECT_EQ(std::string(&buf[0], size), d.data_received()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->set_method("POST"); |
- |
- ScopedVector<UploadElementReader> element_readers; |
- |
- element_readers.push_back(new UploadFileElementReader( |
- base::MessageLoopProxy::current().get(), |
- base::FilePath(FILE_PATH_LITERAL( |
- "c:\\path\\to\\non\\existant\\file.randomness.12345")), |
- 0, |
- kuint64max, |
- base::Time())); |
- r->set_upload(make_scoped_ptr<UploadDataStream>( |
- new ElementsUploadDataStream(element_readers.Pass(), 0))); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.request_failed()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- EXPECT_EQ(ERR_FILE_NOT_FOUND, r->status().error()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->EnableChunkedUpload(); |
- r->set_method("POST"); |
- AddChunksToUpload(r.get()); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- VerifyReceivedDataMatchesChunks(r.get(), &d); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->EnableChunkedUpload(); |
- r->set_method("POST"); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- AddChunksToUpload(r.get()); |
- base::RunLoop().Run(); |
- |
- VerifyReceivedDataMatchesChunks(r.get(), &d); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); |
- r->EnableChunkedUpload(); |
- r->set_method("POST"); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().RunUntilIdle(); |
- AddChunksToUpload(r.get()); |
- base::RunLoop().Run(); |
- |
- VerifyReceivedDataMatchesChunks(r.get(), &d); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, ResponseHeadersTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/with-headers.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- const HttpResponseHeaders* headers = req->response_headers(); |
- |
- // Simple sanity check that response_info() accesses the same data. |
- EXPECT_EQ(headers, req->response_info().headers.get()); |
- |
- std::string header; |
- EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header)); |
- EXPECT_EQ("private", header); |
- |
- header.clear(); |
- EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header)); |
- EXPECT_EQ("text/html; charset=ISO-8859-1", header); |
- |
- // The response has two "X-Multiple-Entries" headers. |
- // This verfies our output has them concatenated together. |
- header.clear(); |
- EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header)); |
- EXPECT_EQ("a, b", header); |
-} |
- |
-TEST_F(URLRequestTestHTTP, ProcessSTS) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- SpawnedTestServer https_test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
- ASSERT_TRUE(https_test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- request->Start(); |
- base::RunLoop().Run(); |
- |
- TransportSecurityState* security_state = |
- default_context_.transport_security_state(); |
- TransportSecurityState::DomainState domain_state; |
- EXPECT_TRUE(security_state->GetDynamicDomainState( |
- SpawnedTestServer::kLocalhost, &domain_state)); |
- EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
- domain_state.sts.upgrade_mode); |
- EXPECT_TRUE(domain_state.sts.include_subdomains); |
- EXPECT_FALSE(domain_state.pkp.include_subdomains); |
-#if defined(OS_ANDROID) |
- // Android's CertVerifyProc does not (yet) handle pins. |
-#else |
- EXPECT_FALSE(domain_state.HasPublicKeyPins()); |
-#endif |
-} |
- |
-// Android's CertVerifyProc does not (yet) handle pins. Therefore, it will |
-// reject HPKP headers, and a test setting only HPKP headers will fail (no |
-// DomainState present because header rejected). |
-#if defined(OS_ANDROID) |
-#define MAYBE_ProcessPKP DISABLED_ProcessPKP |
-#else |
-#define MAYBE_ProcessPKP ProcessPKP |
-#endif |
- |
-// Tests that enabling HPKP on a domain does not affect the HSTS |
-// validity/expiration. |
-TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- SpawnedTestServer https_test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
- ASSERT_TRUE(https_test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- request->Start(); |
- base::RunLoop().Run(); |
- |
- TransportSecurityState* security_state = |
- default_context_.transport_security_state(); |
- TransportSecurityState::DomainState domain_state; |
- EXPECT_TRUE(security_state->GetDynamicDomainState( |
- SpawnedTestServer::kLocalhost, &domain_state)); |
- EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT, |
- domain_state.sts.upgrade_mode); |
- EXPECT_FALSE(domain_state.sts.include_subdomains); |
- EXPECT_FALSE(domain_state.pkp.include_subdomains); |
- EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
- EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
-} |
- |
-TEST_F(URLRequestTestHTTP, ProcessSTSOnce) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- SpawnedTestServer https_test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
- ASSERT_TRUE(https_test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- https_test_server.GetURL("files/hsts-multiple-headers.html"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- request->Start(); |
- base::RunLoop().Run(); |
- |
- // We should have set parameters from the first header, not the second. |
- TransportSecurityState* security_state = |
- default_context_.transport_security_state(); |
- TransportSecurityState::DomainState domain_state; |
- EXPECT_TRUE(security_state->GetDynamicDomainState( |
- SpawnedTestServer::kLocalhost, &domain_state)); |
- EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
- domain_state.sts.upgrade_mode); |
- EXPECT_FALSE(domain_state.sts.include_subdomains); |
- EXPECT_FALSE(domain_state.pkp.include_subdomains); |
-} |
- |
-TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- SpawnedTestServer https_test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
- ASSERT_TRUE(https_test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- https_test_server.GetURL("files/hsts-and-hpkp-headers.html"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- request->Start(); |
- base::RunLoop().Run(); |
- |
- // We should have set parameters from the first header, not the second. |
- TransportSecurityState* security_state = |
- default_context_.transport_security_state(); |
- TransportSecurityState::DomainState domain_state; |
- EXPECT_TRUE(security_state->GetDynamicDomainState( |
- SpawnedTestServer::kLocalhost, &domain_state)); |
- EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
- domain_state.sts.upgrade_mode); |
-#if defined(OS_ANDROID) |
- // Android's CertVerifyProc does not (yet) handle pins. |
-#else |
- EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
-#endif |
- EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
- |
- // Even though there is an HSTS header asserting includeSubdomains, it is |
- // the *second* such header, and we MUST process only the first. |
- EXPECT_FALSE(domain_state.sts.include_subdomains); |
- // includeSubdomains does not occur in the test HPKP header. |
- EXPECT_FALSE(domain_state.pkp.include_subdomains); |
-} |
- |
-// Tests that when multiple HPKP headers are present, asserting different |
-// policies, that only the first such policy is processed. |
-TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- SpawnedTestServer https_test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
- ASSERT_TRUE(https_test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- request->Start(); |
- base::RunLoop().Run(); |
- |
- TransportSecurityState* security_state = |
- default_context_.transport_security_state(); |
- TransportSecurityState::DomainState domain_state; |
- EXPECT_TRUE(security_state->GetDynamicDomainState( |
- SpawnedTestServer::kLocalhost, &domain_state)); |
- EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
- domain_state.sts.upgrade_mode); |
-#if defined(OS_ANDROID) |
- // Android's CertVerifyProc does not (yet) handle pins. |
-#else |
- EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
-#endif |
- EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
- |
- EXPECT_TRUE(domain_state.sts.include_subdomains); |
- EXPECT_FALSE(domain_state.pkp.include_subdomains); |
-} |
- |
-TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/content-type-normalization.html"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- std::string mime_type; |
- req->GetMimeType(&mime_type); |
- EXPECT_EQ("text/html", mime_type); |
- |
- std::string charset; |
- req->GetCharset(&charset); |
- EXPECT_EQ("utf-8", charset); |
- req->Cancel(); |
-} |
- |
-TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) { |
- // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget(). |
- GURL data_url("data:,foo"); |
- DataProtocolHandler data_protocol_handler; |
- EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url)); |
- |
- // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget(). |
- EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(data_url)); |
-} |
- |
-#if !defined(DISABLE_FILE_SUPPORT) |
-TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) { |
- // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget(). |
- GURL file_url("file:///foo.txt"); |
- FileProtocolHandler file_protocol_handler(base::MessageLoopProxy::current()); |
- EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url)); |
- |
- // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget(). |
- EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(file_url)); |
-} |
- |
-TEST_F(URLRequestTestHTTP, RestrictFileRedirects) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-to-file.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error()); |
-} |
-#endif // !defined(DISABLE_FILE_SUPPORT) |
- |
-TEST_F(URLRequestTestHTTP, RestrictDataRedirects) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-to-data.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::MessageLoop::current()->Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-to-invalid-url.html"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_INVALID_URL, req->status().error()); |
-} |
- |
-// Make sure redirects are cached, despite not reading their bodies. |
-TEST_F(URLRequestTestHTTP, CacheRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- GURL redirect_url = |
- test_server_.GetURL("files/redirect302-to-echo-cacheable"); |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- redirect_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(test_server_.GetURL("echo"), req->url()); |
- } |
- |
- { |
- TestDelegate d; |
- d.set_quit_on_redirect(true); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- redirect_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(0, d.response_started_count()); |
- EXPECT_TRUE(req->was_cached()); |
- |
- req->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- EXPECT_EQ(test_server_.GetURL("echo"), req->url()); |
- } |
-} |
- |
-// Make sure a request isn't cached when a NetworkDelegate forces a redirect |
-// when the headers are read, since the body won't have been read. |
-TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- // URL that is normally cached. |
- GURL initial_url = test_server_.GetURL("cachetime"); |
- |
- { |
- // Set up the TestNetworkDelegate tp force a redirect. |
- GURL redirect_to_url = test_server_.GetURL("echo"); |
- default_network_delegate_.set_redirect_on_headers_received_url( |
- redirect_to_url); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- initial_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(redirect_to_url, req->url()); |
- } |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- initial_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- EXPECT_FALSE(req->was_cached()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- EXPECT_EQ(initial_url, req->url()); |
- } |
-} |
- |
-// Tests that redirection to an unsafe URL is allowed when it has been marked as |
-// safe. |
-TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL unsafe_url("data:text/html,this-is-considered-an-unsafe-url"); |
- default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); |
- default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(unsafe_url, r->url()); |
- EXPECT_EQ("this-is-considered-an-unsafe-url", d.data_received()); |
- } |
-} |
- |
-// Tests that a redirect to a different unsafe URL is blocked, even after adding |
-// some other URL to the whitelist. |
-TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL unsafe_url("data:text/html,something"); |
- GURL different_unsafe_url("data:text/html,something-else"); |
- default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); |
- default_network_delegate_.set_allowed_unsafe_redirect_url( |
- different_unsafe_url); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- EXPECT_EQ(ERR_UNSAFE_REDIRECT, r->status().error()); |
- } |
-} |
- |
-// Redirects from an URL with fragment to an unsafe URL with fragment should |
-// be allowed, and the reference fragment of the target URL should be preserved. |
-TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL original_url(test_server_.GetURL("original#fragment1")); |
- GURL unsafe_url("data:,url-marked-safe-and-used-in-redirect#fragment2"); |
- GURL expected_url("data:,url-marked-safe-and-used-in-redirect#fragment2"); |
- |
- default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); |
- default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(expected_url, r->url()); |
- } |
-} |
- |
-// When a delegate has specified a safe redirect URL, but it does not match the |
-// redirect target, then do not prevent the reference fragment from being added. |
-TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL original_url(test_server_.GetURL("original#expected-fragment")); |
- GURL unsafe_url("data:text/html,this-url-does-not-match-redirect-url"); |
- GURL redirect_url(test_server_.GetURL("target")); |
- GURL expected_redirect_url(test_server_.GetURL("target#expected-fragment")); |
- |
- default_network_delegate_.set_redirect_on_headers_received_url(redirect_url); |
- default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(expected_redirect_url, r->url()); |
- } |
-} |
- |
-// When a delegate has specified a safe redirect URL, assume that the redirect |
-// URL should not be changed. In particular, the reference fragment should not |
-// be modified. |
-TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL original_url(test_server_.GetURL("original#should-not-be-appended")); |
- GURL redirect_url("data:text/html,expect-no-reference-fragment"); |
- |
- default_network_delegate_.set_redirect_on_headers_received_url(redirect_url); |
- default_network_delegate_.set_allowed_unsafe_redirect_url(redirect_url); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(redirect_url, r->url()); |
- } |
-} |
- |
-// When a URLRequestRedirectJob is created, the redirection must be followed and |
-// the reference fragment of the target URL must not be modified. |
-TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL original_url(test_server_.GetURL("original#should-not-be-appended")); |
- GURL redirect_url(test_server_.GetURL("echo")); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- URLRequestRedirectJob* job = new URLRequestRedirectJob( |
- r.get(), &default_network_delegate_, redirect_url, |
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); |
- AddTestInterceptor()->set_main_intercept_job(job); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(redirect_url, r->url()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetReferrer("http://user:pass@foo.com/"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(std::string("http://foo.com/"), d.data_received()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetReferrer("http://foo.com/test#fragment"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(std::string("http://foo.com/test"), d.data_received()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); |
- req->SetReferrer("http://foo.com/test#fragment"); |
- req->SetReferrer(""); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(std::string("None"), d.data_received()); |
-} |
- |
-// Defer network start and then resume, checking that the request was a success |
-// and bytes were received. |
-TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_network_start(true); |
- GURL test_url(test_server_.GetURL("echo")); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_before_network_start_count()); |
- EXPECT_EQ(0, d.response_started_count()); |
- |
- req->ResumeNetworkStart(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- } |
-} |
- |
-// Check that OnBeforeNetworkStart is only called once even if there is a |
-// redirect. |
-TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_redirect(true); |
- d.set_quit_on_network_start(true); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("server-redirect?echo"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_before_network_start_count()); |
- EXPECT_EQ(0, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- |
- req->ResumeNetworkStart(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- req->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- |
- // Check that the redirect's new network transaction does not get propagated |
- // to a second OnBeforeNetworkStart() notification. |
- EXPECT_EQ(1, d.received_before_network_start_count()); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_NE(0, d.bytes_received()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- } |
-} |
- |
-// Cancel the request after learning that the request would use the network. |
-TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_network_start(true); |
- GURL test_url(test_server_.GetURL("echo")); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_before_network_start_count()); |
- EXPECT_EQ(0, d.response_started_count()); |
- |
- req->Cancel(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_cancel_in_received_redirect(true); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, DeferredRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_redirect(true); |
- GURL test_url(test_server_.GetURL("files/redirect-test.html")); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- |
- req->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- |
- base::FilePath path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &path); |
- path = path.Append(FILE_PATH_LITERAL("net")); |
- path = path.Append(FILE_PATH_LITERAL("data")); |
- path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
- path = path.Append(FILE_PATH_LITERAL("with-headers.html")); |
- |
- std::string contents; |
- EXPECT_TRUE(base::ReadFileToString(path, &contents)); |
- EXPECT_EQ(contents, d.data_received()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_redirect(true); |
- GURL test_url(test_server_.GetURL("files/redirect-test.html")); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- EXPECT_FALSE(d.have_full_request_headers()); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_TRUE(d.have_full_request_headers()); |
- CheckFullRequestHeaders(d.full_request_headers(), test_url); |
- d.ClearFullRequestHeaders(); |
- |
- req->FollowDeferredRedirect(); |
- base::RunLoop().Run(); |
- |
- GURL target_url(test_server_.GetURL("files/with-headers.html")); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_TRUE(d.have_full_request_headers()); |
- CheckFullRequestHeaders(d.full_request_headers(), target_url); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); |
- |
- base::FilePath path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &path); |
- path = path.Append(FILE_PATH_LITERAL("net")); |
- path = path.Append(FILE_PATH_LITERAL("data")); |
- path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); |
- path = path.Append(FILE_PATH_LITERAL("with-headers.html")); |
- |
- std::string contents; |
- EXPECT_TRUE(base::ReadFileToString(path, &contents)); |
- EXPECT_EQ(contents, d.data_received()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- d.set_quit_on_redirect(true); |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- |
- req->Cancel(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.bytes_received()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, VaryHeader) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- // Populate the cache. |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader("foo", "1"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- LoadTimingInfo load_timing_info; |
- req->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- } |
- |
- // Expect a cache hit. |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader("foo", "1"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(req->was_cached()); |
- |
- LoadTimingInfo load_timing_info; |
- req->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingCacheHitNoNetwork(load_timing_info); |
- } |
- |
- // Expect a cache miss. |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader("foo", "2"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_FALSE(req->was_cached()); |
- |
- LoadTimingInfo load_timing_info; |
- req->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, BasicAuth) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- // populate the cache |
- { |
- TestDelegate d; |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
- } |
- |
- // repeat request with end-to-end validation. since auth-basic results in a |
- // cachable page, we expect this test to result in a 304. in which case, the |
- // response should be fetched from the cache. |
- { |
- TestDelegate d; |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); |
- r->SetLoadFlags(LOAD_VALIDATE_CACHE); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
- |
- // Should be the same cached document. |
- EXPECT_TRUE(r->was_cached()); |
- } |
-} |
- |
-// Check that Set-Cookie headers in 401 responses are respected. |
-// http://crbug.com/6450 |
-TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL url_requiring_auth = |
- test_server_.GetURL("auth-basic?set-cookie-if-challenged"); |
- |
- // Request a page that will give a 401 containing a Set-Cookie header. |
- // Verify that when the transaction is restarted, it includes the new cookie. |
- { |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- TestDelegate d; |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url_requiring_auth, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
- |
- // Make sure we sent the cookie in the restarted transaction. |
- EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") |
- != std::string::npos); |
- } |
- |
- // Same test as above, except this time the restart is initiated earlier |
- // (without user intervention since identity is embedded in the URL). |
- { |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- TestDelegate d; |
- |
- GURL::Replacements replacements; |
- replacements.SetUsernameStr("user2"); |
- replacements.SetPasswordStr("secret"); |
- GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements); |
- |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- url_with_identity, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos); |
- |
- // Make sure we sent the cookie in the restarted transaction. |
- EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") |
- != std::string::npos); |
- } |
-} |
- |
-// Tests that load timing works as expected with auth and the cache. |
-TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- // populate the cache |
- { |
- TestDelegate d; |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
- |
- LoadTimingInfo load_timing_info_before_auth; |
- EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeAuth( |
- &load_timing_info_before_auth)); |
- TestLoadTimingNotReused(load_timing_info_before_auth, |
- CONNECT_TIMING_HAS_DNS_TIMES); |
- |
- LoadTimingInfo load_timing_info; |
- r->GetLoadTimingInfo(&load_timing_info); |
- // The test server does not support keep alive sockets, so the second |
- // request with auth should use a new socket. |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- EXPECT_NE(load_timing_info_before_auth.socket_log_id, |
- load_timing_info.socket_log_id); |
- EXPECT_LE(load_timing_info_before_auth.receive_headers_end, |
- load_timing_info.connect_timing.connect_start); |
- } |
- |
- // Repeat request with end-to-end validation. Since auth-basic results in a |
- // cachable page, we expect this test to result in a 304. In which case, the |
- // response should be fetched from the cache. |
- { |
- TestDelegate d; |
- d.set_credentials(AuthCredentials(kUser, kSecret)); |
- |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); |
- r->SetLoadFlags(LOAD_VALIDATE_CACHE); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); |
- |
- // Should be the same cached document. |
- EXPECT_TRUE(r->was_cached()); |
- |
- // Since there was a request that went over the wire, the load timing |
- // information should include connection times. |
- LoadTimingInfo load_timing_info; |
- r->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); |
- } |
-} |
- |
-// In this test, we do a POST which the server will 302 redirect. |
-// The subsequent transaction should use GET, and should not send the |
-// Content-Type header. |
-// http://code.google.com/p/chromium/issues/detail?id=843 |
-TEST_F(URLRequestTestHTTP, Post302RedirectGet) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const char kData[] = "hello world"; |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("files/redirect-to-echoall"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->set_method("POST"); |
- req->set_upload(CreateSimpleUploadData(kData)); |
- |
- // Set headers (some of which are specific to the POST). |
- HttpRequestHeaders headers; |
- headers.AddHeadersFromString( |
- "Content-Type: multipart/form-data; " |
- "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n" |
- "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9," |
- "text/plain;q=0.8,image/png,*/*;q=0.5\r\n" |
- "Accept-Language: en-US,en\r\n" |
- "Accept-Charset: ISO-8859-1,*,utf-8\r\n" |
- "Content-Length: 11\r\n" |
- "Origin: http://localhost:1337/"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- std::string mime_type; |
- req->GetMimeType(&mime_type); |
- EXPECT_EQ("text/html", mime_type); |
- |
- const std::string& data = d.data_received(); |
- |
- // Check that the post-specific headers were stripped: |
- EXPECT_FALSE(ContainsString(data, "Content-Length:")); |
- EXPECT_FALSE(ContainsString(data, "Content-Type:")); |
- EXPECT_FALSE(ContainsString(data, "Origin:")); |
- |
- // These extra request headers should not have been stripped. |
- EXPECT_TRUE(ContainsString(data, "Accept:")); |
- EXPECT_TRUE(ContainsString(data, "Accept-Language:")); |
- EXPECT_TRUE(ContainsString(data, "Accept-Charset:")); |
-} |
- |
-// The following tests check that we handle mutating the request method for |
-// HTTP redirects as expected. |
-// See http://crbug.com/56373 and http://crbug.com/102130. |
- |
-TEST_F(URLRequestTestHTTP, Redirect301Tests) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const GURL url = test_server_.GetURL("files/redirect301-to-echo"); |
- |
- HTTPRedirectMethodTest(url, "POST", "GET", true); |
- HTTPRedirectMethodTest(url, "PUT", "PUT", true); |
- HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); |
-} |
- |
-TEST_F(URLRequestTestHTTP, Redirect302Tests) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const GURL url = test_server_.GetURL("files/redirect302-to-echo"); |
- |
- HTTPRedirectMethodTest(url, "POST", "GET", true); |
- HTTPRedirectMethodTest(url, "PUT", "PUT", true); |
- HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); |
-} |
- |
-TEST_F(URLRequestTestHTTP, Redirect303Tests) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const GURL url = test_server_.GetURL("files/redirect303-to-echo"); |
- |
- HTTPRedirectMethodTest(url, "POST", "GET", true); |
- HTTPRedirectMethodTest(url, "PUT", "GET", true); |
- HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); |
-} |
- |
-TEST_F(URLRequestTestHTTP, Redirect307Tests) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const GURL url = test_server_.GetURL("files/redirect307-to-echo"); |
- |
- HTTPRedirectMethodTest(url, "POST", "POST", true); |
- HTTPRedirectMethodTest(url, "PUT", "PUT", true); |
- HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); |
-} |
- |
-TEST_F(URLRequestTestHTTP, Redirect308Tests) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const GURL url = test_server_.GetURL("files/redirect308-to-echo"); |
- |
- HTTPRedirectMethodTest(url, "POST", "POST", true); |
- HTTPRedirectMethodTest(url, "PUT", "PUT", true); |
- HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); |
-} |
- |
-// Make sure that 308 responses without bodies are not treated as redirects. |
-// Certain legacy apis that pre-date the response code expect this behavior |
-// (Like Google Drive). |
-TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- const GURL url = test_server_.GetURL("files/308-without-location-header"); |
- |
- scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- request->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, request->status().status()); |
- EXPECT_EQ(OK, request->status().error()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- EXPECT_EQ(308, request->response_headers()->response_code()); |
- EXPECT_EQ("This is not a redirect.", d.data_received()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL original_url(test_server_.GetURL("files/redirect302-to-echo#fragment")); |
- GURL expected_url(test_server_.GetURL("echo#fragment")); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- original_url, DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(original_url, r->original_url()); |
- EXPECT_EQ(expected_url, r->url()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL url(test_server_.GetURL("files/redirect302-to-echo")); |
- GURL first_party_url("http://example.com"); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->set_first_party_for_cookies(first_party_url); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(first_party_url, r->first_party_for_cookies()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- GURL url(test_server_.GetURL("files/redirect302-to-echo")); |
- GURL original_first_party_url("http://example.com"); |
- GURL expected_first_party_url(test_server_.GetURL("echo")); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->set_first_party_for_cookies(original_first_party_url); |
- r->set_first_party_url_policy( |
- URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); |
- |
- r->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(2U, r->url_chain().size()); |
- EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); |
- EXPECT_EQ(OK, r->status().error()); |
- EXPECT_EQ(expected_first_party_url, r->first_party_for_cookies()); |
- } |
-} |
- |
-TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const char kData[] = "hello world"; |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); |
- req->set_method("POST"); |
- req->set_upload(CreateSimpleUploadData(kData)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kContentLength, |
- base::UintToString(arraysize(kData) - 1)); |
- req->SetExtraRequestHeaders(headers); |
- |
- URLRequestRedirectJob* job = new URLRequestRedirectJob( |
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"), |
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); |
- AddTestInterceptor()->set_main_intercept_job(job); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ("GET", req->method()); |
-} |
- |
-TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- const char kData[] = "hello world"; |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); |
- req->set_method("POST"); |
- req->set_upload(CreateSimpleUploadData(kData)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kContentLength, |
- base::UintToString(arraysize(kData) - 1)); |
- req->SetExtraRequestHeaders(headers); |
- |
- URLRequestRedirectJob* job = new URLRequestRedirectJob( |
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"), |
- URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, |
- "Very Good Reason"); |
- AddTestInterceptor()->set_main_intercept_job(job); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ("POST", req->method()); |
- EXPECT_EQ(kData, d.data_received()); |
-} |
- |
-// Check that default A-L header is sent. |
-TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- StaticHttpUserAgentSettings settings("en", std::string()); |
- TestNetworkDelegate network_delegate; // Must outlive URLRequests. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_http_user_agent_settings(&settings); |
- context.Init(); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ("en", d.data_received()); |
-} |
- |
-// Check that an empty A-L header is not sent. http://crbug.com/77365. |
-TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- std::string empty_string; // Avoid most vexing parse on line below. |
- StaticHttpUserAgentSettings settings(empty_string, empty_string); |
- TestNetworkDelegate network_delegate; // Must outlive URLRequests. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- // We override the language after initialization because empty entries |
- // get overridden by Init(). |
- context.set_http_user_agent_settings(&settings); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ("None", d.data_received()); |
-} |
- |
-// Check that if request overrides the A-L header, the default is not appended. |
-// See http://crbug.com/20894 |
-TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(std::string("ru"), d.data_received()); |
-} |
- |
-// Check that default A-E header is sent. |
-TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_TRUE(ContainsString(d.data_received(), "gzip")); |
-} |
- |
-// Check that if request overrides the A-E header, the default is not appended. |
-// See http://crbug.com/47381 |
-TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, "identity"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_FALSE(ContainsString(d.data_received(), "gzip")); |
- EXPECT_TRUE(ContainsString(d.data_received(), "identity")); |
-} |
- |
-// Check that setting the A-C header sends the proper header. |
-TEST_F(URLRequestTestHTTP, SetAcceptCharset) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?Accept-Charset"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(std::string("koi-8r"), d.data_received()); |
-} |
- |
-// Check that default User-Agent header is sent. |
-TEST_F(URLRequestTestHTTP, DefaultUserAgent) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(default_context_.http_user_agent_settings()->GetUserAgent(), |
- d.data_received()); |
-} |
- |
-// Check that if request overrides the User-Agent header, |
-// the default is not appended. |
-TEST_F(URLRequestTestHTTP, OverrideUserAgent) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d, |
- NULL)); |
- HttpRequestHeaders headers; |
- headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)"); |
- req->SetExtraRequestHeaders(headers); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(std::string("Lynx (textmode)"), d.data_received()); |
-} |
- |
-// Check that a NULL HttpUserAgentSettings causes the corresponding empty |
-// User-Agent header to be sent but does not send the Accept-Language and |
-// Accept-Charset headers. |
-TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequests. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- // We override the HttpUserAgentSettings after initialization because empty |
- // entries get overridden by Init(). |
- context.set_http_user_agent_settings(NULL); |
- |
- struct { |
- const char* request; |
- const char* expected_response; |
- } tests[] = { { "echoheader?Accept-Language", "None" }, |
- { "echoheader?Accept-Charset", "None" }, |
- { "echoheader?User-Agent", "" } }; |
- |
- for (size_t i = 0; i < arraysize(tests); i++) { |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- test_server_.GetURL(tests[i].request), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- EXPECT_EQ(tests[i].expected_response, d.data_received()) |
- << " Request = \"" << tests[i].request << "\""; |
- } |
-} |
- |
-// Make sure that URLRequest passes on its priority updates to |
-// newly-created jobs after the first one. |
-TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context_.CreateRequest( |
- test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); |
- EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); |
- |
- scoped_refptr<URLRequestRedirectJob> redirect_job = |
- new URLRequestRedirectJob( |
- req.get(), &default_network_delegate_, test_server_.GetURL("echo"), |
- URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); |
- AddTestInterceptor()->set_main_intercept_job(redirect_job.get()); |
- |
- req->SetPriority(LOW); |
- req->Start(); |
- EXPECT_TRUE(req->is_pending()); |
- |
- scoped_refptr<URLRequestTestJob> job = |
- new URLRequestTestJob(req.get(), &default_network_delegate_); |
- AddTestInterceptor()->set_main_intercept_job(job.get()); |
- |
- // Should trigger |job| to be started. |
- base::RunLoop().Run(); |
- EXPECT_EQ(LOW, job->priority()); |
-} |
- |
-// Check that creating a network request while entering/exiting suspend mode |
-// fails as it should. This is the only case where an HttpTransactionFactory |
-// does not return an HttpTransaction. |
-TEST_F(URLRequestTestHTTP, NetworkSuspendTest) { |
- // Create a new HttpNetworkLayer that thinks it's suspended. |
- HttpNetworkSession::Params params; |
- params.host_resolver = default_context_.host_resolver(); |
- params.cert_verifier = default_context_.cert_verifier(); |
- params.transport_security_state = default_context_.transport_security_state(); |
- params.proxy_service = default_context_.proxy_service(); |
- params.ssl_config_service = default_context_.ssl_config_service(); |
- params.http_auth_handler_factory = |
- default_context_.http_auth_handler_factory(); |
- params.network_delegate = &default_network_delegate_; |
- params.http_server_properties = default_context_.http_server_properties(); |
- scoped_ptr<HttpNetworkLayer> network_layer( |
- new HttpNetworkLayer(new HttpNetworkSession(params))); |
- network_layer->OnSuspend(); |
- |
- HttpCache http_cache(network_layer.release(), default_context_.net_log(), |
- HttpCache::DefaultBackend::InMemory(0)); |
- |
- TestURLRequestContext context(true); |
- context.set_http_transaction_factory(&http_cache); |
- context.Init(); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.request_failed()); |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error()); |
-} |
- |
-// Check that creating a network request while entering/exiting suspend mode |
-// fails as it should in the case there is no cache. This is the only case |
-// where an HttpTransactionFactory does not return an HttpTransaction. |
-TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) { |
- // Create a new HttpNetworkLayer that thinks it's suspended. |
- HttpNetworkSession::Params params; |
- params.host_resolver = default_context_.host_resolver(); |
- params.cert_verifier = default_context_.cert_verifier(); |
- params.transport_security_state = default_context_.transport_security_state(); |
- params.proxy_service = default_context_.proxy_service(); |
- params.ssl_config_service = default_context_.ssl_config_service(); |
- params.http_auth_handler_factory = |
- default_context_.http_auth_handler_factory(); |
- params.network_delegate = &default_network_delegate_; |
- params.http_server_properties = default_context_.http_server_properties(); |
- HttpNetworkLayer network_layer(new HttpNetworkSession(params)); |
- network_layer.OnSuspend(); |
- |
- TestURLRequestContext context(true); |
- context.set_http_transaction_factory(&network_layer); |
- context.Init(); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(d.request_failed()); |
- EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); |
- EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error()); |
-} |
- |
-class URLRequestInterceptorTestHTTP : public URLRequestTestHTTP { |
- public: |
- // TODO(bengr): Merge this with the URLRequestInterceptorHTTPTest fixture, |
- // ideally remove the dependency on URLRequestTestJob, and maybe move these |
- // tests into the factory tests. |
- URLRequestInterceptorTestHTTP() : URLRequestTestHTTP(), interceptor_(NULL) { |
- } |
- |
- void SetUpFactory() override { |
- interceptor_ = new MockURLRequestInterceptor(); |
- job_factory_.reset(new URLRequestInterceptingJobFactory( |
- job_factory_.Pass(), make_scoped_ptr(interceptor_))); |
- } |
- |
- MockURLRequestInterceptor* interceptor() const { |
- return interceptor_; |
- } |
- |
- private: |
- MockURLRequestInterceptor* interceptor_; |
-}; |
- |
-TEST_F(URLRequestInterceptorTestHTTP, |
- NetworkDelegateNotificationOnRedirectIntercept) { |
- interceptor()->set_intercept_redirect(true); |
- interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data()); |
- |
- ASSERT_TRUE(test_server()->Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- test_server()->GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, |
- &d, nullptr)); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(interceptor()->did_intercept_redirect()); |
- // Check we got one good response |
- EXPECT_TRUE(req->status().is_success()); |
- if (req->status().is_success()) |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- |
- EXPECT_EQ(1, default_network_delegate()->created_requests()); |
- EXPECT_EQ(1, default_network_delegate()->before_send_headers_count()); |
- EXPECT_EQ(1, default_network_delegate()->headers_received_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTestHTTP, |
- NetworkDelegateNotificationOnErrorIntercept) { |
- // Intercept that error and respond with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); |
- interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); |
- default_network_delegate()->set_can_be_intercepted_on_error(true); |
- |
- ASSERT_TRUE(test_server()->Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- test_server()->GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY, |
- &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(interceptor()->did_intercept_final()); |
- |
- // Check we received one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- if (req->status().is_success()) |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- |
- EXPECT_EQ(1, default_network_delegate()->created_requests()); |
- EXPECT_EQ(1, default_network_delegate()->before_send_headers_count()); |
- EXPECT_EQ(0, default_network_delegate()->headers_received_count()); |
-} |
- |
-TEST_F(URLRequestInterceptorTestHTTP, |
- NetworkDelegateNotificationOnResponseIntercept) { |
- // Intercept that error and respond with an OK response. |
- interceptor()->set_intercept_final_response(true); |
- |
- // Intercept with a real URLRequestHttpJob. |
- interceptor()->set_use_url_request_http_job(true); |
- |
- ASSERT_TRUE(test_server()->Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req(default_context().CreateRequest( |
- test_server()->GetURL("files/simple.html"), DEFAULT_PRIORITY, |
- &d, nullptr)); |
- req->set_method("GET"); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_TRUE(interceptor()->did_intercept_final()); |
- |
- // Check we received one good response. |
- EXPECT_TRUE(req->status().is_success()); |
- if (req->status().is_success()) |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- EXPECT_EQ("hello", d.data_received()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(0, d.received_redirect_count()); |
- |
- EXPECT_EQ(1, default_network_delegate()->created_requests()); |
- EXPECT_EQ(2, default_network_delegate()->before_send_headers_count()); |
- EXPECT_EQ(2, default_network_delegate()->headers_received_count()); |
-} |
- |
-class URLRequestTestReferrerPolicy : public URLRequestTest { |
- public: |
- URLRequestTestReferrerPolicy() {} |
- |
- void InstantiateSameOriginServers(SpawnedTestServer::Type origin_type) { |
- origin_server_.reset(new SpawnedTestServer( |
- origin_type, SpawnedTestServer::kLocalhost, |
- origin_type == SpawnedTestServer::TYPE_HTTPS |
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) |
- : base::FilePath( |
- FILE_PATH_LITERAL("net/data/url_request_unittest")))); |
- ASSERT_TRUE(origin_server_->Start()); |
- } |
- |
- void InstantiateCrossOriginServers(SpawnedTestServer::Type origin_type, |
- SpawnedTestServer::Type destination_type) { |
- origin_server_.reset(new SpawnedTestServer( |
- origin_type, SpawnedTestServer::kLocalhost, |
- origin_type == SpawnedTestServer::TYPE_HTTPS |
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) |
- : base::FilePath( |
- FILE_PATH_LITERAL("net/data/url_request_unittest")))); |
- ASSERT_TRUE(origin_server_->Start()); |
- |
- destination_server_.reset(new SpawnedTestServer( |
- destination_type, SpawnedTestServer::kLocalhost, |
- destination_type == SpawnedTestServer::TYPE_HTTPS |
- ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) |
- : base::FilePath( |
- FILE_PATH_LITERAL("net/data/url_request_unittest")))); |
- ASSERT_TRUE(destination_server_->Start()); |
- } |
- |
- void VerifyReferrerAfterRedirect(URLRequest::ReferrerPolicy policy, |
- const GURL& referrer, |
- const GURL& expected) { |
- // Create and execute the request: we'll only have a |destination_server_| |
- // if the origins are meant to be distinct. Otherwise, we'll use the |
- // |origin_server_| for both endpoints. |
- GURL destination_url = |
- destination_server_ ? destination_server_->GetURL("echoheader?Referer") |
- : origin_server_->GetURL("echoheader?Referer"); |
- GURL origin_url = |
- origin_server_->GetURL("server-redirect?" + destination_url.spec()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> req( |
- default_context_.CreateRequest(origin_url, DEFAULT_PRIORITY, &d, NULL)); |
- req->set_referrer_policy(policy); |
- req->SetReferrer(referrer.spec()); |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_EQ(1, d.received_redirect_count()); |
- EXPECT_EQ(destination_url, req->url()); |
- EXPECT_TRUE(req->status().is_success()); |
- EXPECT_EQ(200, req->response_headers()->response_code()); |
- |
- EXPECT_EQ(expected.spec(), req->referrer()); |
- if (expected.is_empty()) |
- EXPECT_EQ("None", d.data_received()); |
- else |
- EXPECT_EQ(expected.spec(), d.data_received()); |
- } |
- |
- SpawnedTestServer* origin_server() const { return origin_server_.get(); } |
- |
- private: |
- scoped_ptr<SpawnedTestServer> origin_server_; |
- scoped_ptr<SpawnedTestServer> destination_server_; |
-}; |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPToSameOriginHTTP) { |
- InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTP); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPToCrossOriginHTTP) { |
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP, |
- SpawnedTestServer::TYPE_HTTP); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPSToSameOriginHTTPS) { |
- InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTPS); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPSToCrossOriginHTTPS) { |
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS, |
- SpawnedTestServer::TYPE_HTTPS); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPToHTTPS) { |
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP, |
- SpawnedTestServer::TYPE_HTTPS); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-TEST_F(URLRequestTestReferrerPolicy, HTTPSToHTTP) { |
- InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS, |
- SpawnedTestServer::TYPE_HTTP); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, |
- origin_server()->GetURL("path/to/file.html"), GURL()); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), GURL()); |
- |
- VerifyReferrerAfterRedirect( |
- URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL(std::string())); |
- |
- VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, |
- origin_server()->GetURL("path/to/file.html"), |
- origin_server()->GetURL("path/to/file.html")); |
-} |
- |
-class HTTPSRequestTest : public testing::Test { |
- public: |
- HTTPSRequestTest() : default_context_(true) { |
- default_context_.set_network_delegate(&default_network_delegate_); |
- default_context_.Init(); |
- } |
- ~HTTPSRequestTest() override {} |
- |
- protected: |
- TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. |
- TestURLRequestContext default_context_; |
-}; |
- |
-TEST_F(HTTPSRequestTest, HTTPSGetTest) { |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- SpawnedTestServer::kLocalhost, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- CheckSSLInfo(r->ssl_info()); |
- EXPECT_EQ(test_server.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- } |
-} |
- |
-TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- bool err_allowed = true; |
- for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { |
- TestDelegate d; |
- { |
- d.set_allow_certificate_errors(err_allowed); |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_TRUE(d.have_certificate_errors()); |
- if (err_allowed) { |
- EXPECT_NE(0, d.bytes_received()); |
- CheckSSLInfo(r->ssl_info()); |
- } else { |
- EXPECT_EQ(0, d.bytes_received()); |
- } |
- } |
- } |
-} |
- |
-TEST_F(HTTPSRequestTest, HTTPSExpiredTest) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_EXPIRED); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Iterate from false to true, just so that we do the opposite of the |
- // previous test in order to increase test coverage. |
- bool err_allowed = false; |
- for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { |
- TestDelegate d; |
- { |
- d.set_allow_certificate_errors(err_allowed); |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_TRUE(d.have_certificate_errors()); |
- if (err_allowed) { |
- EXPECT_NE(0, d.bytes_received()); |
- CheckSSLInfo(r->ssl_info()); |
- } else { |
- EXPECT_EQ(0, d.bytes_received()); |
- } |
- } |
- } |
-} |
- |
-// This tests that a load of www.google.com with a certificate error sets |
-// the |certificate_errors_are_fatal| flag correctly. This flag will cause |
-// the interstitial to be fatal. |
-TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- // We require that the URL be www.google.com in order to pick up the |
- // preloaded HSTS entries in the TransportSecurityState. This means that we |
- // have to use a MockHostResolver in order to direct www.google.com to the |
- // testserver. By default, MockHostResolver maps all hosts to 127.0.0.1. |
- |
- MockHostResolver host_resolver; |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_host_resolver(&host_resolver); |
- TransportSecurityState transport_security_state; |
- context.set_transport_security_state(&transport_security_state); |
- context.Init(); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- GURL(base::StringPrintf("https://www.google.com:%d", |
- test_server.host_port_pair().port())), |
- DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_TRUE(d.have_certificate_errors()); |
- EXPECT_TRUE(d.certificate_errors_are_fatal()); |
-} |
- |
-// This tests that cached HTTPS page loads do not cause any updates to the |
-// TransportSecurityState. |
-TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) { |
- // The actual problem -- CERT_MISMATCHED_NAME in this case -- doesn't |
- // matter. It just has to be any error. |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- // We require that the URL be www.google.com in order to pick up the static |
- // and dynamic STS and PKP entries in the TransportSecurityState. This means |
- // that we have to use a MockHostResolver in order to direct www.google.com to |
- // the testserver. By default, MockHostResolver maps all hosts to 127.0.0.1. |
- |
- MockHostResolver host_resolver; |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- TestURLRequestContext context(true); |
- context.set_network_delegate(&network_delegate); |
- context.set_host_resolver(&host_resolver); |
- TransportSecurityState transport_security_state; |
- |
- TransportSecurityState::DomainState static_domain_state; |
- EXPECT_TRUE(transport_security_state.GetStaticDomainState( |
- "www.google.com", &static_domain_state)); |
- context.set_transport_security_state(&transport_security_state); |
- context.Init(); |
- |
- TransportSecurityState::DomainState dynamic_domain_state; |
- EXPECT_FALSE(transport_security_state.GetDynamicDomainState( |
- "www.google.com", &dynamic_domain_state)); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(context.CreateRequest( |
- GURL(base::StringPrintf("https://www.google.com:%d", |
- test_server.host_port_pair().port())), |
- DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_TRUE(d.have_certificate_errors()); |
- EXPECT_TRUE(d.certificate_errors_are_fatal()); |
- |
- // Get a fresh copy of the states, and check that they haven't changed. |
- TransportSecurityState::DomainState new_static_domain_state; |
- EXPECT_TRUE(transport_security_state.GetStaticDomainState( |
- "www.google.com", &new_static_domain_state)); |
- TransportSecurityState::DomainState new_dynamic_domain_state; |
- EXPECT_FALSE(transport_security_state.GetDynamicDomainState( |
- "www.google.com", &new_dynamic_domain_state)); |
- |
- EXPECT_EQ(new_static_domain_state.sts.upgrade_mode, |
- static_domain_state.sts.upgrade_mode); |
- EXPECT_EQ(new_static_domain_state.sts.include_subdomains, |
- static_domain_state.sts.include_subdomains); |
- EXPECT_EQ(new_static_domain_state.pkp.include_subdomains, |
- static_domain_state.pkp.include_subdomains); |
- EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.spki_hashes, |
- static_domain_state.pkp.spki_hashes)); |
- EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.bad_spki_hashes, |
- static_domain_state.pkp.bad_spki_hashes)); |
-} |
- |
-// Make sure HSTS preserves a POST request's method and body. |
-TEST_F(HTTPSRequestTest, HSTSPreservesPosts) { |
- static const char kData[] = "hello world"; |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- |
- // Per spec, TransportSecurityState expects a domain name, rather than an IP |
- // address, so a MockHostResolver is needed to redirect www.somewhere.com to |
- // the SpawnedTestServer. By default, MockHostResolver maps all hosts |
- // to 127.0.0.1. |
- MockHostResolver host_resolver; |
- |
- // Force https for www.somewhere.com. |
- TransportSecurityState transport_security_state; |
- base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000); |
- bool include_subdomains = false; |
- transport_security_state.AddHSTS("www.somewhere.com", expiry, |
- include_subdomains); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- |
- TestURLRequestContext context(true); |
- context.set_host_resolver(&host_resolver); |
- context.set_transport_security_state(&transport_security_state); |
- context.set_network_delegate(&network_delegate); |
- context.Init(); |
- |
- TestDelegate d; |
- // Navigating to https://www.somewhere.com instead of https://127.0.0.1 will |
- // cause a certificate error. Ignore the error. |
- d.set_allow_certificate_errors(true); |
- |
- scoped_ptr<URLRequest> req(context.CreateRequest( |
- GURL(base::StringPrintf("http://www.somewhere.com:%d/echo", |
- test_server.host_port_pair().port())), |
- DEFAULT_PRIORITY, &d, NULL)); |
- req->set_method("POST"); |
- req->set_upload(CreateSimpleUploadData(kData)); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ("https", req->url().scheme()); |
- EXPECT_EQ("POST", req->method()); |
- EXPECT_EQ(kData, d.data_received()); |
- |
- LoadTimingInfo load_timing_info; |
- network_delegate.GetLoadTimingInfoBeforeRedirect(&load_timing_info); |
- // LoadTimingInfo of HSTS redirects is similar to that of network cache hits |
- TestLoadTimingCacheHitNoNetwork(load_timing_info); |
-} |
- |
-// Make sure that the CORS headers are added to cross-origin HSTS redirects. |
-TEST_F(HTTPSRequestTest, HSTSCrossOriginAddHeaders) { |
- static const char kOriginHeaderValue[] = "http://www.example.com"; |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- // Per spec, TransportSecurityState expects a domain name, rather than an IP |
- // address, so a MockHostResolver is needed to redirect example.net to the |
- // SpawnedTestServer. MockHostResolver maps all hosts to 127.0.0.1 by default. |
- MockHostResolver host_resolver; |
- |
- TransportSecurityState transport_security_state; |
- base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1); |
- bool include_subdomains = false; |
- transport_security_state.AddHSTS("example.net", expiry, include_subdomains); |
- |
- TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
- |
- MockCertVerifier cert_verifier; |
- cert_verifier.set_default_result(OK); |
- |
- TestURLRequestContext context(true); |
- context.set_host_resolver(&host_resolver); |
- context.set_transport_security_state(&transport_security_state); |
- context.set_network_delegate(&network_delegate); |
- context.set_cert_verifier(&cert_verifier); |
- context.Init(); |
- |
- GURL hsts_http_url(base::StringPrintf("http://example.net:%d/somehstssite", |
- test_server.host_port_pair().port())); |
- url::Replacements<char> replacements; |
- const char kNewScheme[] = "https"; |
- replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme))); |
- GURL hsts_https_url = hsts_http_url.ReplaceComponents(replacements); |
- |
- TestDelegate d; |
- // Quit on redirect to allow response header inspection upon redirect. |
- d.set_quit_on_redirect(true); |
- |
- scoped_ptr<URLRequest> req(context.CreateRequest(hsts_http_url, |
- DEFAULT_PRIORITY, &d, NULL)); |
- // Set Origin header to simulate a cross-origin request. |
- HttpRequestHeaders request_headers; |
- request_headers.SetHeader("Origin", kOriginHeaderValue); |
- req->SetExtraRequestHeaders(request_headers); |
- |
- req->Start(); |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.received_redirect_count()); |
- |
- const HttpResponseHeaders* headers = req->response_headers(); |
- std::string redirect_location; |
- EXPECT_TRUE(headers->EnumerateHeader(NULL, "Location", &redirect_location)); |
- EXPECT_EQ(hsts_https_url.spec(), redirect_location); |
- |
- std::string received_cors_header; |
- EXPECT_TRUE(headers->EnumerateHeader(NULL, "Access-Control-Allow-Origin", |
- &received_cors_header)); |
- EXPECT_EQ(kOriginHeaderValue, received_cors_header); |
-} |
- |
-namespace { |
- |
-class SSLClientAuthTestDelegate : public TestDelegate { |
- public: |
- SSLClientAuthTestDelegate() : on_certificate_requested_count_(0) { |
- } |
- void OnCertificateRequested(URLRequest* request, |
- SSLCertRequestInfo* cert_request_info) override { |
- on_certificate_requested_count_++; |
- base::MessageLoop::current()->Quit(); |
- } |
- int on_certificate_requested_count() { |
- return on_certificate_requested_count_; |
- } |
- private: |
- int on_certificate_requested_count_; |
-}; |
- |
-} // namespace |
- |
-// TODO(davidben): Test the rest of the code. Specifically, |
-// - Filtering which certificates to select. |
-// - Sending a certificate back. |
-// - Getting a certificate request in an SSL renegotiation sending the |
-// HTTP request. |
-TEST_F(HTTPSRequestTest, ClientAuthTest) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- ssl_options.request_client_certificate = true; |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- SSLClientAuthTestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.on_certificate_requested_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(0, d.bytes_received()); |
- |
- // Send no certificate. |
- // TODO(davidben): Get temporary client cert import (with keys) working on |
- // all platforms so we can test sending a cert as well. |
- r->ContinueWithCertificate(NULL); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_NE(0, d.bytes_received()); |
- } |
-} |
- |
-TEST_F(HTTPSRequestTest, ResumeTest) { |
- // Test that we attempt a session resume when making two connections to the |
- // same host. |
- SpawnedTestServer::SSLOptions ssl_options; |
- ssl_options.record_resume = true; |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- SSLClientSocket::ClearSessionCache(); |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- } |
- |
- reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())-> |
- CloseAllConnections(); |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- // The response will look like; |
- // insert abc |
- // lookup abc |
- // insert xyz |
- // |
- // With a newline at the end which makes the split think that there are |
- // four lines. |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- std::vector<std::string> lines; |
- base::SplitString(d.data_received(), '\n', &lines); |
- ASSERT_EQ(4u, lines.size()) << d.data_received(); |
- |
- std::string session_id; |
- |
- for (size_t i = 0; i < 2; i++) { |
- std::vector<std::string> parts; |
- base::SplitString(lines[i], '\t', &parts); |
- ASSERT_EQ(2u, parts.size()); |
- if (i == 0) { |
- EXPECT_EQ("insert", parts[0]); |
- session_id = parts[1]; |
- } else { |
- EXPECT_EQ("lookup", parts[0]); |
- EXPECT_EQ(session_id, parts[1]); |
- } |
- } |
- } |
-} |
- |
-// AssertTwoDistinctSessionsInserted checks that |session_info|, which must be |
-// the result of fetching "ssl-session-cache" from the test server, indicates |
-// that exactly two different sessions were inserted, with no lookups etc. |
-static void AssertTwoDistinctSessionsInserted(const string& session_info) { |
- std::vector<std::string> lines; |
- base::SplitString(session_info, '\n', &lines); |
- ASSERT_EQ(3u, lines.size()) << session_info; |
- |
- std::string session_id; |
- for (size_t i = 0; i < 2; i++) { |
- std::vector<std::string> parts; |
- base::SplitString(lines[i], '\t', &parts); |
- ASSERT_EQ(2u, parts.size()); |
- EXPECT_EQ("insert", parts[0]); |
- if (i == 0) { |
- session_id = parts[1]; |
- } else { |
- EXPECT_NE(session_id, parts[1]); |
- } |
- } |
-} |
- |
-TEST_F(HTTPSRequestTest, SSLSessionCacheShardTest) { |
- // Test that sessions aren't resumed when the value of ssl_session_cache_shard |
- // differs. |
- SpawnedTestServer::SSLOptions ssl_options; |
- ssl_options.record_resume = true; |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- SSLClientSocket::ClearSessionCache(); |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- } |
- |
- // Now create a new HttpCache with a different ssl_session_cache_shard value. |
- HttpNetworkSession::Params params; |
- params.host_resolver = default_context_.host_resolver(); |
- params.cert_verifier = default_context_.cert_verifier(); |
- params.transport_security_state = default_context_.transport_security_state(); |
- params.proxy_service = default_context_.proxy_service(); |
- params.ssl_config_service = default_context_.ssl_config_service(); |
- params.http_auth_handler_factory = |
- default_context_.http_auth_handler_factory(); |
- params.network_delegate = &default_network_delegate_; |
- params.http_server_properties = default_context_.http_server_properties(); |
- params.ssl_session_cache_shard = "alternate"; |
- |
- scoped_ptr<HttpCache> cache(new HttpCache( |
- new HttpNetworkSession(params), |
- HttpCache::DefaultBackend::InMemory(0))); |
- |
- default_context_.set_http_transaction_factory(cache.get()); |
- |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- // The response will look like; |
- // insert abc |
- // insert xyz |
- // |
- // With a newline at the end which makes the split think that there are |
- // three lines. |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- AssertTwoDistinctSessionsInserted(d.data_received()); |
- } |
-} |
- |
-#if defined(OS_WIN) |
- |
-namespace { |
- |
-bool IsECDSACipherSuite(uint16_t cipher_suite) { |
- const char* key_exchange; |
- const char* cipher; |
- const char* mac; |
- bool is_aead; |
- SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite); |
- return std::string(key_exchange).find("ECDSA") != std::string::npos; |
-} |
- |
-} // namespace |
- |
-// Test that ECDSA is disabled on Windows XP, where ECDSA certificates cannot be |
-// verified. |
-TEST_F(HTTPSRequestTest, DisableECDSAOnXP) { |
- if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
- LOG(INFO) << "Skipping test on this version."; |
- return; |
- } |
- |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- SpawnedTestServer::kLocalhost, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("client-cipher-list"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- std::vector<std::string> lines; |
- base::SplitString(d.data_received(), '\n', &lines); |
- |
- for (size_t i = 0; i < lines.size(); i++) { |
- int cipher_suite; |
- ASSERT_TRUE(base::StringToInt(lines[i], &cipher_suite)); |
- EXPECT_FALSE(IsECDSACipherSuite(cipher_suite)) |
- << "ClientHello advertised " << cipher_suite; |
- } |
-} |
- |
-#endif // OS_WIN |
- |
-class TestSSLConfigService : public SSLConfigService { |
- public: |
- TestSSLConfigService(bool ev_enabled, |
- bool online_rev_checking, |
- bool rev_checking_required_local_anchors) |
- : ev_enabled_(ev_enabled), |
- online_rev_checking_(online_rev_checking), |
- rev_checking_required_local_anchors_( |
- rev_checking_required_local_anchors), |
- min_version_(kDefaultSSLVersionMin), |
- fallback_min_version_(kDefaultSSLVersionFallbackMin) {} |
- |
- void set_min_version(uint16 version) { |
- min_version_ = version; |
- } |
- |
- void set_fallback_min_version(uint16 version) { |
- fallback_min_version_ = version; |
- } |
- |
- // SSLConfigService: |
- void GetSSLConfig(SSLConfig* config) override { |
- *config = SSLConfig(); |
- config->rev_checking_enabled = online_rev_checking_; |
- config->verify_ev_cert = ev_enabled_; |
- config->rev_checking_required_local_anchors = |
- rev_checking_required_local_anchors_; |
- if (fallback_min_version_) { |
- config->version_fallback_min = fallback_min_version_; |
- } |
- if (min_version_) { |
- config->version_min = min_version_; |
- } |
- } |
- |
- protected: |
- ~TestSSLConfigService() override {} |
- |
- private: |
- const bool ev_enabled_; |
- const bool online_rev_checking_; |
- const bool rev_checking_required_local_anchors_; |
- uint16 min_version_; |
- uint16 fallback_min_version_; |
-}; |
- |
-class FallbackTestURLRequestContext : public TestURLRequestContext { |
- public: |
- explicit FallbackTestURLRequestContext(bool delay_initialization) |
- : TestURLRequestContext(delay_initialization) {} |
- |
- void set_fallback_min_version(uint16 version) { |
- TestSSLConfigService *ssl_config_service = |
- new TestSSLConfigService(true /* check for EV */, |
- false /* online revocation checking */, |
- false /* require rev. checking for local |
- anchors */); |
- ssl_config_service->set_min_version(SSL_PROTOCOL_VERSION_SSL3); |
- ssl_config_service->set_fallback_min_version(version); |
- set_ssl_config_service(ssl_config_service); |
- } |
-}; |
- |
-class HTTPSFallbackTest : public testing::Test { |
- public: |
- HTTPSFallbackTest() : context_(true) {} |
- ~HTTPSFallbackTest() override {} |
- |
- protected: |
- void DoFallbackTest(const SpawnedTestServer::SSLOptions& ssl_options) { |
- DCHECK(!request_); |
- context_.Init(); |
- delegate_.set_allow_certificate_errors(true); |
- |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- request_ = context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate_, NULL); |
- request_->Start(); |
- |
- base::RunLoop().Run(); |
- } |
- |
- void set_fallback_min_version(uint16 version) { |
- context_.set_fallback_min_version(version); |
- } |
- |
- void ExpectConnection(int version) { |
- EXPECT_EQ(1, delegate_.response_started_count()); |
- EXPECT_NE(0, delegate_.bytes_received()); |
- EXPECT_EQ(version, SSLConnectionStatusToVersion( |
- request_->ssl_info().connection_status)); |
- EXPECT_TRUE(request_->ssl_info().connection_status & |
- SSL_CONNECTION_VERSION_FALLBACK); |
- } |
- |
- void ExpectFailure(int error) { |
- EXPECT_EQ(1, delegate_.response_started_count()); |
- EXPECT_FALSE(request_->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::FAILED, request_->status().status()); |
- EXPECT_EQ(error, request_->status().error()); |
- } |
- |
- private: |
- TestDelegate delegate_; |
- FallbackTestURLRequestContext context_; |
- scoped_ptr<URLRequest> request_; |
-}; |
- |
-// Tests TLSv1.1 -> TLSv1 fallback. Verifies that we don't fall back more |
-// than necessary. |
-TEST_F(HTTPSFallbackTest, TLSv1Fallback) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectConnection(SSL_CONNECTION_VERSION_TLS1); |
-} |
- |
-// This test is disabled on Android because the remote test server doesn't cause |
-// a TCP reset. |
-#if !defined(OS_ANDROID) |
-// Tests fallback to TLS 1.0 on connection reset. |
-TEST_F(HTTPSFallbackTest, TLSv1FallbackReset) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; |
- ssl_options.tls_intolerance_type = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectConnection(SSL_CONNECTION_VERSION_TLS1); |
-} |
-#endif // !OS_ANDROID |
- |
-// Tests that we don't fallback on handshake failure with servers that implement |
-// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported. |
-TEST_F(HTTPSFallbackTest, FallbackSCSV) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger |
- // a version fallback. |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; |
- // Have the server process TLS_FALLBACK_SCSV so that version fallback |
- // connections are rejected. |
- ssl_options.fallback_scsv_enabled = true; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- |
- // ERR_SSL_VERSION_OR_CIPHER_MISMATCH is how the server simulates version |
- // intolerance. If the fallback SCSV is processed when the original error |
- // that caused the fallback should be returned, which should be |
- // ERR_SSL_VERSION_OR_CIPHER_MISMATCH. |
- ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH); |
-} |
- |
-// Tests that we don't fallback on connection closed with servers that implement |
-// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported. |
-TEST_F(HTTPSFallbackTest, FallbackSCSVClosed) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger |
- // a version fallback. |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; |
- ssl_options.tls_intolerance_type = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; |
- // Have the server process TLS_FALLBACK_SCSV so that version fallback |
- // connections are rejected. |
- ssl_options.fallback_scsv_enabled = true; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- |
- // The original error should be replayed on rejected fallback. |
- ExpectFailure(ERR_CONNECTION_CLOSED); |
-} |
- |
-// Tests that the SSLv3 fallback doesn't happen by default. |
-TEST_F(HTTPSFallbackTest, SSLv3Fallback) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH); |
-} |
- |
-// Tests that the SSLv3 fallback works when explicitly enabled. |
-TEST_F(HTTPSFallbackTest, SSLv3FallbackEnabled) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; |
- set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectConnection(SSL_CONNECTION_VERSION_SSL3); |
-} |
- |
-// Tests that the SSLv3 fallback triggers on closed connections when explicitly |
-// enabled. |
-TEST_F(HTTPSFallbackTest, SSLv3FallbackClosed) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; |
- ssl_options.tls_intolerance_type = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; |
- set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectConnection(SSL_CONNECTION_VERSION_SSL3); |
-} |
- |
-// Test that SSLv3 fallback probe connections don't cause sessions to be cached. |
-TEST_F(HTTPSRequestTest, SSLv3FallbackNoCache) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; |
- ssl_options.tls_intolerance_type = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; |
- ssl_options.record_resume = true; |
- |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- SSLClientSocket::ClearSessionCache(); |
- |
- // Make a connection that does a probe fallback to SSLv3 but fails because |
- // SSLv3 fallback is disabled. We don't wish a session for this connection to |
- // be inserted locally. |
- { |
- TestDelegate delegate; |
- FallbackTestURLRequestContext context(true); |
- |
- context.set_fallback_min_version(SSL_PROTOCOL_VERSION_TLS1); |
- context.Init(); |
- scoped_ptr<URLRequest> request(context.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate, NULL)); |
- request->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, delegate.response_started_count()); |
- EXPECT_FALSE(request->status().is_success()); |
- EXPECT_EQ(URLRequestStatus::FAILED, request->status().status()); |
- EXPECT_EQ(ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION, |
- request->status().error()); |
- } |
- |
- // Now allow SSLv3 connections and request the session cache log. |
- { |
- TestDelegate delegate; |
- FallbackTestURLRequestContext context(true); |
- context.set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); |
- |
- context.Init(); |
- scoped_ptr<URLRequest> request( |
- context.CreateRequest(test_server.GetURL("ssl-session-cache"), |
- DEFAULT_PRIORITY, |
- &delegate, |
- NULL)); |
- request->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, delegate.response_started_count()); |
- EXPECT_NE(0, delegate.bytes_received()); |
- EXPECT_EQ(SSL_CONNECTION_VERSION_SSL3, SSLConnectionStatusToVersion( |
- request->ssl_info().connection_status)); |
- EXPECT_TRUE(request->ssl_info().connection_status & |
- SSL_CONNECTION_VERSION_FALLBACK); |
- |
- std::vector<std::string> lines; |
- // If no sessions were cached then the server should have seen two sessions |
- // inserted with no lookups. |
- AssertTwoDistinctSessionsInserted(delegate.data_received()); |
- } |
-} |
- |
-// This test is disabled on Android because the remote test server doesn't cause |
-// a TCP reset. |
-#if !defined(OS_ANDROID) |
-// Tests that a reset connection does not fallback down to SSL3. |
-TEST_F(HTTPSFallbackTest, SSLv3NoFallbackReset) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_OK); |
- ssl_options.tls_intolerant = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; |
- ssl_options.tls_intolerance_type = |
- SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET; |
- |
- ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); |
- ExpectFailure(ERR_CONNECTION_RESET); |
-} |
-#endif // !OS_ANDROID |
- |
-class HTTPSSessionTest : public testing::Test { |
- public: |
- HTTPSSessionTest() : default_context_(true) { |
- cert_verifier_.set_default_result(OK); |
- |
- default_context_.set_network_delegate(&default_network_delegate_); |
- default_context_.set_cert_verifier(&cert_verifier_); |
- default_context_.Init(); |
- } |
- ~HTTPSSessionTest() override {} |
- |
- protected: |
- MockCertVerifier cert_verifier_; |
- TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. |
- TestURLRequestContext default_context_; |
-}; |
- |
-// Tests that session resumption is not attempted if an invalid certificate |
-// is presented. |
-TEST_F(HTTPSSessionTest, DontResumeSessionsForInvalidCertificates) { |
- SpawnedTestServer::SSLOptions ssl_options; |
- ssl_options.record_resume = true; |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- SSLClientSocket::ClearSessionCache(); |
- |
- // Simulate the certificate being expired and attempt a connection. |
- cert_verifier_.set_default_result(ERR_CERT_DATE_INVALID); |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- } |
- |
- reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())-> |
- CloseAllConnections(); |
- |
- // Now change the certificate to be acceptable (so that the response is |
- // loaded), and ensure that no session id is presented to the peer. |
- cert_verifier_.set_default_result(OK); |
- { |
- TestDelegate d; |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); |
- |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- // The response will look like; |
- // insert abc |
- // insert xyz |
- // |
- // With a newline at the end which makes the split think that there are |
- // three lines. |
- // |
- // If a session was presented (eg: a bug), then the response would look |
- // like; |
- // insert abc |
- // lookup abc |
- // insert xyz |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- AssertTwoDistinctSessionsInserted(d.data_received()); |
- } |
-} |
- |
-// This the fingerprint of the "Testing CA" certificate used by the testserver. |
-// See net/data/ssl/certificates/ocsp-test-root.pem. |
-static const SHA1HashValue kOCSPTestCertFingerprint = |
- { { 0xf1, 0xad, 0xf6, 0xce, 0x42, 0xac, 0xe7, 0xb4, 0xf4, 0x24, |
- 0xdb, 0x1a, 0xf7, 0xa0, 0x9f, 0x09, 0xa1, 0xea, 0xf1, 0x5c } }; |
- |
-// This is the SHA256, SPKI hash of the "Testing CA" certificate used by the |
-// testserver. |
-static const SHA256HashValue kOCSPTestCertSPKI = { { |
- 0xee, 0xe6, 0x51, 0x2d, 0x4c, 0xfa, 0xf7, 0x3e, |
- 0x6c, 0xd8, 0xca, 0x67, 0xed, 0xb5, 0x5d, 0x49, |
- 0x76, 0xe1, 0x52, 0xa7, 0x6e, 0x0e, 0xa0, 0x74, |
- 0x09, 0x75, 0xe6, 0x23, 0x24, 0xbd, 0x1b, 0x28, |
-} }; |
- |
-// This is the policy OID contained in the certificates that testserver |
-// generates. |
-static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1"; |
- |
-class HTTPSOCSPTest : public HTTPSRequestTest { |
- public: |
- HTTPSOCSPTest() |
- : context_(true), |
- ev_test_policy_( |
- new ScopedTestEVPolicy(EVRootCAMetadata::GetInstance(), |
- kOCSPTestCertFingerprint, |
- kOCSPTestCertPolicy)) { |
- } |
- |
- void SetUp() override { |
- SetupContext(&context_); |
- context_.Init(); |
- |
- scoped_refptr<X509Certificate> root_cert = |
- ImportCertFromFile(GetTestCertsDirectory(), "ocsp-test-root.pem"); |
- CHECK_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); |
- test_root_.reset(new ScopedTestRoot(root_cert.get())); |
- |
-#if defined(USE_NSS) || defined(OS_IOS) |
- SetURLRequestContextForNSSHttpIO(&context_); |
- EnsureNSSHttpIOInit(); |
-#endif |
- } |
- |
- void DoConnection(const SpawnedTestServer::SSLOptions& ssl_options, |
- CertStatus* out_cert_status) { |
- // We always overwrite out_cert_status. |
- *out_cert_status = 0; |
- SpawnedTestServer test_server( |
- SpawnedTestServer::TYPE_HTTPS, |
- ssl_options, |
- base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); |
- ASSERT_TRUE(test_server.Start()); |
- |
- TestDelegate d; |
- d.set_allow_certificate_errors(true); |
- scoped_ptr<URLRequest> r(context_.CreateRequest( |
- test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_EQ(1, d.response_started_count()); |
- *out_cert_status = r->ssl_info().cert_status; |
- } |
- |
- ~HTTPSOCSPTest() override { |
-#if defined(USE_NSS) || defined(OS_IOS) |
- ShutdownNSSHttpIO(); |
-#endif |
- } |
- |
- protected: |
- // SetupContext configures the URLRequestContext that will be used for making |
- // connetions to testserver. This can be overridden in test subclasses for |
- // different behaviour. |
- virtual void SetupContext(URLRequestContext* context) { |
- context->set_ssl_config_service( |
- new TestSSLConfigService(true /* check for EV */, |
- true /* online revocation checking */, |
- false /* require rev. checking for local |
- anchors */)); |
- } |
- |
- scoped_ptr<ScopedTestRoot> test_root_; |
- TestURLRequestContext context_; |
- scoped_ptr<ScopedTestEVPolicy> ev_test_policy_; |
-}; |
- |
-static CertStatus ExpectedCertStatusForFailedOnlineRevocationCheck() { |
-#if defined(OS_WIN) |
- // Windows can return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION but we don't |
- // have that ability on other platforms. |
- return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; |
-#else |
- return 0; |
-#endif |
-} |
- |
-// SystemSupportsHardFailRevocationChecking returns true iff the current |
-// operating system supports revocation checking and can distinguish between |
-// situations where a given certificate lacks any revocation information (eg: |
-// no CRLDistributionPoints and no OCSP Responder AuthorityInfoAccess) and when |
-// revocation information cannot be obtained (eg: the CRL was unreachable). |
-// If it does not, then tests which rely on 'hard fail' behaviour should be |
-// skipped. |
-static bool SystemSupportsHardFailRevocationChecking() { |
-#if defined(OS_WIN) || defined(USE_NSS) || defined(OS_IOS) |
- return true; |
-#else |
- return false; |
-#endif |
-} |
- |
-// SystemUsesChromiumEVMetadata returns true iff the current operating system |
-// uses Chromium's EV metadata (i.e. EVRootCAMetadata). If it does not, then |
-// several tests are effected because our testing EV certificate won't be |
-// recognised as EV. |
-static bool SystemUsesChromiumEVMetadata() { |
-#if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID) |
- // http://crbug.com/117478 - OpenSSL does not support EV validation. |
- return false; |
-#elif (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID) |
- // On OS X and Android, we use the system to tell us whether a certificate is |
- // EV or not and the system won't recognise our testing root. |
- return false; |
-#else |
- return true; |
-#endif |
-} |
- |
-static bool SystemSupportsOCSP() { |
-#if defined(USE_OPENSSL_CERTS) |
- // http://crbug.com/117478 - OpenSSL does not support OCSP. |
- return false; |
-#elif defined(OS_WIN) |
- return base::win::GetVersion() >= base::win::VERSION_VISTA; |
-#elif defined(OS_ANDROID) |
- // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported. |
- return false; |
-#else |
- return true; |
-#endif |
-} |
- |
-static bool SystemSupportsOCSPStapling() { |
-#if defined(USE_NSS) |
- return true; |
-#elif defined(OS_WIN) |
- return base::win::GetVersion() >= base::win::VERSION_VISTA; |
-#else |
- return false; |
-#endif |
-} |
- |
-TEST_F(HTTPSOCSPTest, Valid) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); |
- |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-TEST_F(HTTPSOCSPTest, Revoked) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
-#if !(defined(OS_MACOSX) && !defined(OS_IOS)) |
- // Doesn't pass on OS X yet for reasons that need to be investigated. |
- EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); |
-#endif |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-TEST_F(HTTPSOCSPTest, Invalid) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), |
- cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- // Without a positive OCSP response, we shouldn't show the EV status. |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-TEST_F(HTTPSOCSPTest, ValidStapled) { |
- if (!SystemSupportsOCSPStapling()) { |
- LOG(WARNING) |
- << "Skipping test because system doesn't support OCSP stapling"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; |
- ssl_options.staple_ocsp_response = true; |
- ssl_options.ocsp_server_unavailable = true; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); |
- |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-// Disabled on NSS ports. See https://crbug.com/431716. |
-#if defined(USE_NSS) |
-#define MAYBE_RevokedStapled DISABLED_RevokedStapled |
-#else |
-#define MAYBE_RevokedStapled RevokedStapled |
-#endif |
-TEST_F(HTTPSOCSPTest, MAYBE_RevokedStapled) { |
- if (!SystemSupportsOCSPStapling()) { |
- LOG(WARNING) |
- << "Skipping test because system doesn't support OCSP stapling"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; |
- ssl_options.staple_ocsp_response = true; |
- ssl_options.ocsp_server_unavailable = true; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-class HTTPSHardFailTest : public HTTPSOCSPTest { |
- protected: |
- void SetupContext(URLRequestContext* context) override { |
- context->set_ssl_config_service( |
- new TestSSLConfigService(false /* check for EV */, |
- false /* online revocation checking */, |
- true /* require rev. checking for local |
- anchors */)); |
- } |
-}; |
- |
-TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- if (!SystemSupportsHardFailRevocationChecking()) { |
- LOG(WARNING) << "Skipping test because system doesn't support hard fail " |
- << "revocation checking"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(CERT_STATUS_REVOKED, |
- cert_status & CERT_STATUS_REVOKED); |
- |
- // Without a positive OCSP response, we shouldn't show the EV status. |
- EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-class HTTPSEVCRLSetTest : public HTTPSOCSPTest { |
- protected: |
- void SetupContext(URLRequestContext* context) override { |
- context->set_ssl_config_service( |
- new TestSSLConfigService(true /* check for EV */, |
- false /* online revocation checking */, |
- false /* require rev. checking for local |
- anchors */)); |
- } |
-}; |
- |
-TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndInvalidOCSP) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), |
- cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndRevokedOCSP) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; |
- SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- // Currently only works for Windows. When using NSS or OS X, it's not |
- // possible to determine whether the check failed because of actual |
- // revocation or because there was an OCSP failure. |
-#if defined(OS_WIN) |
- EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); |
-#else |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
-#endif |
- |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; |
- SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSet) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), |
- cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::ForTesting( |
- false, &kOCSPTestCertSPKI, ""))); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- // With a fresh CRLSet that covers the issuing certificate, we shouldn't do a |
- // revocation check for EV. |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); |
- EXPECT_FALSE( |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) { |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::EmptyCRLSetForTesting())); |
- |
- CertStatus cert_status = 0; |
- DoConnection(ssl_options, &cert_status); |
- |
- // Even with a fresh CRLSet, we should still do online revocation checks when |
- // the certificate chain isn't covered by the CRLSet, which it isn't in this |
- // test. |
- EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), |
- cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_EQ(SystemUsesChromiumEVMetadata(), |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
- |
-TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) { |
- // Test that when EV verification is requested, but online revocation |
- // checking is disabled, and the leaf certificate is not in fact EV, that |
- // no revocation checking actually happens. |
- if (!SystemSupportsOCSP()) { |
- LOG(WARNING) << "Skipping test because system doesn't support OCSP"; |
- return; |
- } |
- |
- // Unmark the certificate's OID as EV, which should disable revocation |
- // checking (as per the user preference) |
- ev_test_policy_.reset(); |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-class HTTPSCRLSetTest : public HTTPSOCSPTest { |
- protected: |
- void SetupContext(URLRequestContext* context) override { |
- context->set_ssl_config_service( |
- new TestSSLConfigService(false /* check for EV */, |
- false /* online revocation checking */, |
- false /* require rev. checking for local |
- anchors */)); |
- } |
-}; |
- |
-TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) { |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); |
- |
- CertStatus cert_status; |
- DoConnection(ssl_options, &cert_status); |
- |
- // If we're not trying EV verification then, even if the CRLSet has expired, |
- // we don't fall back to online revocation checks. |
- EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); |
-} |
- |
-TEST_F(HTTPSCRLSetTest, CRLSetRevoked) { |
-#if defined(OS_ANDROID) |
- LOG(WARNING) << "Skipping test because system doesn't support CRLSets"; |
- return; |
-#endif |
- |
- SpawnedTestServer::SSLOptions ssl_options( |
- SpawnedTestServer::SSLOptions::CERT_AUTO); |
- ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; |
- ssl_options.cert_serial = 10; |
- SSLConfigService::SetCRLSet( |
- scoped_refptr<CRLSet>(CRLSet::ForTesting( |
- false, &kOCSPTestCertSPKI, "\x0a"))); |
- |
- CertStatus cert_status = 0; |
- DoConnection(ssl_options, &cert_status); |
- |
- // If the certificate is recorded as revoked in the CRLSet, that should be |
- // reflected without online revocation checking. |
- EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); |
- EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); |
- EXPECT_FALSE( |
- static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); |
-} |
-#endif // !defined(OS_IOS) |
- |
-#if !defined(DISABLE_FTP_SUPPORT) |
-class URLRequestTestFTP : public URLRequestTest { |
- public: |
- URLRequestTestFTP() |
- : test_server_(SpawnedTestServer::TYPE_FTP, SpawnedTestServer::kLocalhost, |
- base::FilePath()) { |
- } |
- |
- protected: |
- SpawnedTestServer test_server_; |
-}; |
- |
-// Make sure an FTP request using an unsafe ports fails. |
-TEST_F(URLRequestTestFTP, UnsafePort) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- URLRequestJobFactoryImpl job_factory; |
- FtpNetworkLayer ftp_transaction_factory(default_context_.host_resolver()); |
- |
- GURL url("ftp://127.0.0.1:7"); |
- job_factory.SetProtocolHandler( |
- "ftp", |
- new FtpProtocolHandler(&ftp_transaction_factory)); |
- default_context_.set_job_factory(&job_factory); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- url, DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); |
- EXPECT_EQ(ERR_UNSAFE_PORT, r->status().error()); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPDirectoryListing) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("/"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_LT(0, d.bytes_received()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPGetTestAnonymous) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPGetTest) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(test_server_.host_port_pair().host(), |
- r->GetSocketAddress().host()); |
- EXPECT_EQ(test_server_.host_port_pair().port(), |
- r->GetSocketAddress().port()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
- |
- LoadTimingInfo load_timing_info; |
- r->GetLoadTimingInfo(&load_timing_info); |
- TestLoadTimingNoHttpResponse(load_timing_info); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPassword) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", |
- "wrong_password"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), 0); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPasswordRestart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- // Set correct login credentials. The delegate will be asked for them when |
- // the initial login with wrong credentials will fail. |
- d.set_credentials(AuthCredentials(kChrome, kChrome)); |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", |
- "wrong_password"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUser) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user", |
- "chrome"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), 0); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUserRestart) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- TestDelegate d; |
- // Set correct login credentials. The delegate will be asked for them when |
- // the initial login with wrong credentials will fail. |
- d.set_credentials(AuthCredentials(kChrome, kChrome)); |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user", |
- "chrome"), |
- DEFAULT_PRIORITY, &d, NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d.response_started_count()); |
- EXPECT_FALSE(d.received_data_before_response()); |
- EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCacheURLCredentials) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- |
- scoped_ptr<TestDelegate> d(new TestDelegate); |
- { |
- // Pass correct login identity in the URL. |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"), |
- DEFAULT_PRIORITY, d.get(), NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d->response_started_count()); |
- EXPECT_FALSE(d->received_data_before_response()); |
- EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
- } |
- |
- d.reset(new TestDelegate); |
- { |
- // This request should use cached identity from previous request. |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d->response_started_count()); |
- EXPECT_FALSE(d->received_data_before_response()); |
- EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
- } |
-} |
- |
-// Flaky, see http://crbug.com/25045. |
-TEST_F(URLRequestTestFTP, DISABLED_FTPCacheLoginBoxCredentials) { |
- ASSERT_TRUE(test_server_.Start()); |
- |
- base::FilePath app_path; |
- PathService::Get(base::DIR_SOURCE_ROOT, &app_path); |
- app_path = app_path.AppendASCII("LICENSE"); |
- |
- scoped_ptr<TestDelegate> d(new TestDelegate); |
- // Set correct login credentials. The delegate will be asked for them when |
- // the initial login with wrong credentials will fail. |
- d->set_credentials(AuthCredentials(kChrome, kChrome)); |
- { |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", |
- "wrong_password"), |
- DEFAULT_PRIORITY, d.get(), NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d->response_started_count()); |
- EXPECT_FALSE(d->received_data_before_response()); |
- EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
- } |
- |
- // Use a new delegate without explicit credentials. The cached ones should be |
- // used. |
- d.reset(new TestDelegate); |
- { |
- // Don't pass wrong credentials in the URL, they would override valid cached |
- // ones. |
- scoped_ptr<URLRequest> r(default_context_.CreateRequest( |
- test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL)); |
- r->Start(); |
- EXPECT_TRUE(r->is_pending()); |
- |
- base::RunLoop().Run(); |
- |
- int64 file_size = 0; |
- base::GetFileSize(app_path, &file_size); |
- |
- EXPECT_FALSE(r->is_pending()); |
- EXPECT_EQ(1, d->response_started_count()); |
- EXPECT_FALSE(d->received_data_before_response()); |
- EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
- } |
-} |
-#endif // !defined(DISABLE_FTP_SUPPORT) |
- |
-} // namespace net |