summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 22:57:09 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 22:57:09 +0000
commit73e0bbac9d097eff34726194d2095dce90f2dfa3 (patch)
treeda2f14f77ee83984118e733a231ada709432ea52
parentcefe1497a83ce69c7da0cec320e258e6f87b3aa9 (diff)
downloadchromium_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.cc11
-rw-r--r--chrome/browser/ssl/ssl_uitest.cc14
-rw-r--r--net/base/ssl_client_socket_nss.cc53
-rw-r--r--net/base/ssl_client_socket_nss.h18
-rw-r--r--net/base/ssl_client_socket_unittest.cc158
-rw-r--r--net/base/ssl_test_util.cc252
-rw-r--r--net/base/ssl_test_util.h88
-rw-r--r--net/base/x509_certificate_nss.cc5
-rw-r--r--net/build/net_unittests.vcproj4
-rw-r--r--net/net.xcodeproj/project.pbxproj16
-rw-r--r--net/net_unittests.scons1
-rw-r--r--net/url_request/url_request_unittest.cc29
-rw-r--r--net/url_request/url_request_unittest.h478
-rw-r--r--webkit/glue/unittest_test_server.h5
-rw-r--r--webkit/tools/test_shell/test_shell_main.cc5
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);