diff options
Diffstat (limited to 'chromium/net/test')
28 files changed, 941 insertions, 167 deletions
diff --git a/chromium/net/test/android/OWNERS b/chromium/net/test/android/OWNERS deleted file mode 100644 index fa129e131b8..00000000000 --- a/chromium/net/test/android/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -digit@chromium.org -yfriedman@chromium.org diff --git a/chromium/net/test/cert_test_util.cc b/chromium/net/test/cert_test_util.cc index 3ccfa65a5ad..c6c412d60e3 100644 --- a/chromium/net/test/cert_test_util.cc +++ b/chromium/net/test/cert_test_util.cc @@ -4,9 +4,8 @@ #include "net/test/cert_test_util.h" -#include "base/file_util.h" #include "base/files/file_path.h" -#include "base/path_service.h" +#include "base/files/file_util.h" #include "net/cert/ev_root_ca_metadata.h" #include "net/cert/x509_certificate.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/net/test/cert_test_util.h b/chromium/net/test/cert_test_util.h index 31b768ae583..6334dd7edd8 100644 --- a/chromium/net/test/cert_test_util.h +++ b/chromium/net/test/cert_test_util.h @@ -11,16 +11,46 @@ #include "net/cert/x509_cert_types.h" #include "net/cert/x509_certificate.h" +#if defined(USE_NSS) +#include "base/memory/scoped_ptr.h" + +// From <pk11pub.h> +typedef struct PK11SlotInfoStr PK11SlotInfo; +#endif + namespace base { class FilePath; } +namespace crypto { +class RSAPrivateKey; +} + namespace net { class EVRootCAMetadata; -// Imports all of the certificates in |cert_file|, a file in |certs_dir|, -// // into a CertificateList. +#if defined(USE_NSS) +// Imports a private key from file |key_filename| in |dir|. The file must +// contain a PKCS#8 PrivateKeyInfo in DER encoding. The key is imported to +// |slot|. +scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile( + const base::FilePath& dir, + const std::string& key_filename, + PK11SlotInfo* slot); + +bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert, + PK11SlotInfo* slot); + +scoped_refptr<X509Certificate> ImportClientCertAndKeyFromFile( + const base::FilePath& dir, + const std::string& cert_filename, + const std::string& key_filename, + PK11SlotInfo* slot); +#endif + +// Imports all of the certificates in |cert_file|, a file in |certs_dir|, into a +// CertificateList. CertificateList CreateCertificateListFromFile(const base::FilePath& certs_dir, const std::string& cert_file, int format); diff --git a/chromium/net/test/cert_test_util_nss.cc b/chromium/net/test/cert_test_util_nss.cc new file mode 100644 index 00000000000..ee929e5a41f --- /dev/null +++ b/chromium/net/test/cert_test_util_nss.cc @@ -0,0 +1,87 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/test/cert_test_util.h" + +#include <pk11pub.h> +#include <secmodt.h> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "crypto/nss_util.h" +#include "crypto/rsa_private_key.h" +#include "net/cert/cert_type.h" + +namespace net { + +scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile( + const base::FilePath& dir, + const std::string& key_filename, + PK11SlotInfo* slot) { + base::FilePath key_path = dir.AppendASCII(key_filename); + std::string key_pkcs8; + bool success = base::ReadFileToString(key_path, &key_pkcs8); + if (!success) { + LOG(ERROR) << "Failed to read file " << key_path.value(); + return scoped_ptr<crypto::RSAPrivateKey>(); + } + + const uint8* key_pkcs8_begin = + reinterpret_cast<const uint8*>(key_pkcs8.data()); + std::vector<uint8> key_vector(key_pkcs8_begin, + key_pkcs8_begin + key_pkcs8.length()); + + scoped_ptr<crypto::RSAPrivateKey> private_key( + crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, + key_vector)); + LOG_IF(ERROR, !private_key) << "Could not create key from file " + << key_path.value(); + return private_key.Pass(); +} + +bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert, + PK11SlotInfo* slot) { + std::string nickname = cert->GetDefaultNickname(USER_CERT); + { + crypto::AutoNSSWriteLock lock; + SECStatus rv = PK11_ImportCert(slot, + cert->os_cert_handle(), + CK_INVALID_HANDLE, + nickname.c_str(), + PR_FALSE); + if (rv != SECSuccess) { + LOG(ERROR) << "Could not import cert"; + return false; + } + } + return true; +} + +scoped_refptr<X509Certificate> ImportClientCertAndKeyFromFile( + const base::FilePath& dir, + const std::string& cert_filename, + const std::string& key_filename, + PK11SlotInfo* slot) { + if (!ImportSensitiveKeyFromFile(dir, key_filename, slot)) { + LOG(ERROR) << "Could not import private key from file " << key_filename; + return NULL; + } + + scoped_refptr<X509Certificate> cert(ImportCertFromFile(dir, cert_filename)); + + if (!cert.get()) { + LOG(ERROR) << "Failed to parse cert from file " << cert_filename; + return NULL; + } + + if (!ImportClientCertToSlot(cert, slot)) + return NULL; + + // |cert| continues to point to the original X509Certificate before the + // import to |slot|. However this should not make a difference as NSS handles + // state globally. + return cert; +} + +} // namespace net diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.cc b/chromium/net/test/embedded_test_server/embedded_test_server.cc index 75b46e22166..7ac764fb708 100644 --- a/chromium/net/test/embedded_test_server/embedded_test_server.cc +++ b/chromium/net/test/embedded_test_server/embedded_test_server.cc @@ -5,10 +5,9 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "base/bind.h" -#include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/message_loop/message_loop.h" -#include "base/path_service.h" #include "base/process/process_metrics.h" #include "base/run_loop.h" #include "base/stl_util.h" @@ -32,7 +31,7 @@ class CustomHttpResponse : public HttpResponse { : headers_(headers), contents_(contents) { } - virtual std::string ToResponseString() const OVERRIDE { + std::string ToResponseString() const override { return headers_ + "\r\n" + contents_; } @@ -73,13 +72,13 @@ scoped_ptr<HttpResponse> HandleFileRequest( scoped_ptr<CustomHttpResponse> http_response( new CustomHttpResponse(headers_contents, file_contents)); - return http_response.PassAs<HttpResponse>(); + return http_response.Pass(); } scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); http_response->set_code(HTTP_OK); http_response->set_content(file_contents); - return http_response.PassAs<HttpResponse>(); + return http_response.Pass(); } } // namespace @@ -95,6 +94,18 @@ void HttpListenSocket::Listen() { TCPListenSocket::Listen(); } +void HttpListenSocket::ListenOnIOThread() { + DCHECK(thread_checker_.CalledOnValidThread()); +#if !defined(OS_POSIX) + // This method may be called after the IO thread is changed, thus we need to + // call |WatchSocket| again to make sure it listens on the current IO thread. + // Only needed for non POSIX platforms, since on POSIX platforms + // StreamListenSocket::Listen already calls WatchSocket inside the function. + WatchSocket(WAITING_ACCEPT); +#endif + Listen(); +} + HttpListenSocket::~HttpListenSocket() { DCHECK(thread_checker_.CalledOnValidThread()); } @@ -198,7 +209,7 @@ void EmbeddedTestServer::InitializeOnIOThread() { void EmbeddedTestServer::ListenOnIOThread() { DCHECK(io_thread_->message_loop_proxy()->BelongsToCurrentThread()); DCHECK(Started()); - listen_socket_->Listen(); + listen_socket_->ListenOnIOThread(); } void EmbeddedTestServer::ShutdownOnIOThread() { @@ -231,8 +242,7 @@ void EmbeddedTestServer::HandleRequest(HttpConnection* connection, << request->relative_url; scoped_ptr<BasicHttpResponse> not_found_response(new BasicHttpResponse); not_found_response->set_code(HTTP_NOT_FOUND); - connection->SendResponse( - not_found_response.PassAs<HttpResponse>()); + connection->SendResponse(not_found_response.Pass()); } // Drop the connection, since we do not support multiple requests per @@ -248,6 +258,15 @@ GURL EmbeddedTestServer::GetURL(const std::string& relative_url) const { return base_url_.Resolve(relative_url); } +GURL EmbeddedTestServer::GetURL( + const std::string& hostname, + const std::string& relative_url) const { + GURL local_url = GetURL(relative_url); + GURL::Replacements replace_host; + replace_host.SetHostStr(hostname); + return local_url.ReplaceComponents(replace_host); +} + void EmbeddedTestServer::ServeFilesFromDirectory( const base::FilePath& directory) { RegisterRequestHandler(base::Bind(&HandleFileRequest, directory)); diff --git a/chromium/net/test/embedded_test_server/embedded_test_server.h b/chromium/net/test/embedded_test_server/embedded_test_server.h index 1232388a6ca..24ff8d7a7b9 100644 --- a/chromium/net/test/embedded_test_server/embedded_test_server.h +++ b/chromium/net/test/embedded_test_server/embedded_test_server.h @@ -35,9 +35,14 @@ class HttpListenSocket : public TCPListenSocket { public: HttpListenSocket(const SocketDescriptor socket_descriptor, StreamListenSocket::Delegate* delegate); - virtual ~HttpListenSocket(); + ~HttpListenSocket() override; virtual void Listen(); + // Listen on the current IO thread. If the IO thread has changed since this + // object is constructed, call |ListenOnIOThread| to make sure it listens on + // the right thread. Otherwise must call |Listen| instead. + void ListenOnIOThread(); + private: friend class EmbeddedTestServer; @@ -101,7 +106,7 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate { // Creates a http test server. InitializeAndWaitUntilReady() must be called // to start the server. EmbeddedTestServer(); - virtual ~EmbeddedTestServer(); + ~EmbeddedTestServer() override; // Initializes and waits until the server is ready to accept requests. bool InitializeAndWaitUntilReady() WARN_UNUSED_RESULT; @@ -124,6 +129,12 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate { // http://127.0.0.1:<port>/path?query=foo. GURL GetURL(const std::string& relative_url) const; + // Similar to the above method with the difference that it uses the supplied + // |hostname| for the URL instead of 127.0.0.1. The hostname should be + // resolved to 127.0.0.1. + GURL GetURL(const std::string& hostname, + const std::string& relative_url) const; + // Returns the port number used by the server. int port() const { return port_; } @@ -161,12 +172,12 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate { scoped_ptr<HttpRequest> request); // StreamListenSocket::Delegate overrides: - virtual void DidAccept(StreamListenSocket* server, - scoped_ptr<StreamListenSocket> connection) OVERRIDE; - virtual void DidRead(StreamListenSocket* connection, - const char* data, - int length) OVERRIDE; - virtual void DidClose(StreamListenSocket* connection) OVERRIDE; + void DidAccept(StreamListenSocket* server, + scoped_ptr<StreamListenSocket> connection) override; + void DidRead(StreamListenSocket* connection, + const char* data, + int length) override; + void DidClose(StreamListenSocket* connection) override; HttpConnection* FindConnection(StreamListenSocket* socket); @@ -186,12 +197,12 @@ class EmbeddedTestServer : public StreamListenSocket::Delegate { // Vector of registered request handlers. std::vector<HandleRequestCallback> request_handlers_; + base::ThreadChecker thread_checker_; + // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<EmbeddedTestServer> weak_factory_; - base::ThreadChecker thread_checker_; - DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer); }; diff --git a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc index 9823947fb5d..28d909e6ce8 100644 --- a/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc +++ b/chromium/net/test/embedded_test_server/embedded_test_server_unittest.cc @@ -4,6 +4,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" +#include "base/path_service.h" #include "base/strings/stringprintf.h" #include "base/threading/thread.h" #include "net/http/http_response_headers.h" @@ -49,7 +50,7 @@ class EmbeddedTestServerTest: public testing::Test, io_thread_("io_thread") { } - virtual void SetUp() OVERRIDE { + void SetUp() override { base::Thread::Options thread_options; thread_options.message_loop_type = base::MessageLoop::TYPE_IO; ASSERT_TRUE(io_thread_.StartWithOptions(thread_options)); @@ -61,12 +62,12 @@ class EmbeddedTestServerTest: public testing::Test, ASSERT_TRUE(server_->InitializeAndWaitUntilReady()); } - virtual void TearDown() OVERRIDE { + void TearDown() override { ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete()); } // URLFetcherDelegate override. - virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE { + void OnURLFetchComplete(const URLFetcher* source) override { ++num_responses_received_; if (num_responses_received_ == num_responses_expected_) base::MessageLoop::current()->Quit(); @@ -95,10 +96,10 @@ class EmbeddedTestServerTest: public testing::Test, http_response->set_code(code); http_response->set_content(content); http_response->set_content_type(content_type); - return http_response.PassAs<HttpResponse>(); + return http_response.Pass(); } - return scoped_ptr<HttpResponse>(); + return nullptr; } protected: @@ -121,6 +122,12 @@ TEST_F(EmbeddedTestServerTest, GetURL) { server_->GetURL("/path?query=foo").spec()); } +TEST_F(EmbeddedTestServerTest, GetURLWithHostname) { + EXPECT_EQ(base::StringPrintf("http://foo.com:%d/path?query=foo", + server_->port()), + server_->GetURL("foo.com", "/path?query=foo").spec()); +} + TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) { server_->RegisterRequestHandler( base::Bind(&EmbeddedTestServerTest::HandleRequest, @@ -260,7 +267,7 @@ class EmbeddedTestServerThreadingTestDelegate message_loop_present_on_shutdown_(message_loop_present_on_shutdown) {} // base::PlatformThread::Delegate: - virtual void ThreadMain() OVERRIDE { + void ThreadMain() override { scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner; base::Thread io_thread("io_thread"); base::Thread::Options thread_options; @@ -298,7 +305,7 @@ class EmbeddedTestServerThreadingTestDelegate } // URLFetcherDelegate override. - virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE { + void OnURLFetchComplete(const URLFetcher* source) override { base::MessageLoop::current()->Quit(); } diff --git a/chromium/net/test/embedded_test_server/http_request.cc b/chromium/net/test/embedded_test_server/http_request.cc index f1bf302a3fd..3acb550292f 100644 --- a/chromium/net/test/embedded_test_server/http_request.cc +++ b/chromium/net/test/embedded_test_server/http_request.cc @@ -89,14 +89,16 @@ HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() { base::SplitString(header_line, ' ', &header_line_tokens); DCHECK_EQ(3u, header_line_tokens.size()); // Method. - http_request_->method = GetMethodType(StringToLowerASCII( + http_request_->method_string = header_line_tokens[0]; + http_request_->method = GetMethodType(base::StringToLowerASCII( header_line_tokens[0])); // Address. // Don't build an absolute URL as the parser does not know (should not // know) anything about the server address. http_request_->relative_url = header_line_tokens[1]; // Protocol. - const std::string protocol = StringToLowerASCII(header_line_tokens[2]); + const std::string protocol = + base::StringToLowerASCII(header_line_tokens[2]); CHECK(protocol == "http/1.0" || protocol == "http/1.1") << "Protocol not supported: " << protocol; } diff --git a/chromium/net/test/embedded_test_server/http_request.h b/chromium/net/test/embedded_test_server/http_request.h index 1e849d87d25..cb9144b1449 100644 --- a/chromium/net/test/embedded_test_server/http_request.h +++ b/chromium/net/test/embedded_test_server/http_request.h @@ -35,6 +35,7 @@ struct HttpRequest { std::string relative_url; // Starts with '/'. Example: "/test?query=foo" HttpMethod method; + std::string method_string; std::map<std::string, std::string> headers; std::string content; bool has_content; diff --git a/chromium/net/test/embedded_test_server/http_request_unittest.cc b/chromium/net/test/embedded_test_server/http_request_unittest.cc index b45742cf37b..1006e4ede90 100644 --- a/chromium/net/test/embedded_test_server/http_request_unittest.cc +++ b/chromium/net/test/embedded_test_server/http_request_unittest.cc @@ -35,6 +35,7 @@ TEST(HttpRequestTest, ParseRequest) { { scoped_ptr<HttpRequest> request = parser.GetRequest(); EXPECT_EQ("/foobar.html", request->relative_url); + EXPECT_EQ("POST", request->method_string); EXPECT_EQ(METHOD_POST, request->method); EXPECT_EQ("1234567890", request->content); ASSERT_EQ(3u, request->headers.size()); @@ -78,5 +79,19 @@ TEST(HttpRequestTest, ParseRequestWithoutBody) { EXPECT_FALSE(request->has_content); } +TEST(HttpRequestTest, ParseGet) { + HttpRequestParser parser; + + parser.ProcessChunk("GET /foobar.html HTTP/1.1\r\n\r\n"); + ASSERT_EQ(HttpRequestParser::ACCEPTED, parser.ParseRequest()); + + scoped_ptr<HttpRequest> request = parser.GetRequest(); + EXPECT_EQ("/foobar.html", request->relative_url); + EXPECT_EQ("GET", request->method_string); + EXPECT_EQ(METHOD_GET, request->method); + EXPECT_EQ("", request->content); + EXPECT_FALSE(request->has_content); +} + } // namespace test_server } // namespace net diff --git a/chromium/net/test/embedded_test_server/http_response.h b/chromium/net/test/embedded_test_server/http_response.h index 422a52553ea..821c02757dc 100644 --- a/chromium/net/test/embedded_test_server/http_response.h +++ b/chromium/net/test/embedded_test_server/http_response.h @@ -32,7 +32,7 @@ class HttpResponse{ class BasicHttpResponse : public HttpResponse { public: BasicHttpResponse(); - virtual ~BasicHttpResponse(); + ~BasicHttpResponse() override; // The response code. HttpStatusCode code() const { return code_; } @@ -54,7 +54,7 @@ class BasicHttpResponse : public HttpResponse { } // Generates and returns a http response string. - virtual std::string ToResponseString() const OVERRIDE; + std::string ToResponseString() const override; private: HttpStatusCode code_; diff --git a/chromium/net/test/net_test_suite.cc b/chromium/net/test/net_test_suite.cc index 2d13877e803..ed8a103ac1e 100644 --- a/chromium/net/test/net_test_suite.cc +++ b/chromium/net/test/net_test_suite.cc @@ -1,67 +1,67 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/test/net_test_suite.h"
-
-#include "base/message_loop/message_loop.h"
-#include "net/base/network_change_notifier.h"
-#include "net/http/http_stream_factory.h"
-#include "net/spdy/spdy_session.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(USE_NSS) || defined(OS_IOS)
-#include "net/ocsp/nss_ocsp.h"
-#endif
-
-class StaticReset : public ::testing::EmptyTestEventListener {
- virtual void OnTestStart(const ::testing::TestInfo& test_info) OVERRIDE {
- net::HttpStreamFactory::ResetStaticSettingsToInit();
- }
-};
-
-NetTestSuite::NetTestSuite(int argc, char** argv)
- : TestSuite(argc, argv) {
-}
-
-NetTestSuite::NetTestSuite(int argc, char** argv,
- bool create_at_exit_manager)
- : TestSuite(argc, argv, create_at_exit_manager) {
-}
-
-NetTestSuite::~NetTestSuite() {}
-
-void NetTestSuite::Initialize() {
- TestSuite::Initialize();
- ::testing::UnitTest::GetInstance()->listeners().Append(new StaticReset());
- InitializeTestThread();
-}
-
-void NetTestSuite::Shutdown() {
-#if defined(USE_NSS) || defined(OS_IOS)
- net::ShutdownNSSHttpIO();
-#endif
-
- // We want to destroy this here before the TestSuite continues to tear down
- // the environment.
- message_loop_.reset();
-
- TestSuite::Shutdown();
-}
-
-void NetTestSuite::InitializeTestThread() {
- network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock());
-
- InitializeTestThreadNoNetworkChangeNotifier();
-}
-
-void NetTestSuite::InitializeTestThreadNoNetworkChangeNotifier() {
- host_resolver_proc_ = new net::RuleBasedHostResolverProc(NULL);
- scoped_host_resolver_proc_.Init(host_resolver_proc_.get());
- // In case any attempts are made to resolve host names, force them all to
- // be mapped to localhost. This prevents DNS queries from being sent in
- // the process of running these unit tests.
- host_resolver_proc_->AddRule("*", "127.0.0.1");
-
- message_loop_.reset(new base::MessageLoopForIO());
-}
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/test/net_test_suite.h" + +#include "base/message_loop/message_loop.h" +#include "net/base/network_change_notifier.h" +#include "net/http/http_stream_factory.h" +#include "net/spdy/spdy_session.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(USE_NSS) || defined(OS_IOS) +#include "net/ocsp/nss_ocsp.h" +#endif + +class StaticReset : public ::testing::EmptyTestEventListener { + virtual void OnTestStart(const ::testing::TestInfo& test_info) override { + net::HttpStreamFactory::ResetStaticSettingsToInit(); + } +}; + +NetTestSuite::NetTestSuite(int argc, char** argv) + : TestSuite(argc, argv) { +} + +NetTestSuite::NetTestSuite(int argc, char** argv, + bool create_at_exit_manager) + : TestSuite(argc, argv, create_at_exit_manager) { +} + +NetTestSuite::~NetTestSuite() {} + +void NetTestSuite::Initialize() { + TestSuite::Initialize(); + ::testing::UnitTest::GetInstance()->listeners().Append(new StaticReset()); + InitializeTestThread(); +} + +void NetTestSuite::Shutdown() { +#if defined(USE_NSS) || defined(OS_IOS) + net::ShutdownNSSHttpIO(); +#endif + + // We want to destroy this here before the TestSuite continues to tear down + // the environment. + message_loop_.reset(); + + TestSuite::Shutdown(); +} + +void NetTestSuite::InitializeTestThread() { + network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock()); + + InitializeTestThreadNoNetworkChangeNotifier(); +} + +void NetTestSuite::InitializeTestThreadNoNetworkChangeNotifier() { + host_resolver_proc_ = new net::RuleBasedHostResolverProc(NULL); + scoped_host_resolver_proc_.Init(host_resolver_proc_.get()); + // In case any attempts are made to resolve host names, force them all to + // be mapped to localhost. This prevents DNS queries from being sent in + // the process of running these unit tests. + host_resolver_proc_->AddRule("*", "127.0.0.1"); + + message_loop_.reset(new base::MessageLoopForIO()); +} diff --git a/chromium/net/test/net_test_suite.h b/chromium/net/test/net_test_suite.h index c8479d724ed..e0f601eb887 100644 --- a/chromium/net/test/net_test_suite.h +++ b/chromium/net/test/net_test_suite.h @@ -21,11 +21,11 @@ class NetworkChangeNotifier; class NetTestSuite : public base::TestSuite { public: NetTestSuite(int argc, char** argv); - virtual ~NetTestSuite(); + ~NetTestSuite() override; - virtual void Initialize() OVERRIDE; + void Initialize() override; - virtual void Shutdown() OVERRIDE; + void Shutdown() override; protected: // This constructor is only accessible to specialized net test diff --git a/chromium/net/test/python_utils.cc b/chromium/net/test/python_utils.cc index 2555c55c264..7e40faefe83 100644 --- a/chromium/net/test/python_utils.cc +++ b/chromium/net/test/python_utils.cc @@ -7,8 +7,8 @@ #include "base/base_paths.h" #include "base/command_line.h" #include "base/environment.h" -#include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/path_service.h" @@ -109,14 +109,8 @@ bool GetPyProtoPath(base::FilePath* dir) { bool GetPythonCommand(base::CommandLine* python_cmd) { DCHECK(python_cmd); -#if defined(OS_WIN) - // This permits finding the proper python in path even if it is a .bat file. - python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("cmd.exe"))); - python_cmd->AppendArg("/c"); - python_cmd->AppendArg("python"); -#else python_cmd->SetProgram(base::FilePath(FILE_PATH_LITERAL("python"))); -#endif // defined(OS_WIN) + // Launch python in unbuffered mode, so that python output doesn't mix with // gtest output in buildbot log files. See http://crbug.com/147368. python_cmd->AppendArg("-u"); diff --git a/chromium/net/test/run_all_unittests.cc b/chromium/net/test/run_all_unittests.cc index 96e8a3c8346..e86487e6fed 100644 --- a/chromium/net/test/run_all_unittests.cc +++ b/chromium/net/test/run_all_unittests.cc @@ -23,6 +23,10 @@ #include "net/proxy/proxy_resolver_v8.h" #endif +#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#include "gin/public/isolate_holder.h" +#endif + using net::internal::ClientSocketPoolBaseHelper; using net::SpdySession; @@ -33,7 +37,7 @@ int main(int argc, char** argv) { #if defined(OS_ANDROID) const base::android::RegistrationMethod kNetTestRegisteredMethods[] = { {"NetAndroid", net::android::RegisterJni}, - {"TestFileUtil", file_util::RegisterContentUriTestUtils}, + {"TestFileUtil", base::RegisterContentUriTestUtils}, {"UrlAndroid", url::android::RegisterJni}, }; @@ -48,7 +52,7 @@ int main(int argc, char** argv) { NetTestSuite test_suite(argc, argv); ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); -#if defined(OS_WIN) +#if defined(OS_WIN) && !defined(USE_OPENSSL) // We want to be sure to init NSPR on the main thread. crypto::EnsureNSPRInit(); #endif @@ -57,6 +61,10 @@ int main(int argc, char** argv) { // single-threaded. net::EnableSSLServerSockets(); +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + gin::IsolateHolder::LoadV8Snapshot(); +#endif + #if !defined(OS_IOS) net::ProxyResolverV8::EnsureIsolateCreated(); #endif diff --git a/chromium/net/test/spawned_test_server/base_test_server.cc b/chromium/net/test/spawned_test_server/base_test_server.cc index 016c9301edf..0e23c7a3b55 100644 --- a/chromium/net/test/spawned_test_server/base_test_server.cc +++ b/chromium/net/test/spawned_test_server/base_test_server.cc @@ -8,7 +8,7 @@ #include <vector> #include "base/base64.h" -#include "base/file_util.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/path_service.h" @@ -72,6 +72,21 @@ void GetCiphersList(int cipher, base::ListValue* values) { values->Append(new base::StringValue("3des")); } +base::StringValue* GetTLSIntoleranceType( + BaseTestServer::SSLOptions::TLSIntoleranceType type) { + switch (type) { + case BaseTestServer::SSLOptions::TLS_INTOLERANCE_ALERT: + return new base::StringValue("alert"); + case BaseTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE: + return new base::StringValue("close"); + case BaseTestServer::SSLOptions::TLS_INTOLERANCE_RESET: + return new base::StringValue("reset"); + default: + NOTREACHED(); + return new base::StringValue(""); + } +} + } // namespace BaseTestServer::SSLOptions::SSLOptions() @@ -83,9 +98,12 @@ BaseTestServer::SSLOptions::SSLOptions() bulk_ciphers(SSLOptions::BULK_CIPHER_ANY), record_resume(false), tls_intolerant(TLS_INTOLERANT_NONE), + tls_intolerance_type(TLS_INTOLERANCE_ALERT), fallback_scsv_enabled(false), staple_ocsp_response(false), - enable_npn(false) {} + enable_npn(false), + disable_session_cache(false) { +} BaseTestServer::SSLOptions::SSLOptions( BaseTestServer::SSLOptions::ServerCertificate cert) @@ -97,9 +115,12 @@ BaseTestServer::SSLOptions::SSLOptions( bulk_ciphers(SSLOptions::BULK_CIPHER_ANY), record_resume(false), tls_intolerant(TLS_INTOLERANT_NONE), + tls_intolerance_type(TLS_INTOLERANCE_ALERT), fallback_scsv_enabled(false), staple_ocsp_response(false), - enable_npn(false) {} + enable_npn(false), + disable_session_cache(false) { +} BaseTestServer::SSLOptions::~SSLOptions() {} @@ -148,7 +169,8 @@ const char BaseTestServer::kLocalhost[] = "127.0.0.1"; BaseTestServer::BaseTestServer(Type type, const std::string& host) : type_(type), started_(false), - log_to_console_(false) { + log_to_console_(false), + ws_basic_auth_(false) { Init(host); } @@ -156,7 +178,8 @@ BaseTestServer::BaseTestServer(Type type, const SSLOptions& ssl_options) : ssl_options_(ssl_options), type_(type), started_(false), - log_to_console_(false) { + log_to_console_(false), + ws_basic_auth_(false) { DCHECK(UsingSSL(type)); Init(GetHostname(type, ssl_options)); } @@ -367,6 +390,11 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const { if (VLOG_IS_ON(1) || log_to_console_) arguments->Set("log-to-console", base::Value::CreateNullValue()); + if (ws_basic_auth_) { + DCHECK(type_ == TYPE_WS || type_ == TYPE_WSS); + arguments->Set("ws-basic-auth", base::Value::CreateNullValue()); + } + if (UsingSSL(type_)) { // Check the certificate arguments of the HTTPS server. base::FilePath certificate_path(certificates_dir_); @@ -418,8 +446,7 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const { arguments->SetString("ocsp", ocsp_arg); if (ssl_options_.cert_serial != 0) { - arguments->Set("cert-serial", - base::Value::CreateIntegerValue(ssl_options_.cert_serial)); + arguments->SetInteger("cert-serial", ssl_options_.cert_serial); } // Check key exchange argument. @@ -435,8 +462,9 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const { if (ssl_options_.record_resume) arguments->Set("https-record-resume", base::Value::CreateNullValue()); if (ssl_options_.tls_intolerant != SSLOptions::TLS_INTOLERANT_NONE) { - arguments->Set("tls-intolerant", - new base::FundamentalValue(ssl_options_.tls_intolerant)); + arguments->SetInteger("tls-intolerant", ssl_options_.tls_intolerant); + arguments->Set("tls-intolerance-type", GetTLSIntoleranceType( + ssl_options_.tls_intolerance_type)); } if (ssl_options_.fallback_scsv_enabled) arguments->Set("fallback-scsv", base::Value::CreateNullValue()); @@ -450,6 +478,8 @@ bool BaseTestServer::GenerateArguments(base::DictionaryValue* arguments) const { arguments->Set("staple-ocsp-response", base::Value::CreateNullValue()); if (ssl_options_.enable_npn) arguments->Set("enable-npn", base::Value::CreateNullValue()); + if (ssl_options_.disable_session_cache) + arguments->Set("disable-session-cache", base::Value::CreateNullValue()); } return GenerateAdditionalArguments(arguments); diff --git a/chromium/net/test/spawned_test_server/base_test_server.h b/chromium/net/test/spawned_test_server/base_test_server.h index 5c47ebc05a3..45ea1cecffa 100644 --- a/chromium/net/test/spawned_test_server/base_test_server.h +++ b/chromium/net/test/spawned_test_server/base_test_server.h @@ -111,6 +111,14 @@ class BaseTestServer { TLS_INTOLERANT_TLS1_2 = 3, // Intolerant of TLS 1.2 or higher. }; + // Values which control how the server reacts in response to a ClientHello + // it is intolerant of. + enum TLSIntoleranceType { + TLS_INTOLERANCE_ALERT = 0, // Send a handshake_failure alert. + TLS_INTOLERANCE_CLOSE = 1, // Close the connection. + TLS_INTOLERANCE_RESET = 2, // Send a TCP reset. + }; + // Initialize a new SSLOptions using CERT_OK as the certificate. SSLOptions(); @@ -171,6 +179,10 @@ class BaseTestServer { // negotiates an intolerant TLS version in order to test version fallback. TLSIntolerantLevel tls_intolerant; + // If |tls_intolerant| is not TLS_INTOLERANT_NONE, how the server reacts to + // an intolerant TLS version. + TLSIntoleranceType tls_intolerance_type; + // fallback_scsv_enabled, if true, causes the server to process the // TLS_FALLBACK_SCSV cipher suite. This cipher suite is sent by Chrome // when performing TLS version fallback in response to an SSL handshake @@ -191,6 +203,11 @@ class BaseTestServer { // Whether to enable NPN support. bool enable_npn; + + // Whether to disable TLS session caching. When session caching is + // disabled, the server will use an empty session ID in the + // ServerHello. + bool disable_session_cache; }; // Pass as the 'host' parameter during construction to server on 127.0.0.1 @@ -230,6 +247,12 @@ class BaseTestServer { type == BaseTestServer::TYPE_WSS; } + // Enable HTTP basic authentication. Currently this only works for TYPE_WS and + // TYPE_WSS. + void set_websocket_basic_auth(bool ws_basic_auth) { + ws_basic_auth_ = ws_basic_auth; + } + protected: virtual ~BaseTestServer(); Type type() const { return type_; } @@ -296,6 +319,9 @@ class BaseTestServer { // Enables logging of the server to the console. bool log_to_console_; + // Is WebSocket basic HTTP authentication enabled? + bool ws_basic_auth_; + scoped_ptr<ScopedPortException> allowed_port_; DISALLOW_COPY_AND_ASSIGN(BaseTestServer); diff --git a/chromium/net/test/spawned_test_server/local_test_server.cc b/chromium/net/test/spawned_test_server/local_test_server.cc index 6516136cea9..c85e05a8dec 100644 --- a/chromium/net/test/spawned_test_server/local_test_server.cc +++ b/chromium/net/test/spawned_test_server/local_test_server.cc @@ -124,11 +124,6 @@ bool LocalTestServer::Stop() { if (!process_handle_) return true; -#if defined(OS_WIN) - // This kills all the processes in the job object. - job_handle_.Close(); -#endif - // First check if the process has already terminated. bool ret = base::WaitForSingleProcess(process_handle_, base::TimeDelta()); if (!ret) { diff --git a/chromium/net/test/spawned_test_server/local_test_server.h b/chromium/net/test/spawned_test_server/local_test_server.h index 334c4344c89..37b118588a5 100644 --- a/chromium/net/test/spawned_test_server/local_test_server.h +++ b/chromium/net/test/spawned_test_server/local_test_server.h @@ -7,7 +7,7 @@ #include <string> -#include "base/file_util.h" +#include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/process/process_handle.h" #include "net/test/spawned_test_server/base_test_server.h" @@ -38,7 +38,7 @@ class LocalTestServer : public BaseTestServer { const SSLOptions& ssl_options, const base::FilePath& document_root); - virtual ~LocalTestServer(); + ~LocalTestServer() override; // Start the test server and block until it's ready. Returns true on success. bool Start() WARN_UNUSED_RESULT; @@ -96,9 +96,6 @@ class LocalTestServer : public BaseTestServer { base::ProcessHandle process_handle_; #if defined(OS_WIN) - // JobObject used to clean up orphaned child processes. - base::win::ScopedHandle job_handle_; - // The pipe file handle we read from. base::win::ScopedHandle child_read_fd_; diff --git a/chromium/net/test/spawned_test_server/local_test_server_posix.cc b/chromium/net/test/spawned_test_server/local_test_server_posix.cc index 67911ed68d0..0edbedf1e42 100644 --- a/chromium/net/test/spawned_test_server/local_test_server_posix.cc +++ b/chromium/net/test/spawned_test_server/local_test_server_posix.cc @@ -9,7 +9,7 @@ #include <vector> #include "base/command_line.h" -#include "base/file_util.h" +#include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/process/kill.h" @@ -34,7 +34,7 @@ class OrphanedTestServerFilter : public base::ProcessFilter { : path_string_(path_string), port_string_(port_string) {} - virtual bool Includes(const base::ProcessEntry& entry) const OVERRIDE { + bool Includes(const base::ProcessEntry& entry) const override { if (entry.parent_pid() != 1) return false; bool found_path_string = false; diff --git a/chromium/net/test/spawned_test_server/local_test_server_win.cc b/chromium/net/test/spawned_test_server/local_test_server_win.cc index 726a5810c0d..412e4e10c80 100644 --- a/chromium/net/test/spawned_test_server/local_test_server_win.cc +++ b/chromium/net/test/spawned_test_server/local_test_server_win.cc @@ -5,7 +5,6 @@ #include "net/test/spawned_test_server/local_test_server.h" #include <windows.h> -#include <wincrypt.h> #include "base/base_paths.h" #include "base/bind.h" @@ -13,7 +12,6 @@ #include "base/environment.h" #include "base/files/file_path.h" #include "base/message_loop/message_loop.h" -#include "base/path_service.h" #include "base/process/launch.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -23,8 +21,6 @@ #include "base/win/scoped_handle.h" #include "net/test/python_utils.h" -#pragma comment(lib, "crypt32.lib") - namespace { // Writes |size| bytes to |handle| and sets |*unblocked| to true. @@ -178,21 +174,8 @@ bool LocalTestServer::LaunchPython(const base::FilePath& testserver_path) { python_command.AppendArg("--startup-pipe=" + base::IntToString(reinterpret_cast<uintptr_t>(child_write))); - job_handle_.Set(CreateJobObject(NULL, NULL)); - if (!job_handle_.IsValid()) { - LOG(ERROR) << "Could not create JobObject."; - return false; - } - - if (!base::SetJobObjectLimitFlags(job_handle_.Get(), - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE)) { - LOG(ERROR) << "Could not SetJobObjectLimitFlags."; - return false; - } - base::LaunchOptions launch_options; launch_options.inherit_handles = true; - launch_options.job_handle = job_handle_.Get(); if (!base::LaunchProcess(python_command, launch_options, &process_handle_)) { LOG(ERROR) << "Failed to launch " << python_command.GetCommandLineString(); return false; diff --git a/chromium/net/test/spawned_test_server/remote_test_server.cc b/chromium/net/test/spawned_test_server/remote_test_server.cc index 13286a9b838..6d098c8f49c 100644 --- a/chromium/net/test/spawned_test_server/remote_test_server.cc +++ b/chromium/net/test/spawned_test_server/remote_test_server.cc @@ -7,8 +7,8 @@ #include <vector> #include "base/base_paths.h" -#include "base/file_util.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/logging.h" #include "base/path_service.h" diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.cc b/chromium/net/test/spawned_test_server/spawner_communicator.cc index d7736b8d77b..53484ead585 100644 --- a/chromium/net/test/spawned_test_server/spawner_communicator.cc +++ b/chromium/net/test/spawned_test_server/spawner_communicator.cc @@ -12,10 +12,10 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" +#include "net/base/elements_upload_data_stream.h" #include "net/base/net_util.h" #include "net/base/request_priority.h" #include "net/base/upload_bytes_element_reader.h" -#include "net/base/upload_data_stream.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request_test_util.h" #include "url/gurl.h" @@ -103,8 +103,8 @@ SpawnerCommunicator::SpawnerCommunicator(uint16 port) event_(false, false), port_(port), next_id_(0), - weak_factory_(this), - is_running_(false) {} + is_running_(false), + weak_factory_(this) {} SpawnerCommunicator::~SpawnerCommunicator() { DCHECK(!is_running_); @@ -188,10 +188,10 @@ void SpawnerCommunicator::SendCommandAndWaitForResultOnIOThread( cur_request_->set_method("POST"); scoped_ptr<UploadElementReader> reader( UploadOwnedBytesElementReader::CreateWithString(post_data)); - cur_request_->set_upload(make_scoped_ptr( - UploadDataStream::CreateWithReader(reader.Pass(), 0))); - net::HttpRequestHeaders headers; - headers.SetHeader(net::HttpRequestHeaders::kContentType, + cur_request_->set_upload( + ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); + HttpRequestHeaders headers; + headers.SetHeader(HttpRequestHeaders::kContentType, "application/json"); cur_request_->SetExtraRequestHeaders(headers); } diff --git a/chromium/net/test/spawned_test_server/spawner_communicator.h b/chromium/net/test/spawned_test_server/spawner_communicator.h index bf426e63502..549ad9158c5 100644 --- a/chromium/net/test/spawned_test_server/spawner_communicator.h +++ b/chromium/net/test/spawned_test_server/spawner_communicator.h @@ -100,8 +100,8 @@ class SpawnerCommunicator : public net::URLRequest::Delegate { std::string* data_received); // URLRequest::Delegate methods. Called on the IO thread. - virtual void OnResponseStarted(URLRequest* request) OVERRIDE; - virtual void OnReadCompleted(URLRequest* request, int num_bytes) OVERRIDE; + virtual void OnResponseStarted(URLRequest* request) override; + virtual void OnReadCompleted(URLRequest* request, int num_bytes) override; // Reads Result from the response. Called on the IO thread. void ReadResult(URLRequest* request); @@ -130,10 +130,6 @@ class SpawnerCommunicator : public net::URLRequest::Delegate { // The next ID to use for |cur_request_| (monotonically increasing). int next_id_; - // Factory for creating the time-out task. This takes care of revoking - // outstanding tasks when |this| is deleted. - base::WeakPtrFactory<SpawnerCommunicator> weak_factory_; - // Request context used by |cur_request_|. scoped_ptr<URLRequestContext> context_; @@ -143,6 +139,10 @@ class SpawnerCommunicator : public net::URLRequest::Delegate { // Only gets/sets |is_running_| on user's thread to avoid race-condition. bool is_running_; + // Factory for creating the time-out task. This takes care of revoking + // outstanding tasks when |this| is deleted. + base::WeakPtrFactory<SpawnerCommunicator> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(SpawnerCommunicator); }; diff --git a/chromium/net/test/url_request/url_request_failed_job.cc b/chromium/net/test/url_request/url_request_failed_job.cc new file mode 100644 index 00000000000..c13c3c8c443 --- /dev/null +++ b/chromium/net/test/url_request/url_request_failed_job.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/test/url_request/url_request_failed_job.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/string_number_conversions.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_filter.h" + +namespace net { +namespace { + +const char kMockHostname[] = "mock.failed.request"; + +// Gets the numeric net error code from URL of the form: +// scheme://kMockHostname/error_code. The error code must be a valid +// net error code, and not net::OK or net::ERR_IO_PENDING. +int GetErrorCode(net::URLRequest* request) { + int net_error; + std::string path = request->url().path(); + if (path[0] == '/' && base::StringToInt(path.c_str() + 1, &net_error)) { + CHECK_LT(net_error, 0); + CHECK_NE(net_error, net::ERR_IO_PENDING); + return net_error; + } + NOTREACHED(); + return net::ERR_UNEXPECTED; +} + +GURL GetMockUrl(const std::string& scheme, + const std::string& hostname, + int net_error) { + CHECK_LT(net_error, 0); + CHECK_NE(net_error, net::ERR_IO_PENDING); + return GURL(scheme + "://" + hostname + "/" + base::IntToString(net_error)); +} + +} // namespace + +URLRequestFailedJob::URLRequestFailedJob(net::URLRequest* request, + net::NetworkDelegate* network_delegate, + int net_error) + : net::URLRequestJob(request, network_delegate), + net_error_(net_error), + weak_factory_(this) {} + +void URLRequestFailedJob::Start() { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&URLRequestFailedJob::StartAsync, weak_factory_.GetWeakPtr())); +} + +// static +void URLRequestFailedJob::AddUrlHandler() { + return AddUrlHandlerForHostname(kMockHostname); +} + +// static +void URLRequestFailedJob::AddUrlHandlerForHostname( + const std::string& hostname) { + // Add |hostname| to net::URLRequestFilter for HTTP and HTTPS. + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->AddHostnameHandler("http", hostname, URLRequestFailedJob::Factory); + filter->AddHostnameHandler("https", hostname, URLRequestFailedJob::Factory); +} + +// static +GURL URLRequestFailedJob::GetMockHttpUrl(int net_error) { + return GetMockHttpUrlForHostname(net_error, kMockHostname); +} + +// static +GURL URLRequestFailedJob::GetMockHttpsUrl(int net_error) { + return GetMockHttpsUrlForHostname(net_error, kMockHostname); +} + +// static +GURL URLRequestFailedJob::GetMockHttpUrlForHostname( + int net_error, const std::string& hostname) { + return GetMockUrl("http", hostname, net_error); +} + +// static +GURL URLRequestFailedJob::GetMockHttpsUrlForHostname( + int net_error, const std::string& hostname) { + return GetMockUrl("https", hostname, net_error); +} + +URLRequestFailedJob::~URLRequestFailedJob() {} + +// static +net::URLRequestJob* URLRequestFailedJob::Factory( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + const std::string& scheme) { + return new URLRequestFailedJob( + request, network_delegate, GetErrorCode(request)); +} + +void URLRequestFailedJob::StartAsync() { + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, + net_error_)); +} + +} // namespace net diff --git a/chromium/net/test/url_request/url_request_failed_job.h b/chromium/net/test/url_request/url_request_failed_job.h new file mode 100644 index 00000000000..4307f91b80b --- /dev/null +++ b/chromium/net/test/url_request/url_request_failed_job.h @@ -0,0 +1,64 @@ +// 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. + +#ifndef NET_TEST_URL_REQUEST_URL_REQUEST_FAILED_JOB_H_ +#define NET_TEST_URL_REQUEST_URL_REQUEST_FAILED_JOB_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" +#include "net/url_request/url_request_job.h" +#include "url/gurl.h" + +namespace net { + +// This class simulates a URLRequestJob failing with a given error code while +// trying to connect. +class URLRequestFailedJob : public URLRequestJob { + public: + URLRequestFailedJob(URLRequest* request, + NetworkDelegate* network_delegate, + int net_error); + + void Start() override; + + // Adds the testing URLs to the URLRequestFilter. + static void AddUrlHandler(); + static void AddUrlHandlerForHostname(const std::string& hostname); + + // Given a net error code, constructs a mock URL that will return that error + // asynchronously when started. |net_error| must be a valid net error code + // other than net::OK and net::ERR_IO_PENDING. + static GURL GetMockHttpUrl(int net_error); + static GURL GetMockHttpsUrl(int net_error); + + // URLRequestFailedJob must be added as a handler for |hostname| for + // the returned URL to return |net_error|. + static GURL GetMockHttpUrlForHostname(int net_error, + const std::string& hostname); + static GURL GetMockHttpsUrlForHostname(int net_error, + const std::string& hostname); + + protected: + ~URLRequestFailedJob() override; + + private: + static URLRequestJob* Factory(URLRequest* request, + NetworkDelegate* network_delegate, + const std::string& scheme); + + // Simulate a failure. + void StartAsync(); + + const int net_error_; + + base::WeakPtrFactory<URLRequestFailedJob> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestFailedJob); +}; + +} // namespace net + +#endif // NET_TEST_URL_REQUEST_URL_REQUEST_FAILED_JOB_H_ diff --git a/chromium/net/test/url_request/url_request_mock_http_job.cc b/chromium/net/test/url_request/url_request_mock_http_job.cc new file mode 100644 index 00000000000..ede87cfeabd --- /dev/null +++ b/chromium/net/test/url_request/url_request_mock_http_job.cc @@ -0,0 +1,286 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/test/url_request/url_request_mock_http_job.h" + +#include "base/files/file_util.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" +#include "base/threading/thread_restrictions.h" +#include "net/base/filename_util.h" +#include "net/base/net_errors.h" +#include "net/base/url_util.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_interceptor.h" + +namespace net { + +namespace { + +const char kMockHostname[] = "mock.http"; +const base::FilePath::CharType kMockHeaderFileSuffix[] = + FILE_PATH_LITERAL(".mock-http-headers"); + +// String names of failure phases matching FailurePhase enum. +const char* kFailurePhase[] { + "start", // START + "readasync", // READ_ASYNC + "readsync", // READ_SYNC +}; + +class MockJobInterceptor : public net::URLRequestInterceptor { + public: + // When |map_all_requests_to_base_path| is true, all request should return the + // contents of the file at |base_path|. When |map_all_requests_to_base_path| + // is false, |base_path| is the file path leading to the root of the directory + // to use as the root of the HTTP server. + MockJobInterceptor( + const base::FilePath& base_path, + bool map_all_requests_to_base_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) + : base_path_(base_path), + map_all_requests_to_base_path_(map_all_requests_to_base_path), + worker_pool_(worker_pool) {} + ~MockJobInterceptor() override {} + + // net::URLRequestJobFactory::ProtocolHandler implementation + net::URLRequestJob* MaybeInterceptRequest( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const override { + return new URLRequestMockHTTPJob( + request, + network_delegate, + map_all_requests_to_base_path_ ? base_path_ : GetOnDiskPath(request), + worker_pool_->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); + } + + private: + base::FilePath GetOnDiskPath(net::URLRequest* request) const { + // Conceptually we just want to "return base_path_ + request->url().path()". + // But path in the request URL is in URL space (i.e. %-encoded spaces). + // So first we convert base FilePath to a URL, then append the URL + // path to that, and convert the final URL back to a FilePath. + GURL file_url(net::FilePathToFileURL(base_path_)); + std::string url = file_url.spec() + request->url().path(); + base::FilePath file_path; + net::FileURLToFilePath(GURL(url), &file_path); + return file_path; + } + + const base::FilePath base_path_; + const bool map_all_requests_to_base_path_; + const scoped_refptr<base::SequencedWorkerPool> worker_pool_; + + DISALLOW_COPY_AND_ASSIGN(MockJobInterceptor); +}; + +std::string DoFileIO(const base::FilePath& file_path) { + base::FilePath header_file = + base::FilePath(file_path.value() + kMockHeaderFileSuffix); + + if (!base::PathExists(header_file)) { + // If there is no mock-http-headers file, fake a 200 OK. + return "HTTP/1.0 200 OK\n"; + } + + std::string raw_headers; + base::ReadFileToString(header_file, &raw_headers); + return raw_headers; +} + +} // namespace + +// static +void URLRequestMockHTTPJob::AddUrlHandler( + const base::FilePath& base_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { + // Add kMockHostname to net::URLRequestFilter. + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->AddHostnameInterceptor( + "http", kMockHostname, CreateInterceptor(base_path, worker_pool)); +} + +// static +void URLRequestMockHTTPJob::AddHostnameToFileHandler( + const std::string& hostname, + const base::FilePath& file, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { + net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); + filter->AddHostnameInterceptor( + "http", hostname, CreateInterceptorForSingleFile(file, worker_pool)); +} + +// static +GURL URLRequestMockHTTPJob::GetMockUrl(const base::FilePath& path) { + std::string url = "http://"; + url.append(kMockHostname); + url.append("/"); + std::string path_str = path.MaybeAsASCII(); + DCHECK(!path_str.empty()); // We only expect ASCII paths in tests. + url.append(path_str); + return GURL(url); +} + +// static +GURL URLRequestMockHTTPJob::GetMockUrlWithFailure(const base::FilePath& path, + FailurePhase phase, + int net_error) { + COMPILE_ASSERT(arraysize(kFailurePhase) == MAX_FAILURE_PHASE, + kFailurePhase_must_match_FailurePhase_enum); + DCHECK_GE(phase, START); + DCHECK_LE(phase, READ_SYNC); + std::string url(GetMockUrl(path).spec()); + url.append("?"); + url.append(kFailurePhase[phase]); + url.append("="); + url.append(base::IntToString(net_error)); + return GURL(url); +} + +// static +scoped_ptr<net::URLRequestInterceptor> URLRequestMockHTTPJob::CreateInterceptor( + const base::FilePath& base_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { + return scoped_ptr<net::URLRequestInterceptor>( + new MockJobInterceptor(base_path, false, worker_pool)); +} + +// static +scoped_ptr<net::URLRequestInterceptor> +URLRequestMockHTTPJob::CreateInterceptorForSingleFile( + const base::FilePath& file, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool) { + return scoped_ptr<net::URLRequestInterceptor>( + new MockJobInterceptor(file, true, worker_pool)); +} + +URLRequestMockHTTPJob::URLRequestMockHTTPJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + const base::FilePath& file_path, + const scoped_refptr<base::TaskRunner>& task_runner) + : net::URLRequestFileJob(request, network_delegate, file_path, task_runner), + task_runner_(task_runner), + weak_ptr_factory_(this) { +} + +URLRequestMockHTTPJob::~URLRequestMockHTTPJob() { +} + +// Public virtual version. +void URLRequestMockHTTPJob::GetResponseInfo(net::HttpResponseInfo* info) { + // Forward to private const version. + GetResponseInfoConst(info); +} + +bool URLRequestMockHTTPJob::IsRedirectResponse(GURL* location, + int* http_status_code) { + // Override the net::URLRequestFileJob implementation to invoke the default + // one based on HttpResponseInfo. + return net::URLRequestJob::IsRedirectResponse(location, http_status_code); +} + +// Public virtual version. +void URLRequestMockHTTPJob::Start() { + if (MaybeReportErrorOnPhase(START)) + return; + base::PostTaskAndReplyWithResult( + task_runner_.get(), + FROM_HERE, + base::Bind(&DoFileIO, file_path_), + base::Bind(&URLRequestMockHTTPJob::SetHeadersAndStart, + weak_ptr_factory_.GetWeakPtr())); +} + +// Public virtual version. +bool URLRequestMockHTTPJob::ReadRawData(IOBuffer* buf, + int buf_size, + int* bytes_read) { + if (MaybeReportErrorOnPhase(READ_SYNC)) + return false; + if (MaybeReportErrorOnPhase(READ_ASYNC)) + return false; + return URLRequestFileJob::ReadRawData(buf, buf_size, bytes_read); +} + +void URLRequestMockHTTPJob::SetHeadersAndStart(const std::string& raw_headers) { + if (MaybeReportErrorOnPhase(START)) + return; + raw_headers_ = raw_headers; + // Handle CRLF line-endings. + ReplaceSubstringsAfterOffset(&raw_headers_, 0, "\r\n", "\n"); + // ParseRawHeaders expects \0 to end each header line. + ReplaceSubstringsAfterOffset(&raw_headers_, 0, "\n", std::string("\0", 1)); + URLRequestFileJob::Start(); +} + +bool URLRequestMockHTTPJob::MaybeReportErrorOnPhase( + FailurePhase current_phase) { + DCHECK_GE(current_phase, START); + DCHECK_LE(current_phase, READ_SYNC); + std::string phase_key(kFailurePhase[current_phase]); + std::string phase_error_string; + if (!GetValueForKeyInQuery(request_->url(), phase_key, &phase_error_string)) + return false; + + int net_error; + if (!base::StringToInt(phase_error_string, &net_error)) + return false; + + if (net_error != net::ERR_IO_PENDING && + (current_phase == START || current_phase == READ_SYNC)) { + NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, net_error)); + return true; + } + + SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); + + if (current_phase != READ_ASYNC) + return true; + + base::MessageLoopProxy::current()->PostTask( + FROM_HERE, + base::Bind( + &URLRequestMockHTTPJob::NotifyDone, + weak_ptr_factory_.GetWeakPtr(), + net::URLRequestStatus(net::URLRequestStatus::FAILED, net_error))); + + return true; +} + +// Private const version. +void URLRequestMockHTTPJob::GetResponseInfoConst( + net::HttpResponseInfo* info) const { + info->headers = new net::HttpResponseHeaders(raw_headers_); +} + +bool URLRequestMockHTTPJob::GetMimeType(std::string* mime_type) const { + net::HttpResponseInfo info; + GetResponseInfoConst(&info); + return info.headers.get() && info.headers->GetMimeType(mime_type); +} + +int URLRequestMockHTTPJob::GetResponseCode() const { + net::HttpResponseInfo info; + GetResponseInfoConst(&info); + // If we have headers, get the response code from them. + if (info.headers.get()) + return info.headers->response_code(); + return net::URLRequestJob::GetResponseCode(); +} + +bool URLRequestMockHTTPJob::GetCharset(std::string* charset) { + net::HttpResponseInfo info; + GetResponseInfo(&info); + return info.headers.get() && info.headers->GetCharset(charset); +} + +} // namespace net diff --git a/chromium/net/test/url_request/url_request_mock_http_job.h b/chromium/net/test/url_request/url_request_mock_http_job.h new file mode 100644 index 00000000000..6eb3c72b861 --- /dev/null +++ b/chromium/net/test/url_request/url_request_mock_http_job.h @@ -0,0 +1,112 @@ +// 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. +// +// A URLRequestJob class that pulls the net and http headers from disk. + +#ifndef NET_TEST_URL_REQUEST_URL_REQUEST_MOCK_HTTP_JOB_H_ +#define NET_TEST_URL_REQUEST_URL_REQUEST_MOCK_HTTP_JOB_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "net/url_request/url_request_file_job.h" +#include "url/gurl.h" + +namespace base { +class FilePath; +class SequencedWorkerPool; +} + +namespace net { +class URLRequestInterceptor; +} + +namespace net { + +class URLRequestMockHTTPJob : public URLRequestFileJob { + public: + enum FailurePhase { + START = 0, + READ_ASYNC = 1, + READ_SYNC = 2, + MAX_FAILURE_PHASE = 3, + }; + + // Note that all file IO is done using |worker_pool|. + URLRequestMockHTTPJob(URLRequest* request, + NetworkDelegate* network_delegate, + const base::FilePath& file_path, + const scoped_refptr<base::TaskRunner>& task_runner); + + void Start() override; + bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override; + bool GetMimeType(std::string* mime_type) const override; + int GetResponseCode() const override; + bool GetCharset(std::string* charset) override; + void GetResponseInfo(HttpResponseInfo* info) override; + bool IsRedirectResponse(GURL* location, int* http_status_code) override; + + // Adds the testing URLs to the URLRequestFilter. + static void AddUrlHandler( + const base::FilePath& base_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); + + // Respond to all HTTP requests of |hostname| with contents of the file + // located at |file_path|. + static void AddHostnameToFileHandler( + const std::string& hostname, + const base::FilePath& file, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); + + // Given the path to a file relative to the path passed to AddUrlHandler(), + // construct a mock URL. + static GURL GetMockUrl(const base::FilePath& path); + + // Given the path to a file relative to the path passed to AddUrlHandler(), + // construct a mock URL that reports |net_error| at given |phase| of the + // request. Reporting |net_error| ERR_IO_PENDING results in a hung request. + static GURL GetMockUrlWithFailure(const base::FilePath& path, + FailurePhase phase, + int net_error); + + // Returns a URLRequestJobFactory::ProtocolHandler that serves + // URLRequestMockHTTPJob's responding like an HTTP server. |base_path| is the + // file path leading to the root of the directory to use as the root of the + // HTTP server. + static scoped_ptr<URLRequestInterceptor> CreateInterceptor( + const base::FilePath& base_path, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); + + // Returns a URLRequestJobFactory::ProtocolHandler that serves + // URLRequestMockHTTPJob's responding like an HTTP server. It responds to all + // requests with the contents of |file|. + static scoped_ptr<URLRequestInterceptor> CreateInterceptorForSingleFile( + const base::FilePath& file, + const scoped_refptr<base::SequencedWorkerPool>& worker_pool); + + protected: + ~URLRequestMockHTTPJob() override; + + private: + void GetResponseInfoConst(HttpResponseInfo* info) const; + void SetHeadersAndStart(const std::string& raw_headers); + // Checks query part of request url, and reports an error if it matches. + // Error is parsed out from the query and is reported synchronously. + // Reporting ERR_IO_PENDING results in a hung request. + // The "readasync" error is posted asynchronously. + bool MaybeReportErrorOnPhase(FailurePhase phase); + + std::string raw_headers_; + const scoped_refptr<base::TaskRunner> task_runner_; + + base::WeakPtrFactory<URLRequestMockHTTPJob> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestMockHTTPJob); +}; + +} // namespace net + +#endif // NET_TEST_URL_REQUEST_URL_REQUEST_MOCK_HTTP_JOB_H_ |