diff options
author | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-19 22:57:09 +0000 |
---|---|---|
committer | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-19 22:57:09 +0000 |
commit | 73e0bbac9d097eff34726194d2095dce90f2dfa3 (patch) | |
tree | da2f14f77ee83984118e733a231ada709432ea52 | |
parent | cefe1497a83ce69c7da0cec320e258e6f87b3aa9 (diff) | |
download | chromium_src-73e0bbac9d097eff34726194d2095dce90f2dfa3.zip chromium_src-73e0bbac9d097eff34726194d2095dce90f2dfa3.tar.gz chromium_src-73e0bbac9d097eff34726194d2095dce90f2dfa3.tar.bz2 |
Enable SSL error handling in Linux again.
Evan, could you review the change since http://codereview.chromium.org/20444 :
- load temporary root cert in test_shell
Thanks!
Review URL: http://codereview.chromium.org/20511
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10055 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/net/url_fetcher_unittest.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_uitest.cc | 14 | ||||
-rw-r--r-- | net/base/ssl_client_socket_nss.cc | 53 | ||||
-rw-r--r-- | net/base/ssl_client_socket_nss.h | 18 | ||||
-rw-r--r-- | net/base/ssl_client_socket_unittest.cc | 158 | ||||
-rw-r--r-- | net/base/ssl_test_util.cc | 252 | ||||
-rw-r--r-- | net/base/ssl_test_util.h | 88 | ||||
-rw-r--r-- | net/base/x509_certificate_nss.cc | 5 | ||||
-rw-r--r-- | net/build/net_unittests.vcproj | 4 | ||||
-rw-r--r-- | net/net.xcodeproj/project.pbxproj | 16 | ||||
-rw-r--r-- | net/net_unittests.scons | 1 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 29 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.h | 478 | ||||
-rw-r--r-- | webkit/glue/unittest_test_server.h | 5 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_main.cc | 5 |
15 files changed, 650 insertions, 487 deletions
diff --git a/chrome/browser/net/url_fetcher_unittest.cc b/chrome/browser/net/url_fetcher_unittest.cc index 6a6e3ff..6ac3614 100644 --- a/chrome/browser/net/url_fetcher_unittest.cc +++ b/chrome/browser/net/url_fetcher_unittest.cc @@ -105,10 +105,6 @@ class URLFetcherBadHTTPSTest : public URLFetcherTest { const ResponseCookies& cookies, const std::string& data); - protected: - FilePath GetExpiredCertPath(); - SSLTestUtil util_; - private: FilePath cert_dir_; }; @@ -300,10 +296,6 @@ void URLFetcherBadHTTPSTest::OnURLFetchComplete( io_loop_.Quit(); } -FilePath URLFetcherBadHTTPSTest::GetExpiredCertPath() { - return cert_dir_.AppendASCII("expired_cert.pem"); -} - void URLFetcherCancelTest::CreateFetcher(const GURL& url) { fetcher_ = new URLFetcher(url, URLFetcher::GET, this); fetcher_->set_request_context( @@ -436,8 +428,7 @@ TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) { TEST_F(URLFetcherBadHTTPSTest, DISABLED_BadHTTPSTest) { #endif scoped_refptr<HTTPSTestServer> server = - HTTPSTestServer::CreateServer(util_.kHostName, util_.kBadHTTPSPort, - kDocRoot, util_.GetExpiredCertPath().ToWStringHack()); + HTTPSTestServer::CreateExpiredServer(kDocRoot); ASSERT_TRUE(NULL != server.get()); CreateFetcher(GURL(server->TestServerPage("defaultresponse"))); diff --git a/chrome/browser/ssl/ssl_uitest.cc b/chrome/browser/ssl/ssl_uitest.cc index f31d8f2..47f4753 100644 --- a/chrome/browser/ssl/ssl_uitest.cc +++ b/chrome/browser/ssl/ssl_uitest.cc @@ -23,7 +23,6 @@ class SSLUITest : public UITest { protected: SSLUITest() { dom_automation_enabled_ = true; - EXPECT_TRUE(util_.CheckCATrusted()); } TabProxy* GetActiveTabProxy() { @@ -47,18 +46,14 @@ class SSLUITest : public UITest { } HTTPSTestServer* GoodCertServer() { - return HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort, - kDocRoot, util_.GetOKCertPath().ToWStringHack()); + return HTTPSTestServer::CreateGoodServer(kDocRoot); } HTTPSTestServer* BadCertServer() { - return HTTPSTestServer::CreateServer(util_.kHostName, util_.kBadHTTPSPort, - kDocRoot, util_.GetExpiredCertPath().ToWStringHack()); + return HTTPSTestServer::CreateExpiredServer(kDocRoot); } protected: - SSLTestUtil util_; - DISALLOW_COPY_AND_ASSIGN(SSLUITest); }; @@ -424,8 +419,7 @@ TEST_F(SSLUITest, TestCachedMixedContents) { TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) { const std::string kLocalHost = "localhost"; scoped_refptr<HTTPSTestServer> https_server = - HTTPSTestServer::CreateServer(kLocalHost, util_.kOKHTTPSPort, - kDocRoot, util_.GetOKCertPath().ToWStringHack()); + HTTPSTestServer::CreateMismatchedServer(kDocRoot); ASSERT_TRUE(NULL != https_server.get()); // First we hit the server with hostname, this generates an invalid policy @@ -462,7 +456,7 @@ TEST_F(SSLUITest, DISABLED_TestCNInvalidStickiness) { ASSERT_TRUE(hostname_index != std::string::npos); // Test sanity check. std::string new_url; new_url.append(url.spec().substr(0, hostname_index)); - new_url.append(util_.kHostName); + new_url.append(net::TestServerLauncher::kHostName); new_url.append(url.spec().substr(hostname_index + kLocalHost.size())); NavigateTab(tab.get(), GURL(new_url)); diff --git a/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc index 5c33dc8..f67c246 100644 --- a/net/base/ssl_client_socket_nss.cc +++ b/net/base/ssl_client_socket_nss.cc @@ -23,21 +23,6 @@ static const int kRecvBufferSize = 4096; -namespace { - -// NSS calls this if an incoming certificate is invalid. -SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket) { - PRErrorCode err = PR_GetError(); - LOG(INFO) << "server certificate is invalid; NSS error code " << err; - // Return SECSuccess to override the problem, - // or SECFailure to let the original function fail - // Chromium wants it to fail here, and may retry it later. - LOG(WARNING) << "TODO(dkegel): return SECFailure here"; - return SECSuccess; -} - -} // anonymous namespace - namespace net { // State machines are easier to debug if you log state transitions. @@ -79,6 +64,8 @@ int NetErrorFromNSPRError(PRErrorCode err) { case SEC_ERROR_REVOKED_KEY: return ERR_CERT_REVOKED; case SEC_ERROR_UNKNOWN_ISSUER: + case SEC_ERROR_UNTRUSTED_CERT: + case SEC_ERROR_UNTRUSTED_ISSUER: return ERR_CERT_AUTHORITY_INVALID; default: { @@ -119,7 +106,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, user_callback_(NULL), user_buf_(NULL), user_buf_len_(0), - server_cert_status_(0), + server_cert_error_(0), completed_handshake_(false), next_state_(STATE_NONE), nss_fd_(NULL), @@ -242,9 +229,12 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { << " for cipherSuite " << channel_info.cipherSuite; } } - ssl_info->cert_status = server_cert_status_; - // TODO(port): implement X509Certificate so we can set the cert field! - // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_); + if (server_cert_error_ != net::OK) + ssl_info->SetCertError(server_cert_error_); + X509Certificate::OSCertHandle nss_cert = SSL_PeerCertificate(nss_fd_); + if (nss_cert) + ssl_info->cert = X509Certificate::CreateFromHandle(nss_cert, + X509Certificate::SOURCE_FROM_NETWORK); LeaveFunction(""); } @@ -401,6 +391,19 @@ int SSLClientSocketNSS::DoConnect() { return transport_->Connect(&io_callback_); } +// static +// NSS calls this if an incoming certificate is invalid. +SECStatus SSLClientSocketNSS::OwnBadCertHandler(void* arg, PRFileDesc* socket) { + SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); + PRErrorCode prerr = PR_GetError(); + that->server_cert_error_ = NetErrorFromNSPRError(prerr); + LOG(INFO) << "server certificate is invalid; NSS error code " << prerr + << ", net error " << that->server_cert_error_; + // Return SECSuccess to override the problem. + // Chromium wants it to succeed here, and may abort the connection later. + return SECSuccess; +} + int SSLClientSocketNSS::DoConnectComplete(int result) { EnterFunction(result); if (result < 0) @@ -479,7 +482,7 @@ int SSLClientSocketNSS::DoConnectComplete(int result) { if (rv != SECSuccess) return ERR_UNEXPECTED; - rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL); + rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, this); if (rv != SECSuccess) return ERR_UNEXPECTED; @@ -500,11 +503,10 @@ int SSLClientSocketNSS::DoHandshakeRead() { int rv = SSL_ForceHandshake(nss_fd_); if (rv == SECSuccess) { - net_error = OK; + net_error = server_cert_error_; // there's a callback for this, too completed_handshake_ = true; - // Indicate we're ready to handle I/O. Badly named? - GotoState(STATE_NONE); + // Done! } else { PRErrorCode prerr = PR_GetError(); net_error = NetErrorFromNSPRError(prerr); @@ -513,10 +515,9 @@ int SSLClientSocketNSS::DoHandshakeRead() { if (net_error == ERR_IO_PENDING) { GotoState(STATE_HANDSHAKE_READ); } else { - server_cert_status_ = MapNetErrorToCertStatus(net_error); + server_cert_error_ = net_error; LOG(ERROR) << "handshake failed; NSS error code " << prerr - << ", net_error " << net_error << ", server_cert_status " - << server_cert_status_; + << ", net_error " << net_error; } } diff --git a/net/base/ssl_client_socket_nss.h b/net/base/ssl_client_socket_nss.h index 5015e1e..b16557c 100644 --- a/net/base/ssl_client_socket_nss.h +++ b/net/base/ssl_client_socket_nss.h @@ -5,15 +5,13 @@ #ifndef NET_BASE_SSL_CLIENT_SOCKET_NSS_H_ #define NET_BASE_SSL_CLIENT_SOCKET_NSS_H_ -#include "build/build_config.h" - -#include <prio.h> -#include "net/base/nss_memio.h" - +#include <nspr.h> +#include <nss.h> #include <string> #include "base/scoped_ptr.h" #include "net/base/completion_callback.h" +#include "net/base/nss_memio.h" #include "net/base/ssl_client_socket.h" #include "net/base/ssl_config_service.h" @@ -60,6 +58,9 @@ class SSLClientSocketNSS : public SSLClientSocket { void BufferSendComplete(int result); void BufferRecvComplete(int result); + // nss calls this on error. We pass 'this' as the first argument. + static SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket); + CompletionCallbackImpl<SSLClientSocketNSS> buffer_send_callback_; CompletionCallbackImpl<SSLClientSocketNSS> buffer_recv_callback_; bool transport_send_busy_; @@ -76,7 +77,8 @@ class SSLClientSocketNSS : public SSLClientSocket { char* user_buf_; int user_buf_len_; - int server_cert_status_; + // Set when handshake finishes. Value is net error code, see net_errors.h + int server_cert_error_; bool completed_handshake_; @@ -91,10 +93,10 @@ class SSLClientSocketNSS : public SSLClientSocket { }; State next_state_; - /* The NSS SSL state machine */ + // The NSS SSL state machine PRFileDesc* nss_fd_; - /* Buffers for the network end of the SSL state machine */ + // Buffers for the network end of the SSL state machine memio_Private* nss_bufs_; static bool nss_options_initialized_; diff --git a/net/base/ssl_client_socket_unittest.cc b/net/base/ssl_client_socket_unittest.cc index faf5a4a..4710151 100644 --- a/net/base/ssl_client_socket_unittest.cc +++ b/net/base/ssl_client_socket_unittest.cc @@ -10,6 +10,7 @@ #include "net/base/net_errors.h" #include "net/base/ssl_client_socket.h" #include "net/base/ssl_config_service.h" +#include "net/base/ssl_test_util.h" #include "net/base/tcp_client_socket.h" #include "net/base/test_completion_callback.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,41 +23,74 @@ const net::SSLConfig kDefaultSSLConfig; class SSLClientSocketTest : public PlatformTest { public: SSLClientSocketTest() - : host_mapper_(new net::RuleBasedHostMapper()), - scoped_host_mapper_(host_mapper_.get()), - socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { - // TODO(darin): kill this exception once we have a way to test out the - // TCPClientSocket class using loopback connections. - host_mapper_->AddRule("bugs.webkit.org", "bugs.webkit.org"); + : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { + } + + void StartOKServer() { + bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, + server_.kHostName, server_.kOKHTTPSPort, + FilePath(), server_.GetOKCertPath()); + ASSERT_TRUE(success); + } + + void StartMismatchedServer() { + bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, + server_.kMismatchedHostName, server_.kOKHTTPSPort, + FilePath(), server_.GetOKCertPath()); + ASSERT_TRUE(success); + } + + void StartExpiredServer() { + bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, + server_.kHostName, server_.kBadHTTPSPort, + FilePath(), server_.GetExpiredCertPath()); + ASSERT_TRUE(success); } protected: - scoped_refptr<net::RuleBasedHostMapper> host_mapper_; - net::ScopedHostMapper scoped_host_mapper_; net::ClientSocketFactory* socket_factory_; + net::TestServerLauncher server_; }; //----------------------------------------------------------------------------- -// bug 1354783 -TEST_F(SSLClientSocketTest, DISABLED_Connect) { +#if defined(OS_MACOSX) +#define MAYBE_Connect DISABLED_Connect +#define MAYBE_ConnectExpired DISABLED_ConnectExpired +#define MAYBE_ConnectMismatched DISABLED_ConnectMismatched +#define MAYBE_Read DISABLED_Read +#define MAYBE_Read_SmallChunks DISABLED_Read_SmallChunks +#define MAYBE_Read_Interrupted DISABLED_Read_Interrupted +#else +#define MAYBE_Connect Connect +#define MAYBE_ConnectExpired ConnectExpired +#define MAYBE_ConnectMismatched ConnectMismatched +#define MAYBE_Read Read +#define MAYBE_Read_SmallChunks Read_SmallChunks +#define MAYBE_Read_Interrupted Read_Interrupted +#endif + +TEST_F(SSLClientSocketTest, MAYBE_Connect) { + StartOKServer(); + net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - std::string hostname = "bugs.webkit.org"; - int rv = resolver.Resolve(hostname, 443, &addr, NULL); + int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, + &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - hostname, kDefaultSSLConfig)); + server_.kHostName, kDefaultSSLConfig)); EXPECT_FALSE(sock->IsConnected()); rv = sock->Connect(&callback); if (rv != net::OK) { ASSERT_EQ(net::ERR_IO_PENDING, rv); + EXPECT_FALSE(sock->IsConnected()); rv = callback.WaitForResult(); EXPECT_EQ(net::OK, rv); @@ -68,14 +102,79 @@ TEST_F(SSLClientSocketTest, DISABLED_Connect) { EXPECT_FALSE(sock->IsConnected()); } -// bug 1354783 -TEST_F(SSLClientSocketTest, DISABLED_Read) { +TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) { + StartExpiredServer(); + net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - std::string hostname = "bugs.webkit.org"; - int rv = resolver.Resolve(hostname, 443, &addr, &callback); + int rv = resolver.Resolve(server_.kHostName, server_.kBadHTTPSPort, + &addr, NULL); + EXPECT_EQ(net::OK, rv); + + scoped_ptr<net::SSLClientSocket> sock( + socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), + server_.kHostName, kDefaultSSLConfig)); + + EXPECT_FALSE(sock->IsConnected()); + + rv = sock->Connect(&callback); + if (rv != net::OK) { + ASSERT_EQ(net::ERR_IO_PENDING, rv); + EXPECT_FALSE(sock->IsConnected()); + + rv = callback.WaitForResult(); + EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv); + } + + EXPECT_TRUE(sock->IsConnected()); +} + +TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) { + StartMismatchedServer(); + + net::AddressList addr; + net::HostResolver resolver; + TestCompletionCallback callback; + + int rv = resolver.Resolve(server_.kMismatchedHostName, server_.kOKHTTPSPort, + &addr, NULL); + EXPECT_EQ(net::OK, rv); + + scoped_ptr<net::SSLClientSocket> sock( + socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), + server_.kMismatchedHostName, kDefaultSSLConfig)); + + EXPECT_FALSE(sock->IsConnected()); + + rv = sock->Connect(&callback); + if (rv != net::ERR_CERT_COMMON_NAME_INVALID) { + ASSERT_EQ(net::ERR_IO_PENDING, rv); + EXPECT_FALSE(sock->IsConnected()); + + rv = callback.WaitForResult(); + EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); + } + + // The Windows code happens to keep the connection + // open now in spite of an error. The designers of + // this API intended to also allow the connection + // to be closed on error, in which case the caller + // should call ReconnectIgnoringLastError, but + // that's currently unimplemented. + EXPECT_TRUE(sock->IsConnected()); +} + +TEST_F(SSLClientSocketTest, MAYBE_Read) { + StartOKServer(); + + net::AddressList addr; + net::HostResolver resolver; + TestCompletionCallback callback; + + int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, + &addr, &callback); EXPECT_EQ(net::ERR_IO_PENDING, rv); rv = callback.WaitForResult(); @@ -83,7 +182,8 @@ TEST_F(SSLClientSocketTest, DISABLED_Read) { scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - hostname, kDefaultSSLConfig)); + server_.kHostName, + kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { @@ -117,19 +217,20 @@ TEST_F(SSLClientSocketTest, DISABLED_Read) { } } -// bug 1354783 -TEST_F(SSLClientSocketTest, DISABLED_Read_SmallChunks) { +TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) { + StartOKServer(); + net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - std::string hostname = "bugs.webkit.org"; - int rv = resolver.Resolve(hostname, 443, &addr, NULL); + int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, + &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - hostname, kDefaultSSLConfig)); + server_.kHostName, kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { @@ -162,19 +263,20 @@ TEST_F(SSLClientSocketTest, DISABLED_Read_SmallChunks) { } } -// bug 1354783 -TEST_F(SSLClientSocketTest, DISABLED_Read_Interrupted) { +TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) { + StartOKServer(); + net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - std::string hostname = "bugs.webkit.org"; - int rv = resolver.Resolve(hostname, 443, &addr, NULL); + int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, + &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - hostname, kDefaultSSLConfig)); + server_.kHostName, kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc index d22e4fd..0b82a6e 100644 --- a/net/base/ssl_test_util.cc +++ b/net/base/ssl_test_util.cc @@ -5,6 +5,8 @@ #include <string> #include <algorithm> +#include "net/base/ssl_test_util.h" + #include "build/build_config.h" #if defined(OS_WIN) @@ -27,16 +29,15 @@ #include "base/file_util.h" #include "base/logging.h" #include "base/path_service.h" +#include "base/platform_thread.h" +#include "base/string_util.h" +#include "net/base/tcp_pinger.h" +#include "net/base/host_resolver.h" +#include "net/base/tcp_client_socket.h" +#include "net/base/test_completion_callback.h" +#include "testing/platform_test.h" -#include "net/base/ssl_test_util.h" - -// static -const char SSLTestUtil::kHostName[] = "127.0.0.1"; -const int SSLTestUtil::kOKHTTPSPort = 9443; -const int SSLTestUtil::kBadHTTPSPort = 9666; - -// The issuer name of the cert that should be trusted for the test to work. -const wchar_t SSLTestUtil::kCertIssuerName[] = L"Test CA"; +namespace { #if defined(OS_LINUX) static CERTCertificate* LoadTemporaryCert(const FilePath& filename) { @@ -67,57 +68,255 @@ static CERTCertificate* LoadTemporaryCert(const FilePath& filename) { rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); if (rv != SECSuccess) { - LOG(ERROR) << "Can't change trust for certificate " + LOG(ERROR) << "Can't change trust for certificate " << filename.ToWStringHack(); CERT_DestroyCertificate(cert); return NULL; } - LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack(); return cert; } #endif -SSLTestUtil::SSLTestUtil() { - PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); - cert_dir_ = cert_dir_.AppendASCII("net"); - cert_dir_ = cert_dir_.AppendASCII("data"); - cert_dir_ = cert_dir_.AppendASCII("ssl"); - cert_dir_ = cert_dir_.AppendASCII("certificates"); +} // namespace + +namespace net { + +// static +const char TestServerLauncher::kHostName[] = "127.0.0.1"; +const char TestServerLauncher::kMismatchedHostName[] = "localhost"; +const int TestServerLauncher::kOKHTTPSPort = 9443; +const int TestServerLauncher::kBadHTTPSPort = 9666; + +// The issuer name of the cert that should be trusted for the test to work. +const wchar_t TestServerLauncher::kCertIssuerName[] = L"Test CA"; +TestServerLauncher::TestServerLauncher() : process_handle_(NULL) #if defined(OS_LINUX) - cert_ = reinterpret_cast<PrivateCERTCertificate*>( - LoadTemporaryCert(GetRootCertPath())); - DCHECK(cert_); +, cert_(NULL) +#endif +{ + PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); + cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("net")) + .Append(FILE_PATH_LITERAL("data")) + .Append(FILE_PATH_LITERAL("ssl")) + .Append(FILE_PATH_LITERAL("certificates")); +} + +namespace { + +void AppendToPythonPath(FilePath dir) { + // Do nothing if dir already on path. + +#if defined(OS_WIN) + const wchar_t kPythonPath[] = L"PYTHONPATH"; + // FIXME(dkegel): handle longer PYTHONPATH variables + wchar_t oldpath[4096]; + if (GetEnvironmentVariable(kPythonPath, oldpath, sizeof(oldpath)) == 0) { + SetEnvironmentVariableW(kPythonPath, dir.value().c_str()); + } else if (!wcsstr(oldpath, dir.value().c_str())) { + std::wstring newpath(oldpath); + newpath.append(L":"); + newpath.append(dir.value()); + SetEnvironmentVariableW(kPythonPath, newpath.c_str()); + } +#elif defined(OS_POSIX) + const char kPythonPath[] = "PYTHONPATH"; + const char* oldpath = getenv(kPythonPath); + if (!oldpath) { + setenv(kPythonPath, dir.value().c_str(), 1); + } else if (!strstr(oldpath, dir.value().c_str())) { + std::string newpath(oldpath); + newpath.append(":"); + newpath.append(dir.value()); + setenv(kPythonPath, newpath.c_str(), 1); + } +#endif +} + +} // end namespace + +void TestServerLauncher::SetPythonPath() { + FilePath third_party_dir; + ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir)); + third_party_dir = third_party_dir.Append(FILE_PATH_LITERAL("third_party")); + + AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("tlslite"))); + AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("pyftpdlib"))); +} + +bool TestServerLauncher::Start(Protocol protocol, + const std::string& host_name, int port, + const FilePath& document_root, + const FilePath& cert_path) { + if (!LoadTestRootCert()) + return false; + if (!CheckCATrusted()) + return false; + + std::string port_str = IntToString(port); + + // Get path to python server script + FilePath testserver_path; + if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) + return false; + testserver_path = testserver_path + .Append(FILE_PATH_LITERAL("net")) + .Append(FILE_PATH_LITERAL("tools")) + .Append(FILE_PATH_LITERAL("testserver")) + .Append(FILE_PATH_LITERAL("testserver.py")); + + PathService::Get(base::DIR_SOURCE_ROOT, &document_root_dir_); + document_root_dir_ = document_root_dir_.Append(document_root); + + SetPythonPath(); + +#if defined(OS_WIN) + // Get path to python interpreter + if (!PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime_)) + return false; + python_runtime_ = python_runtime_ + .Append(FILE_PATH_LITERAL("third_party")) + .Append(FILE_PATH_LITERAL("python_24")) + .Append(FILE_PATH_LITERAL("python.exe")); + + std::wstring command_line = + L"\"" + python_runtime_.ToWStringHack() + L"\" " + + L"\"" + testserver_path.ToWStringHack() + + L"\" --port=" + UTF8ToWide(port_str) + + L" --data-dir=\"" + document_root_dir_.ToWStringHack() + L"\""; + if (protocol == ProtoFTP) + command_line.append(L" -f"); + if (!cert_path.value().empty()) { + command_line.append(L" --https=\""); + command_line.append(cert_path.ToWStringHack()); + command_line.append(L"\""); + } + + if (!base::LaunchApp(command_line, false, true, &process_handle_)) { + LOG(ERROR) << "Failed to launch " << command_line; + return false; + } +#elif defined(OS_POSIX) + std::vector<std::string> command_line; + command_line.push_back("python"); + command_line.push_back(WideToUTF8(testserver_path.ToWStringHack())); + command_line.push_back("--port=" + port_str); + command_line.push_back("--data-dir=" + + WideToUTF8(document_root_dir_.ToWStringHack())); + if (protocol == ProtoFTP) + command_line.push_back("-f"); + if (!cert_path.value().empty()) + command_line.push_back("--https=" + WideToUTF8(cert_path.ToWStringHack())); + + base::file_handle_mapping_vector no_mappings; + LOG(INFO) << "Trying to launch " << command_line[0] << " ..."; + if (!base::LaunchApp(command_line, no_mappings, false, &process_handle_)) { + LOG(ERROR) << "Failed to launch " << command_line[0] << " ..."; + return false; + } #endif + + // Let the server start, then verify that it's up. + // Our server is Python, and takes about 500ms to start + // up the first time, and about 200ms after that. + if (!WaitToStart(host_name, port)) { + LOG(ERROR) << "Failed to connect to server"; + Stop(); + return false; + } + + LOG(INFO) << "Started on port " << port_str; + return true; } -SSLTestUtil::~SSLTestUtil() { +bool TestServerLauncher::WaitToStart(const std::string& host_name, int port) { + // Verify that the webserver is actually started. + // Otherwise tests can fail if they run faster than Python can start. + net::AddressList addr; + net::HostResolver resolver; + int rv = resolver.Resolve(host_name, port, &addr, NULL); + if (rv != net::OK) + return false; + + net::TCPPinger pinger(addr); + rv = pinger.Ping(); + return rv == net::OK; +} + +bool TestServerLauncher::WaitToFinish(int timeout_ms) { + if (!process_handle_) + return true; + + bool ret = base::WaitForSingleProcess(process_handle_, timeout_ms); + if (ret) { + base::CloseProcessHandle(process_handle_); + process_handle_ = NULL; + LOG(INFO) << "Finished."; + } else { + LOG(INFO) << "Timed out."; + } + return ret; +} + +bool TestServerLauncher::Stop() { + if (!process_handle_) + return true; + + bool ret = base::KillProcess(process_handle_, 1, true); + if (ret) { + base::CloseProcessHandle(process_handle_); + process_handle_ = NULL; + LOG(INFO) << "Stopped."; + } else { + LOG(INFO) << "Kill failed?"; + } + + return ret; +} + +TestServerLauncher::~TestServerLauncher() { #if defined(OS_LINUX) if (cert_) CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_)); #endif + Stop(); } -FilePath SSLTestUtil::GetRootCertPath() { +FilePath TestServerLauncher::GetRootCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("root_ca_cert.crt"); return path; } -FilePath SSLTestUtil::GetOKCertPath() { +FilePath TestServerLauncher::GetOKCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("ok_cert.pem"); return path; } -FilePath SSLTestUtil::GetExpiredCertPath() { +FilePath TestServerLauncher::GetExpiredCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("expired_cert.pem"); return path; } -bool SSLTestUtil::CheckCATrusted() { +bool TestServerLauncher::LoadTestRootCert() { +#if defined(OS_LINUX) + if (cert_) + return true; + + // TODO(dkegel): figure out how to get this to only happen once? + cert_ = reinterpret_cast<PrivateCERTCertificate*>( + LoadTemporaryCert(GetRootCertPath())); + DCHECK(cert_); + return (cert_ != NULL); +#else + return true; +#endif +} + +bool TestServerLauncher::CheckCATrusted() { // TODO(port): Port either this or LoadTemporaryCert to MacOSX. #if defined(OS_WIN) HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT"); @@ -146,3 +345,6 @@ bool SSLTestUtil::CheckCATrusted() { #endif return true; } + +} // namespace net + diff --git a/net/base/ssl_test_util.h b/net/base/ssl_test_util.h index 9daa4cc..acc5aab 100644 --- a/net/base/ssl_test_util.h +++ b/net/base/ssl_test_util.h @@ -5,49 +5,109 @@ #ifndef NET_BASE_SSL_TEST_UTIL_H_ #define NET_BASE_SSL_TEST_UTIL_H_ -#include "build/build_config.h" +#include <string> #include "base/file_path.h" +#include "base/process_util.h" +#include "base/ref_counted.h" +#include "build/build_config.h" -// TODO(dkegel): share this between net/base and +// TODO(dkegel): share this between net/base and // chrome/browser without putting it in net.lib -class SSLTestUtil { - public: - SSLTestUtil(); - - ~SSLTestUtil(); +namespace net { - FilePath GetRootCertPath(); +// This object bounds the lifetime of an external python-based HTTP/HTTPS/FTP +// server that can provide various responses useful for testing. +// A few basic convenience methods are provided, but no +// URL handling methods (those belong at a higher layer, e.g. in +// url_request_unittest.h). +class TestServerLauncher { + public: + TestServerLauncher(); + + virtual ~TestServerLauncher(); + + enum Protocol { + ProtoHTTP, ProtoFTP + }; + + // Load the test root cert, if it hasn't been loaded yet. + bool LoadTestRootCert(); + + // Start src/net/tools/testserver/testserver.py and + // ask it to serve the given protocol. + // If protocol is HTTP, and cert_path is not empty, serves HTTPS. + // Returns true on success, false if files not found or root cert + // not trusted. + bool Start(Protocol protocol, + const std::string& host_name, int port, + const FilePath& document_root, + const FilePath& cert_path); + + // Stop the server started by Start(). + bool Stop(); + + // If you access the server's Kill url, it will exit by itself + // without a call to Stop(). + // WaitToFinish is handy in that case. + // It returns true if the server exited cleanly. + bool WaitToFinish(int milliseconds); + + // Paths to a good, an expired, and an invalid server certificate + // (use as arguments to Start()). FilePath GetOKCertPath(); - FilePath GetExpiredCertPath(); + FilePath GetDocumentRootPath() { return document_root_dir_; } + + // Issuer name of the root cert that should be trusted for the test to work. + static const wchar_t kCertIssuerName[]; + // Hostname to use for test server static const char kHostName[]; + // Different hostname to use for test server (that still resolves to same IP) + static const char kMismatchedHostName[]; + // Port to use for test server static const int kOKHTTPSPort; // Port to use for bad test server static const int kBadHTTPSPort; - // Issuer name of the cert that should be trusted for the test to work. - static const wchar_t kCertIssuerName[]; + private: + // Wait a while for the server to start, return whether + // we were able to make a connection to it. + bool WaitToStart(const std::string& host_name, int port); + + // Append to PYTHONPATH so Python can find pyftpdlib and tlslite. + void SetPythonPath(); + + // Path to our test root certificate. + FilePath GetRootCertPath(); // Returns false if our test root certificate is not trusted. bool CheckCATrusted(); - private: + FilePath document_root_dir_; + FilePath cert_dir_; + FilePath python_runtime_; + + base::ProcessHandle process_handle_; + #if defined(OS_LINUX) struct PrivateCERTCertificate; PrivateCERTCertificate *cert_; #endif - DISALLOW_COPY_AND_ASSIGN(SSLTestUtil); + DISALLOW_COPY_AND_ASSIGN(TestServerLauncher); }; -#endif // NET_BASE_SSL_TEST_UTIL_H_ +} + +#endif // NET_BASE_SSL_TEST_UTIL_H_ + diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc index 2924fd0..2a456e9 100644 --- a/net/base/x509_certificate_nss.cc +++ b/net/base/x509_certificate_nss.cc @@ -183,7 +183,10 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, } void X509Certificate::Persist(Pickle* pickle) { - NOTIMPLEMENTED(); + // TODO(port): implement. + + // Calling NOTIMPLEMENTED here breaks webkit tests. + //NOTIMPLEMENTED(); } void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj index c25c546..2d9a249 100644 --- a/net/build/net_unittests.vcproj +++ b/net/build/net_unittests.vcproj @@ -367,6 +367,10 @@ > </File> <File + RelativePath="..\base\tcp_pinger_unittest.cc" + > + </File> + <File RelativePath="..\base\tcp_client_socket_unittest.cc" > </File> diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj index 2016e45..2e118bc 100644 --- a/net/net.xcodeproj/project.pbxproj +++ b/net/net.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ 04C626D80E8DE3AA0067E92A /* http_auth_handler_basic_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 04C626D70E8DE3AA0067E92A /* http_auth_handler_basic_unittest.cc */; }; 04C626DA0E8DE3BA0067E92A /* http_auth_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 04C626D90E8DE3BA0067E92A /* http_auth_unittest.cc */; }; 04E7BD550EC4ECF60078FE58 /* http_auth_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 04E7BD540EC4ECF60078FE58 /* http_auth_cache.cc */; }; + 07B79D4A0F4221D7001EA432 /* ssl_test_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 07B79D480F4221D7001EA432 /* ssl_test_util.cc */; }; + 07FE37F10F424D9F00049AB8 /* tcp_pinger_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 07FE37F00F424D9F00049AB8 /* tcp_pinger_unittest.cc */; }; 3853286C2A6C0BE6E1113FA2 /* client_socket.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2C481A2E21097E841607B968 /* client_socket.cc */; }; 4D4C5BE20EF1B89E002CA805 /* directory_lister_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED325A0E5A181C00A747DB /* directory_lister_unittest.cc */; }; 4D4C5C060EF1B8C5002CA805 /* filter_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D4C5C050EF1B8C5002CA805 /* filter_unittest.cc */; }; @@ -158,7 +160,6 @@ 8220FABD0E914ACA008170A9 /* ssl_client_socket_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32950E5A181C00A747DB /* ssl_client_socket_unittest.cc */; }; 8220FAFC0E915561008170A9 /* ssl_client_socket_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32970E5A181C00A747DB /* ssl_client_socket_mac.cc */; }; 825C2FCC0E5C968B00FDEAB7 /* ev_root_ca_metadata.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32BE0E5A181C00A747DB /* ev_root_ca_metadata.cc */; }; - 826F15770EE48CEA00D973C7 /* ssl_test_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */; }; 827E139D0E81611D00183614 /* x509_certificate_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32800E5A181C00A747DB /* x509_certificate_mac.cc */; }; 82ECB3090E5B651D00A913E3 /* mime_sniffer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED32AD0E5A181C00A747DB /* mime_sniffer.cc */; }; 93D11DCE0E91463000C36437 /* file_stream_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 93D11DCD0E91463000C36437 /* file_stream_posix.cc */; }; @@ -446,6 +447,8 @@ 04C626D90E8DE3BA0067E92A /* http_auth_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_auth_unittest.cc; sourceTree = "<group>"; }; 04E7BD540EC4ECF60078FE58 /* http_auth_cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http_auth_cache.cc; sourceTree = "<group>"; }; 04E7BD560EC4ED020078FE58 /* http_auth_cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http_auth_cache.h; sourceTree = "<group>"; }; + 07B79D480F4221D7001EA432 /* ssl_test_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ssl_test_util.cc; sourceTree = "<group>"; }; + 07FE37F00F424D9F00049AB8 /* tcp_pinger_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tcp_pinger_unittest.cc; sourceTree = "<group>"; }; 0E81748E2B2E8B814DBB78EC /* ftp_auth_cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ftp_auth_cache.cc; path = ftp/ftp_auth_cache.cc; sourceTree = SOURCE_ROOT; }; 15C6370BF6FE62308A559648 /* ftp_auth_cache_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ftp_auth_cache_unittest.cc; path = ftp/ftp_auth_cache_unittest.cc; sourceTree = SOURCE_ROOT; }; 3C5876D639CF4CE40AF8F45B /* proxy_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proxy_server.h; path = proxy/proxy_server.h; sourceTree = SOURCE_ROOT; }; @@ -691,8 +694,6 @@ 82113A270E84360200E3848F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = "<group>"; }; 82113BBC0E892E5800E3848F /* x509_certificate.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = x509_certificate.cc; sourceTree = "<group>"; }; 8249C4920EA786B100A4A54B /* ssl_client_socket_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_client_socket_mac.h; sourceTree = "<group>"; }; - 826F15750EE48CEA00D973C7 /* ssl_test_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssl_test_util.h; sourceTree = "<group>"; }; - 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ssl_test_util.cc; sourceTree = "<group>"; }; 936882DC0E9154E200043405 /* file_stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_stream.h; sourceTree = "<group>"; }; 93D11DCD0E91463000C36437 /* file_stream_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_stream_posix.cc; sourceTree = "<group>"; }; A5AB7BFB0EB7DBA10070A7D3 /* file_stream_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_stream_unittest.cc; sourceTree = "<group>"; }; @@ -929,6 +930,7 @@ 7BED326C0E5A181C00A747DB /* client_socket_pool.cc */, 7BED326B0E5A181C00A747DB /* client_socket_pool.h */, 7BED326A0E5A181C00A747DB /* client_socket_pool_unittest.cc */, + 07FE37F00F424D9F00049AB8 /* tcp_pinger_unittest.cc */, 7BED32680E5A181C00A747DB /* completion_callback.h */, F17062083BCE6F0A42F4C479 /* connection_type_histograms.cc */, D4726BC70CCE10F4FF2A5E12 /* connection_type_histograms.h */, @@ -1010,8 +1012,7 @@ 7BED32930E5A181C00A747DB /* ssl_config_service.h */, 7BED32920E5A181C00A747DB /* ssl_config_service_unittest.cc */, 7BED32910E5A181C00A747DB /* ssl_info.h */, - 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */, - 826F15750EE48CEA00D973C7 /* ssl_test_util.h */, + 07B79D480F4221D7001EA432 /* ssl_test_util.cc */, 7BED328F0E5A181C00A747DB /* tcp_client_socket.h */, E47E933E0E8924DC00CA613E /* tcp_client_socket_libevent.cc */, 7BED328E0E5A181C00A747DB /* tcp_client_socket_unittest.cc */, @@ -1558,6 +1559,7 @@ 7BA362B60E8C3D020023C8B9 /* sdch_filter.cc in Sources */, E49DD2EA0E892F8C003C7A87 /* sdch_manager.cc in Sources */, 8220FAFC0E915561008170A9 /* ssl_client_socket_mac.cc in Sources */, + 07B79D4A0F4221D7001EA432 /* ssl_test_util.cc in Sources */, 7B8504410E5B2E9600730B43 /* stats.cc in Sources */, DFEE18270E882E3600666107 /* stats_histogram.cc in Sources */, E47E933F0E8924DC00CA613E /* tcp_client_socket_libevent.cc in Sources */, @@ -1581,7 +1583,6 @@ 821F20A50E5CD414003C7E38 /* url_request_view_cache_job.cc in Sources */, 82113BBD0E892E5800E3848F /* x509_certificate.cc in Sources */, 827E139D0E81611D00183614 /* x509_certificate_mac.cc in Sources */, - 043C23DB0EFC592900658F5E /* proxy_script_fetcher.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1595,6 +1596,7 @@ 7BD8F70C0E65DCD800034DE9 /* block_files_unittest.cc in Sources */, 7BA015210E5A1B9800044150 /* bzip2_filter_unittest.cc in Sources */, 7B4DF64A0E5B98DF004D7619 /* client_socket_pool_unittest.cc in Sources */, + 07FE37F10F424D9F00049AB8 /* tcp_pinger_unittest.cc in Sources */, 7B8B5B530E5CEAC7002F9A97 /* cookie_monster_unittest.cc in Sources */, 7BA3614E0E8C347E0023C8B9 /* cookie_policy_unittest.cc in Sources */, 7B4DF6A90E5B98E7004D7619 /* data_url_unittest.cc in Sources */, @@ -1631,14 +1633,12 @@ E4AFA6430E5241B400201347 /* run_all_unittests.cc in Sources */, 7BA362B70E8C3D040023C8B9 /* sdch_filter_unittest.cc in Sources */, 8220FABD0E914ACA008170A9 /* ssl_client_socket_unittest.cc in Sources */, - 826F15770EE48CEA00D973C7 /* ssl_test_util.cc in Sources */, 7BD8F7110E65DCF500034DE9 /* storage_block_unittest.cc in Sources */, E47E93430E8924EE00CA613E /* tcp_client_socket_unittest.cc in Sources */, A50055BF0EBF7CB2007B0A90 /* telnet_server_unittest.cc in Sources */, 7BA361450E8C341F0023C8B9 /* test_completion_callback_unittest.cc in Sources */, 048133550ED27FEF005C5BBC /* url_request_unittest.cc in Sources */, 82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */, - 043C23D90EFC592000658F5E /* proxy_script_fetcher_unittest.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/net/net_unittests.scons b/net/net_unittests.scons index c59b6f3..6ac239a 100644 --- a/net/net_unittests.scons +++ b/net/net_unittests.scons @@ -76,6 +76,7 @@ input_files = ChromeFileList([ 'base/base64_unittest.cc', 'base/bzip2_filter_unittest.cc', 'base/client_socket_pool_unittest.cc', + 'base/tcp_pinger_unittest.cc', 'base/cookie_monster_unittest.cc', 'base/cookie_policy_unittest.cc', 'base/data_url_unittest.cc', diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 5ba7165..f2028f13 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -180,18 +180,27 @@ TEST_F(URLRequestTest, GetTest) { #endif } -class HTTPSRequestTest : public testing::Test { - protected: - HTTPSRequestTest() : util_() {} +TEST_F(URLRequestTest, QuitTest) { + scoped_refptr<HTTPTestServer> server = + HTTPTestServer::CreateServer(L"", NULL); + ASSERT_TRUE(NULL != server.get()); + server->SendQuit(); + EXPECT_TRUE(server->WaitToFinish(20000)); - SSLTestUtil util_; +#ifndef NDEBUG + DCHECK_EQ(url_request_metrics.object_count, 0); +#endif +} + +class HTTPSRequestTest : public testing::Test { }; #if defined(OS_MACOSX) -// TODO(port): support temporary root cert on mac -#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest +// ssl_client_socket_mac.cc crashes currently in GetSSLInfo +// when called on a connection with an unrecognized certificate +#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest #else -#define MAYBE_HTTPSGetTest HTTPSGetTest +#define MAYBE_HTTPSGetTest HTTPSGetTest #endif TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { @@ -200,11 +209,9 @@ TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { // so this test doesn't really need to specify a document root. // But if it did, a good one would be net/data/ssl. scoped_refptr<HTTPSTestServer> server = - HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort, - L"net/data/ssl", util_.GetOKCertPath().ToWStringHack()); + HTTPSTestServer::CreateGoodServer(L"net/data/ssl"); ASSERT_TRUE(NULL != server.get()); - EXPECT_TRUE(util_.CheckCATrusted()); TestDelegate d; { TestURLRequest r(server->TestServerPage(""), &d); @@ -223,6 +230,8 @@ TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) { #endif } +// TODO(dkegel): add test for expired and mismatched certificates here + TEST_F(URLRequestTest, CancelTest) { TestDelegate d; { diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h index 0351382..692ee9a 100644 --- a/net/url_request/url_request_unittest.h +++ b/net/url_request/url_request_unittest.h @@ -13,6 +13,7 @@ #include "base/file_path.h" #include "base/file_util.h" +#include "base/logging.h" #include "base/message_loop.h" #include "base/path_service.h" #include "base/platform_thread.h" @@ -23,6 +24,7 @@ #include "base/waitable_event.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" +#include "net/base/ssl_test_util.h" #include "net/http/http_network_layer.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -211,46 +213,17 @@ class TestDelegate : public URLRequest::Delegate { // that can provide various responses useful for testing. class BaseTestServer : public base::RefCounted<BaseTestServer> { protected: - BaseTestServer() - : process_handle_(NULL) { - } + BaseTestServer() { } public: - virtual ~BaseTestServer() { - if (!IsFinished()) - if (!WaitToFinish(1000)) - Kill(); - } - - bool IsFinished() { - return WaitToFinish(0); - } - - void Kill() { - if (process_handle_) { -#if defined(OS_WIN) - base::KillProcess(process_handle_, 0, true); -#elif defined(OS_POSIX) - // Make sure the process has exited and clean up the process to avoid - // a zombie. - kill(process_handle_, SIGINT); - waitpid(process_handle_, 0, 0); -#endif - base::CloseProcessHandle(process_handle_); - process_handle_ = NULL; - } - } + // Used with e.g. HTTPTestServer::SendQuit() bool WaitToFinish(int milliseconds) { - if (process_handle_ == 0) - return true; - bool ret = base::WaitForSingleProcess(process_handle_, milliseconds); - if (ret) { - base::CloseProcessHandle(process_handle_); - process_handle_ = NULL; - } + return launcher_.WaitToFinish(milliseconds); + } - return ret; + bool Stop() { + return launcher_.Stop(); } GURL TestServerPage(const std::string& base_address, @@ -266,142 +239,54 @@ class BaseTestServer : public base::RefCounted<BaseTestServer> { return GURL(base_address_ + WideToUTF8(path)); } - void SetPythonPaths() { -#if defined(OS_WIN) - // Set up PYTHONPATH so that Python is able to find the in-tree copy of - // pyftpdlib. - static bool set_python_path = false; - if (!set_python_path) { - FilePath pyftpdlib_path; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &pyftpdlib_path)); - pyftpdlib_path = pyftpdlib_path.Append(L"third_party"); - pyftpdlib_path = pyftpdlib_path.Append(L"pyftpdlib"); - - const wchar_t kPythonPath[] = L"PYTHONPATH"; - wchar_t python_path_c[1024]; - if (GetEnvironmentVariable(kPythonPath, python_path_c, 1023) > 0) { - // PYTHONPATH is already set, append to it. - std::wstring python_path(python_path_c); - python_path.append(L":"); - python_path.append(pyftpdlib_path.value()); - SetEnvironmentVariableW(kPythonPath, python_path.c_str()); - } else { - SetEnvironmentVariableW(kPythonPath, pyftpdlib_path.value().c_str()); - } + virtual bool MakeGETRequest(const std::string& page_name) = 0; - set_python_path = true; - } -#elif defined(OS_POSIX) - // Set up PYTHONPATH so that Python is able to find the in-tree copy of - // tlslite and pyftpdlib. - static bool set_python_path = false; - if (!set_python_path) { - FilePath tlslite_path; - FilePath pyftpdlib_path; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &tlslite_path)); - tlslite_path = tlslite_path.Append("third_party"); - tlslite_path = tlslite_path.Append("tlslite"); - - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &pyftpdlib_path)); - pyftpdlib_path = pyftpdlib_path.Append("third_party"); - pyftpdlib_path = pyftpdlib_path.Append("pyftpdlib"); - - const char kPythonPath[] = "PYTHONPATH"; - char* python_path_c = getenv(kPythonPath); - if (python_path_c) { - // PYTHONPATH is already set, append to it. - std::string python_path(python_path_c); - python_path.append(":"); - python_path.append(tlslite_path.value()); - python_path.append(":"); - python_path.append(pyftpdlib_path.value()); - setenv(kPythonPath, python_path.c_str(), 1); - } else { - std::string python_path = tlslite_path.value().c_str(); - python_path.append(":"); - python_path.append(pyftpdlib_path.value()); - setenv(kPythonPath, python_path.c_str(), 1); - } - set_python_path = true; - } -#endif + std::wstring GetDataDirectory() { + return launcher_.GetDocumentRootPath().ToWStringHack(); } - void SetAppPath(const std::string& host_name, int port, - const std::wstring& document_root, const std::string& scheme, - std::wstring* testserver_path, std::wstring* test_data_directory) { - port_str_ = IntToString(port); - if (url_user_.empty()) { - base_address_ = scheme + "://" + host_name + ":" + port_str_ + "/"; + protected: + bool Start(net::TestServerLauncher::Protocol protocol, + const std::string& host_name, int port, + const FilePath& document_root, + const FilePath& cert_path) { + std::string blank; + return Start(protocol, host_name, port, document_root, cert_path, + blank, blank); + } + + bool Start(net::TestServerLauncher::Protocol protocol, + const std::string& host_name, int port, + const FilePath& document_root, + const FilePath& cert_path, + const std::string& url_user, + const std::string& url_password) { + if (!launcher_.Start(protocol, + host_name, port, document_root, cert_path)) + return false; + + std::string scheme; + if (protocol == net::TestServerLauncher::ProtoFTP) + scheme = "ftp"; + else + scheme = "http"; + if (!cert_path.empty()) + scheme.push_back('s'); + + std::string port_str = IntToString(port); + if (url_user.empty()) { + base_address_ = scheme + "://" + host_name + ":" + port_str + "/"; } else { - if (url_password_.empty()) - base_address_ = scheme + "://" + url_user_ + "@" + - host_name + ":" + port_str_ + "/"; + if (url_password.empty()) + base_address_ = scheme + "://" + url_user + "@" + + host_name + ":" + port_str + "/"; else - base_address_ = scheme + "://" + url_user_ + ":" + url_password_ + - "@" + host_name + ":" + port_str_ + "/"; - } - - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, testserver_path)); - file_util::AppendToPath(testserver_path, L"net"); - file_util::AppendToPath(testserver_path, L"tools"); - file_util::AppendToPath(testserver_path, L"testserver"); - file_util::AppendToPath(testserver_path, L"testserver.py"); - - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime_)); - file_util::AppendToPath(&python_runtime_, L"third_party"); - file_util::AppendToPath(&python_runtime_, L"python_24"); - file_util::AppendToPath(&python_runtime_, L"python.exe"); - - PathService::Get(base::DIR_SOURCE_ROOT, test_data_directory); - std::wstring normalized_document_root = document_root; - -#if defined(OS_WIN) - // It is just for windows only and have no effect on other OS - std::replace(normalized_document_root.begin(), - normalized_document_root.end(), - L'/', FilePath::kSeparators[0]); -#endif - if (!normalized_document_root.empty()) - file_util::AppendToPath(test_data_directory, normalized_document_root); - data_directory_ = *test_data_directory; - } - -#if defined(OS_WIN) - void LaunchApp(const std::wstring& command_line) { - ASSERT_TRUE(base::LaunchApp(command_line, false, true, &process_handle_)) << - "Failed to launch " << command_line; - } -#elif defined(OS_POSIX) - void LaunchApp(const std::vector<std::string>& command_line) { - base::file_handle_mapping_vector fds_empty; - ASSERT_TRUE(base::LaunchApp(command_line, fds_empty, false, - &process_handle_)) << - "Failed to launch " << command_line[0] << " ..."; - } -#endif - - virtual bool MakeGETRequest(const std::string& page_name) = 0; - - // Verify that the Server is actually started. - // Otherwise tests can fail if they run faster than Python can start. - bool VerifyLaunchApp(const std::string& page_name) { - int retries = 10; - bool success; - while ((success = MakeGETRequest(page_name)) == false && retries > 0) { - retries--; - PlatformThread::Sleep(500); + base_address_ = scheme + "://" + url_user + ":" + url_password + + "@" + host_name + ":" + port_str + "/"; } - if (!success) - return false; return true; } - std::wstring GetDataDirectory() { - return data_directory_; - } - - protected: // Used by MakeGETRequest to implement sync load behavior. class SyncTestDelegate : public TestDelegate { public: @@ -424,18 +309,13 @@ class BaseTestServer : public base::RefCounted<BaseTestServer> { bool success_; DISALLOW_COPY_AND_ASSIGN(SyncTestDelegate); }; + net::TestServerLauncher launcher_; - std::string host_name_; std::string base_address_; - std::string url_user_; - std::string url_password_; - std::wstring python_runtime_; - std::wstring data_directory_; - base::ProcessHandle process_handle_; - std::string port_str_; - }; + +// HTTP class HTTPTestServer : public BaseTestServer { protected: explicit HTTPTestServer() : loop_(NULL) { @@ -448,37 +328,16 @@ class HTTPTestServer : public BaseTestServer { MessageLoop* loop) { HTTPTestServer* test_server = new HTTPTestServer(); test_server->loop_ = loop; - if (!test_server->Init(kDefaultHostName, kHTTPDefaultPort, document_root)) { - delete test_server; + FilePath no_cert; + FilePath docroot = FilePath::FromWStringHack(document_root); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + kDefaultHostName, kHTTPDefaultPort, docroot, no_cert)) { + test_server->Release(); return NULL; } return test_server; } - bool Init(const std::string& host_name, int port, - const std::wstring& document_root) { - std::wstring testserver_path; - std::wstring test_data_directory; - host_name_ = host_name; -#if defined(OS_WIN) - std::wstring command_line; -#elif defined(OS_POSIX) - std::vector<std::string> command_line; -#endif - - // Set PYTHONPATH for tlslite and pyftpdlib - SetPythonPaths(); - SetAppPath(host_name, port, document_root, scheme(), - &testserver_path, &test_data_directory); - SetCommandLineOption(testserver_path, test_data_directory, &command_line); - LaunchApp(command_line); - if (!VerifyLaunchApp("hello.html")) { - LOG(ERROR) << "Webserver not starting properly"; - return false; - } - return true; - } - // A subclass may wish to send the request in a different manner virtual bool MakeGETRequest(const std::string& page_name) { const GURL& url = TestServerPage(page_name); @@ -517,15 +376,13 @@ class HTTPTestServer : public BaseTestServer { EXPECT_TRUE(request->is_pending()); } - virtual ~HTTPTestServer() { - Stop(); - } - - void Stop() { - if (IsFinished()) - return; - - // here we append the time to avoid problems where the kill page + // Some tests use browser javascript to fetch a 'kill' url that causes + // the server to exit by itself (rather than letting TestServerLauncher's + // destructor kill it). + // This method does the same thing so we can unit test that mechanism. + // You can then use WaitToFinish() to sleep until the server terminates. + void SendQuit() { + // Append the time to avoid problems where the kill page // is being cached rather than being executed on the server std::string page_name = StringPrintf("kill?%u", static_cast<int>(base::Time::Now().ToInternalValue())); @@ -540,31 +397,12 @@ class HTTPTestServer : public BaseTestServer { break; retry_count--; } - // Make sure we were successfull in stopping the testserver. + // Make sure we were successful in stopping the testserver. DCHECK(retry_count > 0); } virtual std::string scheme() { return "http"; } -#if defined(OS_WIN) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::wstring* command_line ) { - command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + - testserver_path + L"\" --port=" + UTF8ToWide(port_str_) + - L" --data-dir=\"" + test_data_directory + L"\""); - } -#elif defined(OS_POSIX) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::vector<std::string>* command_line) { - command_line->push_back("python"); - command_line->push_back(WideToUTF8(testserver_path)); - command_line->push_back("--port=" + port_str_); - command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); - } -#endif - private: // If non-null a background thread isn't created and instead this message loop // is used. @@ -573,50 +411,74 @@ class HTTPTestServer : public BaseTestServer { class HTTPSTestServer : public HTTPTestServer { protected: - explicit HTTPSTestServer(const std::wstring& cert_path) - : cert_path_(cert_path) { + explicit HTTPSTestServer() { } public: - static HTTPSTestServer* CreateServer(const std::string& host_name, int port, - const std::wstring& document_root, - const std::wstring& cert_path) { - HTTPSTestServer* test_server = new HTTPSTestServer(cert_path); - if (!test_server->Init(host_name, port, document_root)) { - delete test_server; + // Create a server with a valid certificate + // TODO(dkegel): HTTPSTestServer should not require an instance to specify + // stock test certificates + static HTTPSTestServer* CreateGoodServer(const std::wstring& document_root) { + HTTPSTestServer* test_server = new HTTPSTestServer(); + FilePath docroot = FilePath::FromWStringHack(document_root); + FilePath certpath = test_server->launcher_.GetOKCertPath(); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + net::TestServerLauncher::kHostName, + net::TestServerLauncher::kOKHTTPSPort, + docroot, certpath)) { + test_server->Release(); + return NULL; + } + return test_server; + } + + // Create a server with an up to date certificate for the wrong hostname + // for this host + static HTTPSTestServer* CreateMismatchedServer( + const std::wstring& document_root) { + HTTPSTestServer* test_server = new HTTPSTestServer(); + FilePath docroot = FilePath::FromWStringHack(document_root); + FilePath certpath = test_server->launcher_.GetOKCertPath(); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + net::TestServerLauncher::kMismatchedHostName, + net::TestServerLauncher::kOKHTTPSPort, + docroot, certpath)) { + test_server->Release(); + return NULL; + } + return test_server; + } + + // Create a server with an expired certificate + static HTTPSTestServer* CreateExpiredServer( + const std::wstring& document_root) { + HTTPSTestServer* test_server = new HTTPSTestServer(); + FilePath docroot = FilePath::FromWStringHack(document_root); + FilePath certpath = test_server->launcher_.GetExpiredCertPath(); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + net::TestServerLauncher::kHostName, + net::TestServerLauncher::kBadHTTPSPort, + docroot, certpath)) { + test_server->Release(); return NULL; } return test_server; } -#if defined(OS_WIN) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::wstring* command_line ) { - command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + - testserver_path + L"\"" + L" --port=" + - UTF8ToWide(port_str_) + L" --data-dir=\"" + - test_data_directory + L"\""); - if (!cert_path_.empty()) { - command_line->append(L" --https=\""); - command_line->append(cert_path_); - command_line->append(L"\""); + // Create a server with an arbitrary certificate + static HTTPSTestServer* CreateServer(const std::string& host_name, int port, + const std::wstring& document_root, + const std::wstring& cert_path) { + HTTPSTestServer* test_server = new HTTPSTestServer(); + FilePath docroot = FilePath::FromWStringHack(document_root); + FilePath certpath = FilePath::FromWStringHack(cert_path); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + host_name, port, docroot, certpath)) { + test_server->Release(); + return NULL; } + return test_server; } -#elif defined(OS_POSIX) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::vector<std::string>* command_line) { - command_line->push_back("python"); - command_line->push_back(WideToUTF8(testserver_path)); - command_line->push_back("--port=" + port_str_); - command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); - if (!cert_path_.empty()) - command_line->push_back("--https=" + WideToUTF8(cert_path_)); -} -#endif - - virtual std::string scheme() { return "https"; } virtual ~HTTPSTestServer() { } @@ -627,88 +489,32 @@ class HTTPSTestServer : public HTTPTestServer { class FTPTestServer : public BaseTestServer { - protected: - FTPTestServer() { - } - public: - FTPTestServer(const std::string& url_user, const std::string& url_password) { - url_user_ = url_user; - url_password_ = url_password; + FTPTestServer() { } static FTPTestServer* CreateServer(const std::wstring& document_root) { - FTPTestServer* test_server = new FTPTestServer(); - if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) { - delete test_server; - return NULL; - } - return test_server; + std::string blank; + return CreateServer(document_root, blank, blank); } static FTPTestServer* CreateServer(const std::wstring& document_root, const std::string& url_user, const std::string& url_password) { - FTPTestServer* test_server = new FTPTestServer(url_user, url_password); - if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) { - delete test_server; + FTPTestServer* test_server = new FTPTestServer(); + FilePath docroot = FilePath::FromWStringHack(document_root); + FilePath no_cert; + if (!test_server->Start(net::TestServerLauncher::ProtoFTP, + kDefaultHostName, kFTPDefaultPort, docroot, no_cert, + url_user, url_password)) { + test_server->Release(); return NULL; } return test_server; } - bool Init(const std::string& host_name, int port, - const std::wstring& document_root) { - std::wstring testserver_path; - std::wstring test_data_directory; - host_name_ = host_name; - -#if defined(OS_WIN) - std::wstring command_line; -#elif defined(OS_POSIX) - std::vector<std::string> command_line; -#endif - - // Set PYTHONPATH for tlslite and pyftpdlib - SetPythonPaths(); - SetAppPath(kDefaultHostName, port, document_root, scheme(), - &testserver_path, &test_data_directory); - SetCommandLineOption(testserver_path, test_data_directory, &command_line); - LaunchApp(command_line); - if (!VerifyLaunchApp("/LICENSE")) { - LOG(ERROR) << "FTPServer not starting properly."; - return false; - } - return true; - } - - virtual ~FTPTestServer() { - Stop(); - } - - void Stop() { - if (IsFinished()) - return; - - const std::string base_address = scheme() + "://" + host_name_ + ":" + - port_str_ + "/"; - const GURL& url = TestServerPage(base_address, "kill"); - TestDelegate d; - URLRequest request(url, &d); - request.set_context(new TestURLRequestContext()); - request.set_method("GET"); - request.Start(); - EXPECT_TRUE(request.is_pending()); - - MessageLoop::current()->Run(); - } - - virtual std::string scheme() { return "ftp"; } - virtual bool MakeGETRequest(const std::string& page_name) { - const std::string base_address = scheme() + "://" + host_name_ + ":" + - port_str_ + "/"; - const GURL& url = TestServerPage(base_address, page_name); + const GURL& url = TestServerPage(base_address_, page_name); TestDelegate d; URLRequest request(url, &d); request.set_context(new TestURLRequestContext()); @@ -723,26 +529,6 @@ class FTPTestServer : public BaseTestServer { return true; } -#if defined(OS_WIN) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::wstring* command_line ) { - command_line->append(L"\"" + python_runtime_ + L"\" " + L"\"" + - testserver_path + L"\"" + L" -f " + L" --port=" + - UTF8ToWide(port_str_) + L" --data-dir=\"" + - test_data_directory + L"\""); - } -#elif defined(OS_POSIX) - virtual void SetCommandLineOption(const std::wstring& testserver_path, - const std::wstring& test_data_directory, - std::vector<std::string>* command_line) { - command_line->push_back("python"); - command_line->push_back(WideToUTF8(testserver_path)); - command_line->push_back(" -f "); - command_line->push_back("--data-dir=" + WideToUTF8(test_data_directory)); - command_line->push_back("--port=" + port_str_); - } -#endif }; #endif // NET_URL_REQUEST_URL_REQUEST_UNITTEST_H_ diff --git a/webkit/glue/unittest_test_server.h b/webkit/glue/unittest_test_server.h index 3e27b875..2a83599 100644 --- a/webkit/glue/unittest_test_server.h +++ b/webkit/glue/unittest_test_server.h @@ -22,7 +22,10 @@ class UnittestTestServer : public HTTPTestServer { public: static UnittestTestServer* CreateServer() { UnittestTestServer* test_server = new UnittestTestServer(); - if (!test_server->Init("localhost", 1337, L"webkit/data")) { + FilePath no_cert; + FilePath docroot = FilePath::FromWStringHack(L"webkit/data"); + if (!test_server->Start(net::TestServerLauncher::ProtoHTTP, + "localhost", 1337, docroot, no_cert)) { delete test_server; return NULL; } diff --git a/webkit/tools/test_shell/test_shell_main.cc b/webkit/tools/test_shell/test_shell_main.cc index 08b8c07..9604dc7 100644 --- a/webkit/tools/test_shell/test_shell_main.cc +++ b/webkit/tools/test_shell/test_shell_main.cc @@ -23,6 +23,7 @@ #include "net/base/cookie_monster.h" #include "net/base/net_module.h" #include "net/http/http_cache.h" +#include "net/base/ssl_test_util.h" #include "net/url_request/url_request_context.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/window_open_disposition.h" @@ -129,6 +130,10 @@ int main(int argc, char* argv[]) { // Config the network module so it has access to a limited set of resources. net::NetModule::SetResourceProvider(TestShell::NetResourceProvider); + // On Linux, load the test root certificate. + net::TestServerLauncher ssl_util; + ssl_util.LoadTestRootCert(); + platform.InitializeGUI(); TestShell::InitializeTestShell(layout_test_mode); |