summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authordkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-14 23:14:35 +0000
committerdkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-14 23:14:35 +0000
commit518fdec3a07a94dc45d6e7e4ad1b529747dc03d3 (patch)
treefb2b17479a907a8960a8dc865630fe7272d041fc /net
parent5e997eacfb2234633831d06c91859ee76af44468 (diff)
downloadchromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.zip
chromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.tar.gz
chromium_src-518fdec3a07a94dc45d6e7e4ad1b529747dc03d3.tar.bz2
Reverting r9823 (http://codereview.chromium.org/16207) because
1) the Interactive Tests (dbg) buildbot needs the SSL cert installed 2) the same buildbot showed a refcounting problem, e.g. FATAL:ref_counted.cc(22)] Check failed: in_dtor_. RefCounted object deleted without calling Release() c:\b\slave\chromium-dbg-builder\build\src\chrome\browser\views\find_bar_win_interactive_uitest.cc(57): error: Value of: NULL != server.get() Actual: false Expected: true [ FAILED ] FindInPageTest.CrashEscHandlers (2109 ms) 3) the Webkit Linux buildbot failed four tests redirect302-frames.html cross-frame-access-protocol-explicit-domain.html cross-frame-access-protocol.html origin-header-for-https.html I'm leaving the tcp_pinger files in for the moment, they shouldn't hurt anything. Review URL: http://codereview.chromium.org/23028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-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.cc226
-rw-r--r--net/base/ssl_test_util.h73
-rw-r--r--net/build/net_unittests.vcproj4
-rw-r--r--net/net.xcodeproj/project.pbxproj18
-rw-r--r--net/net_unittests.scons1
-rw-r--r--net/url_request/url_request_unittest.cc17
-rw-r--r--net/url_request/url_request_unittest.h479
10 files changed, 482 insertions, 565 deletions
diff --git a/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc
index f67c246..5c33dc8 100644
--- a/net/base/ssl_client_socket_nss.cc
+++ b/net/base/ssl_client_socket_nss.cc
@@ -23,6 +23,21 @@
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.
@@ -64,8 +79,6 @@ 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: {
@@ -106,7 +119,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
user_callback_(NULL),
user_buf_(NULL),
user_buf_len_(0),
- server_cert_error_(0),
+ server_cert_status_(0),
completed_handshake_(false),
next_state_(STATE_NONE),
nss_fd_(NULL),
@@ -229,12 +242,9 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
<< " for cipherSuite " << channel_info.cipherSuite;
}
}
- 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);
+ ssl_info->cert_status = server_cert_status_;
+ // TODO(port): implement X509Certificate so we can set the cert field!
+ // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_);
LeaveFunction("");
}
@@ -391,19 +401,6 @@ 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)
@@ -482,7 +479,7 @@ int SSLClientSocketNSS::DoConnectComplete(int result) {
if (rv != SECSuccess)
return ERR_UNEXPECTED;
- rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, this);
+ rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL);
if (rv != SECSuccess)
return ERR_UNEXPECTED;
@@ -503,10 +500,11 @@ int SSLClientSocketNSS::DoHandshakeRead() {
int rv = SSL_ForceHandshake(nss_fd_);
if (rv == SECSuccess) {
- net_error = server_cert_error_;
+ net_error = OK;
// there's a callback for this, too
completed_handshake_ = true;
- // Done!
+ // Indicate we're ready to handle I/O. Badly named?
+ GotoState(STATE_NONE);
} else {
PRErrorCode prerr = PR_GetError();
net_error = NetErrorFromNSPRError(prerr);
@@ -515,9 +513,10 @@ int SSLClientSocketNSS::DoHandshakeRead() {
if (net_error == ERR_IO_PENDING) {
GotoState(STATE_HANDSHAKE_READ);
} else {
- server_cert_error_ = net_error;
+ server_cert_status_ = MapNetErrorToCertStatus(net_error);
LOG(ERROR) << "handshake failed; NSS error code " << prerr
- << ", net_error " << net_error;
+ << ", net_error " << net_error << ", server_cert_status "
+ << server_cert_status_;
}
}
diff --git a/net/base/ssl_client_socket_nss.h b/net/base/ssl_client_socket_nss.h
index b16557c..5015e1e 100644
--- a/net/base/ssl_client_socket_nss.h
+++ b/net/base/ssl_client_socket_nss.h
@@ -5,13 +5,15 @@
#ifndef NET_BASE_SSL_CLIENT_SOCKET_NSS_H_
#define NET_BASE_SSL_CLIENT_SOCKET_NSS_H_
-#include <nspr.h>
-#include <nss.h>
+#include "build/build_config.h"
+
+#include <prio.h>
+#include "net/base/nss_memio.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"
@@ -58,9 +60,6 @@ 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_;
@@ -77,8 +76,7 @@ class SSLClientSocketNSS : public SSLClientSocket {
char* user_buf_;
int user_buf_len_;
- // Set when handshake finishes. Value is net error code, see net_errors.h
- int server_cert_error_;
+ int server_cert_status_;
bool completed_handshake_;
@@ -93,10 +91,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 4710151..faf5a4a 100644
--- a/net/base/ssl_client_socket_unittest.cc
+++ b/net/base/ssl_client_socket_unittest.cc
@@ -10,7 +10,6 @@
#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"
@@ -23,74 +22,41 @@ const net::SSLConfig kDefaultSSLConfig;
class SSLClientSocketTest : public PlatformTest {
public:
SSLClientSocketTest()
- : 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);
+ : 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");
}
protected:
+ scoped_refptr<net::RuleBasedHostMapper> host_mapper_;
+ net::ScopedHostMapper scoped_host_mapper_;
net::ClientSocketFactory* socket_factory_;
- net::TestServerLauncher server_;
};
//-----------------------------------------------------------------------------
-#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();
-
+// bug 1354783
+TEST_F(SSLClientSocketTest, DISABLED_Connect) {
net::AddressList addr;
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL);
+ std::string hostname = "bugs.webkit.org";
+ int rv = resolver.Resolve(hostname, 443, &addr, NULL);
EXPECT_EQ(net::OK, rv);
scoped_ptr<net::SSLClientSocket> sock(
socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr),
- server_.kHostName, kDefaultSSLConfig));
+ hostname, 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);
@@ -102,79 +68,14 @@ TEST_F(SSLClientSocketTest, MAYBE_Connect) {
EXPECT_FALSE(sock->IsConnected());
}
-TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) {
- StartExpiredServer();
-
+// bug 1354783
+TEST_F(SSLClientSocketTest, DISABLED_Read) {
net::AddressList addr;
net::HostResolver resolver;
TestCompletionCallback 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);
+ std::string hostname = "bugs.webkit.org";
+ int rv = resolver.Resolve(hostname, 443, &addr, &callback);
EXPECT_EQ(net::ERR_IO_PENDING, rv);
rv = callback.WaitForResult();
@@ -182,8 +83,7 @@ TEST_F(SSLClientSocketTest, MAYBE_Read) {
scoped_ptr<net::SSLClientSocket> sock(
socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr),
- server_.kHostName,
- kDefaultSSLConfig));
+ hostname, kDefaultSSLConfig));
rv = sock->Connect(&callback);
if (rv != net::OK) {
@@ -217,20 +117,19 @@ TEST_F(SSLClientSocketTest, MAYBE_Read) {
}
}
-TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) {
- StartOKServer();
-
+// bug 1354783
+TEST_F(SSLClientSocketTest, DISABLED_Read_SmallChunks) {
net::AddressList addr;
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL);
+ std::string hostname = "bugs.webkit.org";
+ int rv = resolver.Resolve(hostname, 443, &addr, NULL);
EXPECT_EQ(net::OK, rv);
scoped_ptr<net::SSLClientSocket> sock(
socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr),
- server_.kHostName, kDefaultSSLConfig));
+ hostname, kDefaultSSLConfig));
rv = sock->Connect(&callback);
if (rv != net::OK) {
@@ -263,20 +162,19 @@ TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) {
}
}
-TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) {
- StartOKServer();
-
+// bug 1354783
+TEST_F(SSLClientSocketTest, DISABLED_Read_Interrupted) {
net::AddressList addr;
net::HostResolver resolver;
TestCompletionCallback callback;
- int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort,
- &addr, NULL);
+ std::string hostname = "bugs.webkit.org";
+ int rv = resolver.Resolve(hostname, 443, &addr, NULL);
EXPECT_EQ(net::OK, rv);
scoped_ptr<net::SSLClientSocket> sock(
socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr),
- server_.kHostName, kDefaultSSLConfig));
+ hostname, 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 a6ad137..d22e4fd 100644
--- a/net/base/ssl_test_util.cc
+++ b/net/base/ssl_test_util.cc
@@ -5,8 +5,6 @@
#include <string>
#include <algorithm>
-#include "net/base/ssl_test_util.h"
-
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -29,15 +27,16 @@
#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"
-namespace {
+#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";
#if defined(OS_LINUX)
static CERTCertificate* LoadTemporaryCert(const FilePath& filename) {
@@ -68,231 +67,57 @@ 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;
}
- // TODO(dkegel): figure out how to get this to only happen once?
+ LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack();
return cert;
}
#endif
-} // 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_(NULL)
-#endif
-{
- PathService::Get(base::DIR_SOURCE_ROOT, &data_dir_);
- data_dir_ = data_dir_.Append(FILE_PATH_LITERAL("net"))
- .Append(FILE_PATH_LITERAL("data"))
- .Append(FILE_PATH_LITERAL("ssl"));
- cert_dir_ = data_dir_.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 (!TestServerLauncher::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"));
-
- FilePath test_data_directory;
- PathService::Get(base::DIR_SOURCE_ROOT, &test_data_directory);
- test_data_directory = test_data_directory.Append(document_root);
+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");
#if defined(OS_LINUX)
- if (!cert_ && !cert_path.value().empty()) {
- cert_ = reinterpret_cast<PrivateCERTCertificate*>(
+ cert_ = reinterpret_cast<PrivateCERTCertificate*>(
LoadTemporaryCert(GetRootCertPath()));
- DCHECK(cert_);
- }
+ DCHECK(cert_);
#endif
-
- 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=\"" + test_data_directory.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(test_data_directory.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 (!Wait(host_name, port)) {
- LOG(ERROR) << "Failed to connect to server";
- Stop();
- return false;
- }
-
- LOG(INFO) << "Started on port " << port_str;
- return true;
-}
-
-bool TestServerLauncher::Wait(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;
-}
-
-void TestServerLauncher::Stop() {
- if (!process_handle_)
- return;
-
- base::KillProcess(process_handle_, 1, true);
-
-#if defined(OS_WIN)
- CloseHandle(process_handle_);
-#endif
-
- process_handle_ = NULL;
- LOG(INFO) << "Stopped.";
}
-TestServerLauncher::~TestServerLauncher() {
+SSLTestUtil::~SSLTestUtil() {
#if defined(OS_LINUX)
if (cert_)
CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_));
#endif
- Stop();
}
-FilePath TestServerLauncher::GetRootCertPath() {
+FilePath SSLTestUtil::GetRootCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("root_ca_cert.crt");
return path;
}
-FilePath TestServerLauncher::GetOKCertPath() {
+FilePath SSLTestUtil::GetOKCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("ok_cert.pem");
return path;
}
-FilePath TestServerLauncher::GetExpiredCertPath() {
+FilePath SSLTestUtil::GetExpiredCertPath() {
FilePath path(cert_dir_);
path = path.AppendASCII("expired_cert.pem");
return path;
}
-bool TestServerLauncher::CheckCATrusted() {
+bool SSLTestUtil::CheckCATrusted() {
// TODO(port): Port either this or LoadTemporaryCert to MacOSX.
#if defined(OS_WIN)
HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT");
@@ -321,6 +146,3 @@ bool TestServerLauncher::CheckCATrusted() {
#endif
return true;
}
-
-} // namespace net
-
diff --git a/net/base/ssl_test_util.h b/net/base/ssl_test_util.h
index dd6d95d..9daa4cc 100644
--- a/net/base/ssl_test_util.h
+++ b/net/base/ssl_test_util.h
@@ -5,98 +5,49 @@
#ifndef NET_BASE_SSL_TEST_UTIL_H_
#define NET_BASE_SSL_TEST_UTIL_H_
-#include <string>
+#include "build/build_config.h"
#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
-namespace net {
-
-// 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 {
+class SSLTestUtil {
public:
- TestServerLauncher();
-
- virtual ~TestServerLauncher();
-
- enum Protocol {
- ProtoHTTP, ProtoFTP
- };
+ SSLTestUtil();
- // Start src/net/tools/test_server/test_server.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);
+ ~SSLTestUtil();
- // Stop the server started by Start().
- void Stop();
+ FilePath GetRootCertPath();
- // Paths to a good, an expired, and an invalid server certificate
- // (use as arguments to Start()).
FilePath GetOKCertPath();
- FilePath GetExpiredCertPath();
- // Issuer name of the root cert that should be trusted for the test to work.
- static const wchar_t kCertIssuerName[];
+ FilePath GetExpiredCertPath();
// 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;
- private:
- // Wait a while for the server to start, return whether
- // we were able to make a connection to it.
- bool Wait(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();
+ // Issuer name of the cert that should be trusted for the test to work.
+ static const wchar_t kCertIssuerName[];
// Returns false if our test root certificate is not trusted.
bool CheckCATrusted();
- FilePath data_dir_;
-
+ private:
FilePath cert_dir_;
- FilePath python_runtime_;
-
- base::ProcessHandle process_handle_;
-
#if defined(OS_LINUX)
struct PrivateCERTCertificate;
PrivateCERTCertificate *cert_;
#endif
- DISALLOW_COPY_AND_ASSIGN(TestServerLauncher);
+ DISALLOW_COPY_AND_ASSIGN(SSLTestUtil);
};
-}
-
-#endif // NET_BASE_SSL_TEST_UTIL_H_
-
+#endif // NET_BASE_SSL_TEST_UTIL_H_
diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj
index 738879f..2323492e 100644
--- a/net/build/net_unittests.vcproj
+++ b/net/build/net_unittests.vcproj
@@ -367,10 +367,6 @@
>
</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 42a1750..37df32e 100644
--- a/net/net.xcodeproj/project.pbxproj
+++ b/net/net.xcodeproj/project.pbxproj
@@ -52,8 +52,6 @@
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 */; };
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 */; };
4D4C5C070EF1B915002CA805 /* http_cache_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33550E5A194700A747DB /* http_cache_unittest.cc */; };
@@ -157,6 +155,7 @@
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 */; };
@@ -441,8 +440,6 @@
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; };
4D4C5C050EF1B8C5002CA805 /* filter_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filter_unittest.cc; sourceTree = "<group>"; };
@@ -686,6 +683,8 @@
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>"; };
@@ -913,7 +912,6 @@
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 */,
@@ -994,7 +992,8 @@
7BED32930E5A181C00A747DB /* ssl_config_service.h */,
7BED32920E5A181C00A747DB /* ssl_config_service_unittest.cc */,
7BED32910E5A181C00A747DB /* ssl_info.h */,
- 07B79D480F4221D7001EA432 /* ssl_test_util.cc */,
+ 826F15760EE48CEA00D973C7 /* ssl_test_util.cc */,
+ 826F15750EE48CEA00D973C7 /* ssl_test_util.h */,
7BED328F0E5A181C00A747DB /* tcp_client_socket.h */,
E47E933E0E8924DC00CA613E /* tcp_client_socket_libevent.cc */,
7BED328E0E5A181C00A747DB /* tcp_client_socket_unittest.cc */,
@@ -1528,14 +1527,12 @@
533102E70E5E3EBF00FF8E32 /* net_util_posix.cc in Sources */,
7B85043C0E5B2E6400730B43 /* platform_mime_util_mac.cc in Sources */,
820701040EB6611F005CD9E7 /* proxy_resolver_mac.cc in Sources */,
- 043C23DB0EFC592900658F5E /* proxy_script_fetcher.cc in Sources */,
E49DD3370E8933A2003C7A87 /* proxy_service.cc in Sources */,
7B85043D0E5B2E6400730B43 /* rankings.cc in Sources */,
7B8B5B560E5CEADE002F9A97 /* registry_controlled_domain.cc in Sources */,
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 */,
@@ -1559,6 +1556,7 @@
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;
};
@@ -1572,7 +1570,6 @@
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 */,
@@ -1603,18 +1600,19 @@
7B4DF9AC0E5C906A004D7619 /* mime_sniffer_unittest.cc in Sources */,
048268090E5B3B4800A30786 /* mime_util_unittest.cc in Sources */,
BAA46E3B0E5CE99A00E77460 /* net_util_unittest.cc in Sources */,
- 043C23D90EFC592000658F5E /* proxy_script_fetcher_unittest.cc in Sources */,
7BA361ED0E8C38D30023C8B9 /* proxy_service_unittest.cc in Sources */,
7B8B5B9E0E5D188E002F9A97 /* registry_controlled_domain_unittest.cc in Sources */,
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 05712ce..4f35414 100644
--- a/net/net_unittests.scons
+++ b/net/net_unittests.scons
@@ -76,7 +76,6 @@ 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 4ab4285..21d1c72 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -180,14 +180,17 @@ TEST_F(URLRequestTest, GetTest) {
}
class HTTPSRequestTest : public testing::Test {
+ protected:
+ HTTPSRequestTest() : util_() {}
+
+ SSLTestUtil util_;
};
#if defined(OS_MACOSX)
-// ssl_client_socket_mac.cc crashes currently in GetSSLInfo
-// when called on a connection with an unrecognized certificate
-#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest
+// TODO(port): support temporary root cert on mac
+#define MAYBE_HTTPSGetTest DISABLED_HTTPSGetTest
#else
-#define MAYBE_HTTPSGetTest HTTPSGetTest
+#define MAYBE_HTTPSGetTest HTTPSGetTest
#endif
TEST_F(HTTPSRequestTest, MAYBE_HTTPSGetTest) {
@@ -196,9 +199,11 @@ 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::CreateGoodServer(L"net/data/ssl");
+ HTTPSTestServer::CreateServer(util_.kHostName, util_.kOKHTTPSPort,
+ L"net/data/ssl", util_.GetOKCertPath().ToWStringHack());
ASSERT_TRUE(NULL != server.get());
+ EXPECT_TRUE(util_.CheckCATrusted());
TestDelegate d;
{
TestURLRequest r(server->TestServerPage(""), &d);
@@ -217,8 +222,6 @@ 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 e6f4da6..7107d50 100644
--- a/net/url_request/url_request_unittest.h
+++ b/net/url_request/url_request_unittest.h
@@ -13,7 +13,6 @@
#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"
@@ -24,7 +23,6 @@
#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/proxy/proxy_service.h"
@@ -212,9 +210,48 @@ class TestDelegate : public URLRequest::Delegate {
// that can provide various responses useful for testing.
class BaseTestServer : public base::RefCounted<BaseTestServer> {
protected:
- BaseTestServer() { }
+ BaseTestServer()
+ : process_handle_(NULL) {
+ }
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;
+ }
+ }
+
+ 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 ret;
+ }
+
GURL TestServerPage(const std::string& base_address,
const std::string& path) {
return GURL(base_address + path);
@@ -228,50 +265,142 @@ class BaseTestServer : public base::RefCounted<BaseTestServer> {
return GURL(base_address_ + WideToUTF8(path));
}
- virtual bool MakeGETRequest(const std::string& page_name) = 0;
+ 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());
+ }
- 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;
+ 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::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 + "/";
+ 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_ + "/";
} 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 + "/";
+ 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);
}
+ 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:
@@ -294,13 +423,18 @@ 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) {
@@ -313,16 +447,37 @@ class HTTPTestServer : public BaseTestServer {
MessageLoop* loop) {
HTTPTestServer* test_server = new HTTPTestServer();
test_server->loop_ = loop;
- FilePath no_cert;
- FilePath docroot = FilePath::FromWStringHack(document_root);
- if (!test_server->Start(net::TestServerLauncher::ProtoHTTP,
- kDefaultHostName, kHTTPDefaultPort, docroot, no_cert)) {
+ if (!test_server->Init(kDefaultHostName, kHTTPDefaultPort, document_root)) {
delete test_server;
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);
@@ -361,8 +516,54 @@ 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
+ // is being cached rather than being executed on the server
+ std::string page_name = StringPrintf("kill?%u",
+ static_cast<int>(base::Time::Now().ToInternalValue()));
+ int retry_count = 5;
+ while (retry_count > 0) {
+ bool r = MakeGETRequest(page_name);
+ // BUG #1048625 causes the kill GET to fail. For now we just retry.
+ // Once the bug is fixed, we should remove the while loop and put back
+ // the following DCHECK.
+ // DCHECK(r);
+ if (r)
+ break;
+ retry_count--;
+ }
+ // Make sure we were successfull 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.
@@ -371,75 +572,51 @@ class HTTPTestServer : public BaseTestServer {
class HTTPSTestServer : public HTTPTestServer {
protected:
- explicit HTTPSTestServer() {
+ explicit HTTPSTestServer(const std::wstring& cert_path)
+ : cert_path_(cert_path) {
}
public:
- // 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)) {
- delete test_server;
- 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)) {
- delete test_server;
- 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)) {
- delete test_server;
- return NULL;
- }
- return test_server;
- }
-
- // 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)) {
+ HTTPSTestServer* test_server = new HTTPSTestServer(cert_path);
+ if (!test_server->Init(host_name, port, document_root)) {
delete test_server;
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"\"");
+ }
+ }
+#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() {
}
@@ -449,32 +626,88 @@ class HTTPSTestServer : public HTTPTestServer {
class FTPTestServer : public BaseTestServer {
- public:
+ protected:
FTPTestServer() {
}
+ public:
+ FTPTestServer(const std::string& url_user, const std::string& url_password) {
+ url_user_ = url_user;
+ url_password_ = url_password;
+ }
+
static FTPTestServer* CreateServer(const std::wstring& document_root) {
- std::string blank;
- return CreateServer(document_root, blank, blank);
+ FTPTestServer* test_server = new FTPTestServer();
+ if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) {
+ delete test_server;
+ return NULL;
+ }
+ return test_server;
}
static FTPTestServer* CreateServer(const std::wstring& document_root,
const std::string& url_user,
const std::string& url_password) {
- 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)) {
+ FTPTestServer* test_server = new FTPTestServer(url_user, url_password);
+ if (!test_server->Init(kDefaultHostName, kFTPDefaultPort, document_root)) {
delete test_server;
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 GURL& url = TestServerPage(base_address_, page_name);
+ const std::string base_address = scheme() + "://" + host_name_ + ":" +
+ port_str_ + "/";
+ const GURL& url = TestServerPage(base_address, page_name);
TestDelegate d;
URLRequest request(url, &d);
request.set_context(new TestURLRequestContext());
@@ -489,6 +722,26 @@ 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_