Delete unused classes AutoDetectProxy and SslSocketFactory.

SslSocketFactory is unused since https://codereview.webrtc.org/2506983002, and it's the last
user of AutoDetectProxy.

Also move HttpListenServer and SocksProxyServer to the rtc_base_tests_utils gn target, since they're used by tests only.

BUG=webrtc:6424

Review-Url: https://codereview.webrtc.org/2541453002
Cr-Commit-Position: refs/heads/master@{#16576}
This commit is contained in:
nisse
2017-02-13 04:33:28 -08:00
committed by Commit bot
parent 375b9ac4cc
commit 1458462303
10 changed files with 4 additions and 2351 deletions

View File

@ -378,8 +378,6 @@ rtc_static_library("rtc_base") {
"asynctcpsocket.h",
"asyncudpsocket.cc",
"asyncudpsocket.h",
"autodetectproxy.cc",
"autodetectproxy.h",
"common.cc",
"common.h",
"crc32.cc",
@ -429,8 +427,6 @@ rtc_static_library("rtc_base") {
"opensslstreamadapter.h",
"physicalsocketserver.cc",
"physicalsocketserver.h",
"proxydetect.cc",
"proxydetect.h",
"proxyinfo.cc",
"proxyinfo.h",
"ratelimiter.cc",
@ -469,8 +465,6 @@ rtc_static_library("rtc_base") {
"sslfingerprint.h",
"sslidentity.cc",
"sslidentity.h",
"sslsocketfactory.cc",
"sslsocketfactory.h",
"sslstreamadapter.cc",
"sslstreamadapter.h",
"stream.cc",
@ -504,8 +498,6 @@ rtc_static_library("rtc_base") {
sources += [
"callback.h",
"fileutils_mock.h",
"httpserver.cc",
"httpserver.h",
"json.cc",
"json.h",
"logsinks.cc",
@ -513,8 +505,6 @@ rtc_static_library("rtc_base") {
"mathutils.h",
"optionsfile.cc",
"optionsfile.h",
"proxyserver.cc",
"proxyserver.h",
"rollingaccumulator.h",
"scopedptrcollection.h",
"sslroots.h",
@ -710,12 +700,16 @@ if (rtc_include_tests) {
"firewallsocketserver.cc",
"firewallsocketserver.h",
"gunit.h",
"httpserver.cc",
"httpserver.h",
"natserver.cc",
"natserver.h",
"natsocketfactory.cc",
"natsocketfactory.h",
"nattypes.cc",
"nattypes.h",
"proxyserver.cc",
"proxyserver.h",
"sigslottester.h",
"sigslottester.h.pump",
"testbase64.h",
@ -853,7 +847,6 @@ if (rtc_include_tests) {
rtc_source_set("rtc_base_unittests") {
testonly = true
sources = [
"autodetectproxy_unittest.cc",
"callback_unittest.cc",
"crc32_unittest.cc",
"filerotatingstream_unittest.cc",
@ -869,7 +862,6 @@ if (rtc_include_tests) {
"network_unittest.cc",
"optionsfile_unittest.cc",
"proxy_unittest.cc",
"proxydetect_unittest.cc",
"ratelimiter_unittest.cc",
"rollingaccumulator_unittest.cc",
"rtccertificate_unittest.cc",

View File

@ -1,302 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/autodetectproxy.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/httpcommon.h"
#include "webrtc/base/httpcommon-inl.h"
#include "webrtc/base/nethelpers.h"
namespace rtc {
static const ProxyType TEST_ORDER[] = {
PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
};
static const int kSavedStringLimit = 128;
static void SaveStringToStack(char *dst,
const std::string &src,
size_t dst_size) {
strncpy(dst, src.c_str(), dst_size - 1);
dst[dst_size - 1] = '\0';
}
AutoDetectProxy::AutoDetectProxy(const std::string& user_agent)
: agent_(user_agent), resolver_(NULL), socket_(NULL), next_(0) {
}
bool AutoDetectProxy::GetProxyForUrl(const char* agent,
const char* url,
rtc::ProxyInfo* proxy) {
return GetProxySettingsForUrl(agent, url, proxy, true);
}
AutoDetectProxy::~AutoDetectProxy() {
if (resolver_) {
resolver_->Destroy(false);
}
}
void AutoDetectProxy::DoWork() {
// TODO: Try connecting to server_url without proxy first here?
if (!server_url_.empty()) {
LOG(LS_INFO) << "GetProxySettingsForUrl(" << server_url_ << ") - start";
GetProxyForUrl(agent_.c_str(), server_url_.c_str(), &proxy_);
LOG(LS_INFO) << "GetProxySettingsForUrl - stop";
}
Url<char> url(proxy_.address.HostAsURIString());
if (url.valid()) {
LOG(LS_WARNING) << "AutoDetectProxy removing http prefix on proxy host";
proxy_.address.SetIP(url.host());
}
LOG(LS_INFO) << "AutoDetectProxy found proxy at " << proxy_.address;
if (proxy_.type == PROXY_UNKNOWN) {
LOG(LS_INFO) << "AutoDetectProxy initiating proxy classification";
Next();
// Process I/O until Stop()
Thread::Current()->ProcessMessages(Thread::kForever);
// Clean up the autodetect socket, from the thread that created it
delete socket_;
}
// TODO: If we found a proxy, try to use it to verify that it
// works by sending a request to server_url. This could either be
// done here or by the HttpPortAllocator.
}
void AutoDetectProxy::OnMessage(Message *msg) {
if (MSG_UNRESOLVABLE == msg->message_id) {
// If we can't resolve the proxy, skip straight to failure.
Complete(PROXY_UNKNOWN);
} else if (MSG_TIMEOUT == msg->message_id) {
OnTimeout();
} else {
// This must be the ST_MSG_WORKER_DONE message that deletes the
// AutoDetectProxy object. We have observed crashes within this stack that
// seem to be highly reproducible for a small subset of users and thus are
// probably correlated with a specific proxy setting, so copy potentially
// relevant information onto the stack to make it available in Windows
// minidumps.
// Save the user agent and the number of auto-detection passes that we
// needed.
char agent[kSavedStringLimit];
SaveStringToStack(agent, agent_, sizeof agent);
int next = next_;
// Now the detected proxy config (minus the password field, which could be
// sensitive).
ProxyType type = proxy().type;
char address_hostname[kSavedStringLimit];
SaveStringToStack(address_hostname,
proxy().address.hostname(),
sizeof address_hostname);
IPAddress address_ip = proxy().address.ipaddr();
uint16_t address_port = proxy().address.port();
char autoconfig_url[kSavedStringLimit];
SaveStringToStack(autoconfig_url,
proxy().autoconfig_url,
sizeof autoconfig_url);
bool autodetect = proxy().autodetect;
char bypass_list[kSavedStringLimit];
SaveStringToStack(bypass_list, proxy().bypass_list, sizeof bypass_list);
char username[kSavedStringLimit];
SaveStringToStack(username, proxy().username, sizeof username);
SignalThread::OnMessage(msg);
// Log the gathered data at a log level that will never actually be enabled
// so that the compiler is forced to retain the data on the stack.
LOG(LS_SENSITIVE) << agent << " " << next << " " << type << " "
<< address_hostname << " " << address_ip << " "
<< address_port << " " << autoconfig_url << " "
<< autodetect << " " << bypass_list << " " << username;
}
}
void AutoDetectProxy::OnResolveResult(AsyncResolverInterface* resolver) {
if (resolver != resolver_) {
return;
}
int error = resolver_->GetError();
if (error == 0) {
LOG(LS_VERBOSE) << "Resolved " << proxy_.address << " to "
<< resolver_->address();
proxy_.address = resolver_->address();
if (!DoConnect()) {
Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TIMEOUT);
}
} else {
LOG(LS_INFO) << "Failed to resolve " << resolver_->address();
resolver_->Destroy(false);
resolver_ = NULL;
proxy_.address = SocketAddress();
Thread::Current()->Post(RTC_FROM_HERE, this, MSG_UNRESOLVABLE);
}
}
void AutoDetectProxy::Next() {
if (TEST_ORDER[next_] >= PROXY_UNKNOWN) {
Complete(PROXY_UNKNOWN);
return;
}
LOG(LS_VERBOSE) << "AutoDetectProxy connecting to "
<< proxy_.address.ToSensitiveString();
if (socket_) {
Thread::Current()->Clear(this, MSG_TIMEOUT);
Thread::Current()->Clear(this, MSG_UNRESOLVABLE);
socket_->Close();
Thread::Current()->Dispose(socket_);
socket_ = NULL;
}
int timeout = 2000;
if (proxy_.address.IsUnresolvedIP()) {
// Launch an asyncresolver. This thread will spin waiting for it.
timeout += 2000;
if (!resolver_) {
resolver_ = new AsyncResolver();
}
resolver_->SignalDone.connect(this, &AutoDetectProxy::OnResolveResult);
resolver_->Start(proxy_.address);
} else {
if (!DoConnect()) {
Thread::Current()->Post(RTC_FROM_HERE, this, MSG_TIMEOUT);
return;
}
}
Thread::Current()->PostDelayed(RTC_FROM_HERE, timeout, this, MSG_TIMEOUT);
}
bool AutoDetectProxy::DoConnect() {
if (resolver_) {
resolver_->Destroy(false);
resolver_ = NULL;
}
socket_ =
Thread::Current()->socketserver()->CreateAsyncSocket(
proxy_.address.family(), SOCK_STREAM);
if (!socket_) {
LOG(LS_VERBOSE) << "Unable to create socket for " << proxy_.address;
return false;
}
socket_->SignalConnectEvent.connect(this, &AutoDetectProxy::OnConnectEvent);
socket_->SignalReadEvent.connect(this, &AutoDetectProxy::OnReadEvent);
socket_->SignalCloseEvent.connect(this, &AutoDetectProxy::OnCloseEvent);
socket_->Connect(proxy_.address);
return true;
}
void AutoDetectProxy::Complete(ProxyType type) {
Thread::Current()->Clear(this, MSG_TIMEOUT);
Thread::Current()->Clear(this, MSG_UNRESOLVABLE);
if (socket_) {
socket_->Close();
}
proxy_.type = type;
LoggingSeverity sev = (proxy_.type == PROXY_UNKNOWN) ? LS_ERROR : LS_INFO;
LOG_V(sev) << "AutoDetectProxy detected "
<< proxy_.address.ToSensitiveString()
<< " as type " << proxy_.type;
Thread::Current()->Quit();
}
void AutoDetectProxy::OnConnectEvent(AsyncSocket * socket) {
std::string probe;
switch (TEST_ORDER[next_]) {
case PROXY_HTTPS:
probe.assign("CONNECT www.google.com:443 HTTP/1.0\r\n"
"User-Agent: ");
probe.append(agent_);
probe.append("\r\n"
"Host: www.google.com\r\n"
"Content-Length: 0\r\n"
"Proxy-Connection: Keep-Alive\r\n"
"\r\n");
break;
case PROXY_SOCKS5:
probe.assign("\005\001\000", 3);
break;
default:
RTC_NOTREACHED();
return;
}
LOG(LS_VERBOSE) << "AutoDetectProxy probing type " << TEST_ORDER[next_]
<< " sending " << probe.size() << " bytes";
socket_->Send(probe.data(), probe.size());
}
void AutoDetectProxy::OnReadEvent(AsyncSocket * socket) {
char data[257];
int len = socket_->Recv(data, 256, nullptr);
if (len > 0) {
data[len] = 0;
LOG(LS_VERBOSE) << "AutoDetectProxy read " << len << " bytes";
}
switch (TEST_ORDER[next_]) {
case PROXY_HTTPS:
if ((len >= 2) && (data[0] == '\x05')) {
Complete(PROXY_SOCKS5);
return;
}
if ((len >= 5) && (strncmp(data, "HTTP/", 5) == 0)) {
Complete(PROXY_HTTPS);
return;
}
break;
case PROXY_SOCKS5:
if ((len >= 2) && (data[0] == '\x05')) {
Complete(PROXY_SOCKS5);
return;
}
break;
default:
RTC_NOTREACHED();
return;
}
++next_;
Next();
}
void AutoDetectProxy::OnTimeout() {
LOG(LS_VERBOSE) << "Timed out waiting for AsyncResolver.";
// If a resolver timed out we shouldn't try to use it again since it may be
// in the middle of resolving the last address.
if (resolver_) {
resolver_->SignalDone.disconnect(this);
resolver_->Destroy(false);
resolver_ = nullptr;
}
++next_;
Next();
}
void AutoDetectProxy::OnCloseEvent(AsyncSocket * socket, int error) {
LOG(LS_VERBOSE) << "AutoDetectProxy closed with error: " << error;
++next_;
Next();
}
} // namespace rtc

View File

@ -1,90 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_AUTODETECTPROXY_H_
#define WEBRTC_BASE_AUTODETECTPROXY_H_
#include <string>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/cryptstring.h"
#include "webrtc/base/proxydetect.h"
#include "webrtc/base/proxyinfo.h"
#include "webrtc/base/signalthread.h"
namespace rtc {
///////////////////////////////////////////////////////////////////////////////
// AutoDetectProxy
///////////////////////////////////////////////////////////////////////////////
class AsyncResolverInterface;
class AsyncSocket;
class AutoDetectProxy : public SignalThread {
public:
explicit AutoDetectProxy(const std::string& user_agent);
const ProxyInfo& proxy() const { return proxy_; }
void set_server_url(const std::string& url) {
server_url_ = url;
}
void set_proxy(const SocketAddress& proxy) {
proxy_.type = PROXY_UNKNOWN;
proxy_.address = proxy;
}
void set_auth_info(bool use_auth, const std::string& username,
const CryptString& password) {
if (use_auth) {
proxy_.username = username;
proxy_.password = password;
}
}
// Default implementation of GetProxySettingsForUrl. Override for special
// implementation.
virtual bool GetProxyForUrl(const char* agent,
const char* url,
rtc::ProxyInfo* proxy);
enum { MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE,
MSG_UNRESOLVABLE,
ADP_MSG_FIRST_AVAILABLE};
protected:
~AutoDetectProxy() override;
// SignalThread Interface
void DoWork() override;
void OnMessage(Message* msg) override;
void Next();
void Complete(ProxyType type);
void OnConnectEvent(AsyncSocket * socket);
void OnReadEvent(AsyncSocket * socket);
void OnCloseEvent(AsyncSocket * socket, int error);
void OnTimeout();
void OnResolveResult(AsyncResolverInterface* resolver);
bool DoConnect();
private:
std::string agent_;
std::string server_url_;
ProxyInfo proxy_;
AsyncResolverInterface* resolver_;
AsyncSocket* socket_;
int next_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AutoDetectProxy);
};
} // namespace rtc
#endif // WEBRTC_BASE_AUTODETECTPROXY_H_

View File

@ -1,131 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/autodetectproxy.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/httpcommon.h"
#include "webrtc/base/httpcommon-inl.h"
namespace rtc {
static const char kUserAgent[] = "";
static const char kPath[] = "/";
static const char kHost[] = "relay.google.com";
static const uint16_t kPort = 443;
static const bool kSecure = true;
// At most, AutoDetectProxy should take ~6 seconds. Each connect step is
// allotted 2 seconds, with the initial resolution + connect given an
// extra 2 seconds. The slowest case is:
// 1) Resolution + HTTPS takes full 4 seconds and fails (but resolution
// succeeds).
// 2) SOCKS5 takes the full 2 seconds.
// Socket creation time seems unbounded, and has been observed to take >1 second
// on a linux machine under load. As such, we allow for 10 seconds for timeout,
// though could still end up with some flakiness.
static const int kTimeoutMs = 10000;
class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> {
public:
AutoDetectProxyTest() : auto_detect_proxy_(NULL), done_(false) {}
protected:
bool Create(const std::string& user_agent,
const std::string& path,
const std::string& host,
uint16_t port,
bool secure,
bool startnow) {
auto_detect_proxy_ = new AutoDetectProxy(user_agent);
EXPECT_TRUE(auto_detect_proxy_ != NULL);
if (!auto_detect_proxy_) {
return false;
}
Url<char> host_url(path, host, port);
host_url.set_secure(secure);
auto_detect_proxy_->set_server_url(host_url.url());
auto_detect_proxy_->SignalWorkDone.connect(
this,
&AutoDetectProxyTest::OnWorkDone);
if (startnow) {
auto_detect_proxy_->Start();
}
return true;
}
bool Run(int timeout_ms) {
EXPECT_TRUE_WAIT(done_, timeout_ms);
return done_;
}
void SetProxy(const SocketAddress& proxy) {
auto_detect_proxy_->set_proxy(proxy);
}
void Start() {
auto_detect_proxy_->Start();
}
void TestCopesWithProxy(const SocketAddress& proxy) {
// Tests that at least autodetect doesn't crash for a given proxy address.
ASSERT_TRUE(Create(kUserAgent,
kPath,
kHost,
kPort,
kSecure,
false));
SetProxy(proxy);
Start();
ASSERT_TRUE(Run(kTimeoutMs));
}
private:
void OnWorkDone(rtc::SignalThread *thread) {
AutoDetectProxy *auto_detect_proxy =
static_cast<rtc::AutoDetectProxy *>(thread);
EXPECT_TRUE(auto_detect_proxy == auto_detect_proxy_);
auto_detect_proxy_ = NULL;
auto_detect_proxy->Release();
done_ = true;
}
AutoDetectProxy *auto_detect_proxy_;
bool done_;
};
TEST_F(AutoDetectProxyTest, TestDetectUnresolvedProxy) {
TestCopesWithProxy(rtc::SocketAddress("localhost", 9999));
}
TEST_F(AutoDetectProxyTest, TestDetectUnresolvableProxy) {
TestCopesWithProxy(rtc::SocketAddress("invalid", 9999));
}
TEST_F(AutoDetectProxyTest, TestDetectIPv6Proxy) {
TestCopesWithProxy(rtc::SocketAddress("::1", 9999));
}
TEST_F(AutoDetectProxyTest, TestDetectIPv4Proxy) {
TestCopesWithProxy(rtc::SocketAddress("127.0.0.1", 9999));
}
// Test that proxy detection completes successfully. (Does not actually verify
// the correct detection result since we don't know what proxy to expect on an
// arbitrary machine.)
TEST_F(AutoDetectProxyTest, TestProxyDetection) {
ASSERT_TRUE(Create(kUserAgent,
kPath,
kHost,
kPort,
kSecure,
true));
ASSERT_TRUE(Run(kTimeoutMs));
}
} // namespace rtc

View File

@ -10,7 +10,6 @@
#include <memory>
#include <string>
#include "webrtc/base/autodetectproxy.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/httpserver.h"
#include "webrtc/base/proxyserver.h"
@ -29,18 +28,6 @@ static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443);
static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0);
static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999);
// Used to run a proxy detect on the current thread. Otherwise we would need
// to make both threads share the same VirtualSocketServer.
class AutoDetectProxyRunner : public rtc::AutoDetectProxy {
public:
explicit AutoDetectProxyRunner(const std::string& agent)
: AutoDetectProxy(agent) {}
void Run() {
DoWork();
Thread::Current()->Restart(); // needed to reset the messagequeue
}
};
// Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers.
class ProxyTest : public testing::Test {
public:
@ -57,16 +44,6 @@ class ProxyTest : public testing::Test {
rtc::SocketServer* ss() { return ss_.get(); }
rtc::ProxyType DetectProxyType(const SocketAddress& address) {
rtc::ProxyType type;
AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0");
detect->set_proxy(address);
detect->Run(); // blocks until done
type = detect->proxy().type;
detect->Destroy(false);
return type;
}
private:
std::unique_ptr<rtc::SocketServer> ss_;
std::unique_ptr<rtc::SocksProxyServer> socks_;
@ -99,38 +76,3 @@ TEST_F(ProxyTest, TestSocks5Connect) {
EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
EXPECT_TRUE(client.CheckNoPacket());
}
/*
// Tests whether we can use a HTTPS proxy to connect to a server.
TEST_F(ProxyTest, TestHttpsConnect) {
AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM);
AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket(
socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString());
TestClient client(new AsyncTCPSocket(proxy_socket));
TestEchoServer server(Thread::Current(), SocketAddress());
EXPECT_TRUE(client.Connect(server.address()));
EXPECT_TRUE(client.CheckConnected());
EXPECT_EQ(server.address(), client.remote_address());
client.Send("foo", 3);
EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
EXPECT_TRUE(client.CheckNoPacket());
}
*/
// Tests whether we can autodetect a SOCKS5 proxy.
TEST_F(ProxyTest, TestAutoDetectSocks5) {
EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr));
}
/*
// Tests whether we can autodetect a HTTPS proxy.
TEST_F(ProxyTest, TestAutoDetectHttps) {
EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr));
}
*/
// Tests whether we fail properly for no proxy.
TEST_F(ProxyTest, TestAutoDetectBogus) {
EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr));
}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
/*
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef _PROXYDETECT_H_
#define _PROXYDETECT_H_
#include "webrtc/base/proxyinfo.h"
namespace rtc {
// Auto-detect the proxy server. Returns true if a proxy is configured,
// although hostname may be empty if the proxy is not required for
// the given URL.
bool GetProxySettingsForUrl(const char* agent, const char* url,
rtc::ProxyInfo* proxy,
bool long_operation = false);
} // namespace rtc
#endif // _PROXYDETECT_H_

View File

@ -1,164 +0,0 @@
/*
* Copyright 2010 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#include "webrtc/base/fileutils_mock.h"
#include "webrtc/base/proxydetect.h"
namespace rtc {
static const std::string kFirefoxProfilesIni =
"[Profile0]\n"
"Name=default\n"
"IsRelative=1\n"
"Path=Profiles/2de53ejb.default\n"
"Default=1\n";
static const std::string kFirefoxHeader =
"# Mozilla User Preferences\n"
"\n"
"/* Some Comments\n"
"*\n"
"*/\n"
"\n";
static const std::string kFirefoxCorruptHeader =
"iuahueqe32164";
static const std::string kProxyAddress = "proxy.net.com";
// Mocking out platform specific path to firefox prefs file.
class FirefoxPrefsFileSystem : public FakeFileSystem {
public:
explicit FirefoxPrefsFileSystem(const std::vector<File>& all_files) :
FakeFileSystem(all_files) {
}
virtual FileStream* OpenFile(const Pathname& filename,
const std::string& mode) {
// TODO: We could have a platform dependent check of paths here.
std::string name = filename.basename();
name.append(filename.extension());
EXPECT_TRUE(name.compare("prefs.js") == 0 ||
name.compare("profiles.ini") == 0);
FileStream* stream = FakeFileSystem::OpenFile(name, mode);
return stream;
}
};
class ProxyDetectTest : public testing::Test {
};
bool GetProxyInfo(const std::string prefs, ProxyInfo* info) {
std::vector<rtc::FakeFileSystem::File> files;
files.push_back(rtc::FakeFileSystem::File("profiles.ini",
kFirefoxProfilesIni));
files.push_back(rtc::FakeFileSystem::File("prefs.js", prefs));
rtc::FilesystemScope fs(new rtc::FirefoxPrefsFileSystem(files));
return GetProxySettingsForUrl("Firefox", "www.google.com", info, false);
}
// Verifies that an empty Firefox prefs file results in no proxy detected.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxEmptyPrefs) {
ProxyInfo proxy_info;
EXPECT_TRUE(GetProxyInfo(kFirefoxHeader, &proxy_info));
EXPECT_EQ(PROXY_NONE, proxy_info.type);
}
// Verifies that corrupted prefs file results in no proxy detected.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxCorruptedPrefs) {
ProxyInfo proxy_info;
EXPECT_TRUE(GetProxyInfo(kFirefoxCorruptHeader, &proxy_info));
EXPECT_EQ(PROXY_NONE, proxy_info.type);
}
// Verifies that SOCKS5 proxy is detected if configured. SOCKS uses a
// handshake protocol to inform the proxy software about the
// connection that the client is trying to make and may be used for
// any form of TCP or UDP socket connection.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySocks) {
ProxyInfo proxy_info;
SocketAddress proxy_address("proxy.socks.com", 6666);
std::string prefs(kFirefoxHeader);
prefs.append("user_pref(\"network.proxy.socks\", \"proxy.socks.com\");\n");
prefs.append("user_pref(\"network.proxy.socks_port\", 6666);\n");
prefs.append("user_pref(\"network.proxy.type\", 1);\n");
EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
EXPECT_EQ(PROXY_SOCKS5, proxy_info.type);
EXPECT_EQ(proxy_address, proxy_info.address);
}
// Verified that SSL proxy is detected if configured. SSL proxy is an
// extention of a HTTP proxy to support secure connections.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySsl) {
ProxyInfo proxy_info;
SocketAddress proxy_address("proxy.ssl.com", 7777);
std::string prefs(kFirefoxHeader);
prefs.append("user_pref(\"network.proxy.ssl\", \"proxy.ssl.com\");\n");
prefs.append("user_pref(\"network.proxy.ssl_port\", 7777);\n");
prefs.append("user_pref(\"network.proxy.type\", 1);\n");
EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
EXPECT_EQ(PROXY_HTTPS, proxy_info.type);
EXPECT_EQ(proxy_address, proxy_info.address);
}
// Verifies that a HTTP proxy is detected if configured.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyHttp) {
ProxyInfo proxy_info;
SocketAddress proxy_address("proxy.http.com", 8888);
std::string prefs(kFirefoxHeader);
prefs.append("user_pref(\"network.proxy.http\", \"proxy.http.com\");\n");
prefs.append("user_pref(\"network.proxy.http_port\", 8888);\n");
prefs.append("user_pref(\"network.proxy.type\", 1);\n");
EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
EXPECT_EQ(PROXY_HTTPS, proxy_info.type);
EXPECT_EQ(proxy_address, proxy_info.address);
}
// Verifies detection of automatic proxy detection.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAuto) {
ProxyInfo proxy_info;
std::string prefs(kFirefoxHeader);
prefs.append("user_pref(\"network.proxy.type\", 4);\n");
EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
EXPECT_EQ(PROXY_NONE, proxy_info.type);
EXPECT_TRUE(proxy_info.autodetect);
EXPECT_TRUE(proxy_info.autoconfig_url.empty());
}
// Verifies detection of automatic proxy detection using a static url
// to config file.
TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAutoUrl) {
ProxyInfo proxy_info;
std::string prefs(kFirefoxHeader);
prefs.append(
"user_pref(\"network.proxy.autoconfig_url\", \"http://a/b.pac\");\n");
prefs.append("user_pref(\"network.proxy.type\", 2);\n");
EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
EXPECT_FALSE(proxy_info.autodetect);
EXPECT_EQ(PROXY_NONE, proxy_info.type);
EXPECT_EQ(0, proxy_info.autoconfig_url.compare("http://a/b.pac"));
}
} // namespace rtc

View File

@ -1,197 +0,0 @@
/*
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "webrtc/base/autodetectproxy.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/httpcommon.h"
#include "webrtc/base/httpcommon-inl.h"
#include "webrtc/base/socketadapters.h"
#include "webrtc/base/ssladapter.h"
#include "webrtc/base/sslsocketfactory.h"
namespace rtc {
///////////////////////////////////////////////////////////////////////////////
// ProxySocketAdapter
// TODO: Consider combining AutoDetectProxy and ProxySocketAdapter. I think
// the socket adapter is the more appropriate idiom for automatic proxy
// detection. We may or may not want to combine proxydetect.* as well.
///////////////////////////////////////////////////////////////////////////////
class ProxySocketAdapter : public AsyncSocketAdapter {
public:
ProxySocketAdapter(SslSocketFactory* factory, int family, int type)
: AsyncSocketAdapter(NULL), factory_(factory), family_(family),
type_(type), detect_(NULL) {
}
~ProxySocketAdapter() override {
Close();
}
int Connect(const SocketAddress& addr) override {
RTC_DCHECK(NULL == detect_);
RTC_DCHECK(NULL == socket_);
remote_ = addr;
if (remote_.IsAnyIP() && remote_.hostname().empty()) {
LOG_F(LS_ERROR) << "Empty address";
return SOCKET_ERROR;
}
Url<char> url("/", remote_.HostAsURIString(), remote_.port());
detect_ = new AutoDetectProxy(factory_->agent_);
detect_->set_server_url(url.url());
detect_->SignalWorkDone.connect(this,
&ProxySocketAdapter::OnProxyDetectionComplete);
detect_->Start();
return SOCKET_ERROR;
}
int GetError() const override {
if (socket_) {
return socket_->GetError();
}
return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL;
}
int Close() override {
if (socket_) {
return socket_->Close();
}
if (detect_) {
detect_->Destroy(false);
detect_ = NULL;
}
return 0;
}
ConnState GetState() const override {
if (socket_) {
return socket_->GetState();
}
return detect_ ? CS_CONNECTING : CS_CLOSED;
}
private:
// AutoDetectProxy Slots
void OnProxyDetectionComplete(SignalThread* thread) {
RTC_DCHECK(detect_ == thread);
Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_));
detect_->Release();
detect_ = NULL;
if (0 == AsyncSocketAdapter::Connect(remote_)) {
SignalConnectEvent(this);
} else if (!IsBlockingError(socket_->GetError())) {
SignalCloseEvent(this, socket_->GetError());
}
}
SslSocketFactory* factory_;
int family_;
int type_;
SocketAddress remote_;
AutoDetectProxy* detect_;
};
///////////////////////////////////////////////////////////////////////////////
// SslSocketFactory
///////////////////////////////////////////////////////////////////////////////
SslSocketFactory::SslSocketFactory(SocketFactory* factory,
const std::string& user_agent)
: factory_(factory),
agent_(user_agent),
autodetect_proxy_(true),
force_connect_(false),
logging_level_(LS_VERBOSE),
binary_mode_(false),
ignore_bad_cert_(false) {
}
SslSocketFactory::~SslSocketFactory() = default;
Socket* SslSocketFactory::CreateSocket(int type) {
return CreateSocket(AF_INET, type);
}
Socket* SslSocketFactory::CreateSocket(int family, int type) {
return factory_->CreateSocket(family, type);
}
AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) {
return CreateAsyncSocket(AF_INET, type);
}
AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) {
if (autodetect_proxy_) {
return new ProxySocketAdapter(this, family, type);
} else {
return CreateProxySocket(proxy_, family, type);
}
}
AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy,
int family,
int type) {
AsyncSocket* socket = factory_->CreateAsyncSocket(family, type);
if (!socket)
return NULL;
// Binary logging happens at the lowest level
if (!logging_label_.empty() && binary_mode_) {
socket = new LoggingSocketAdapter(socket, logging_level_,
logging_label_.c_str(), binary_mode_);
}
if (proxy.type) {
AsyncSocket* proxy_socket = 0;
if (proxy_.type == PROXY_SOCKS5) {
proxy_socket = new AsyncSocksProxySocket(socket, proxy.address,
proxy.username, proxy.password);
} else {
// Note: we are trying unknown proxies as HTTPS currently
AsyncHttpsProxySocket* http_proxy =
new AsyncHttpsProxySocket(socket, agent_, proxy.address,
proxy.username, proxy.password);
http_proxy->SetForceConnect(force_connect_ || !hostname_.empty());
proxy_socket = http_proxy;
}
if (!proxy_socket) {
delete socket;
return NULL;
}
socket = proxy_socket; // for our purposes the proxy is now the socket
}
if (!hostname_.empty()) {
std::unique_ptr<SSLAdapter> ssl_adapter(SSLAdapter::Create(socket));
if (!ssl_adapter) {
LOG_F(LS_ERROR) << "SSL unavailable";
delete socket;
return NULL;
}
ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_);
if (ssl_adapter->StartSSL(hostname_.c_str(), true) != 0) {
LOG_F(LS_ERROR) << "SSL failed to start.";
return NULL;
}
socket = ssl_adapter.release();
}
// Regular logging occurs at the highest level
if (!logging_label_.empty() && !binary_mode_) {
socket = new LoggingSocketAdapter(socket, logging_level_,
logging_label_.c_str(), binary_mode_);
}
return socket;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace rtc

View File

@ -1,78 +0,0 @@
/*
* Copyright 2007 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_SSLSOCKETFACTORY_H__
#define WEBRTC_BASE_SSLSOCKETFACTORY_H__
#include "webrtc/base/proxyinfo.h"
#include "webrtc/base/socketserver.h"
namespace rtc {
///////////////////////////////////////////////////////////////////////////////
// SslSocketFactory
///////////////////////////////////////////////////////////////////////////////
class SslSocketFactory : public SocketFactory {
public:
SslSocketFactory(SocketFactory* factory, const std::string& user_agent);
~SslSocketFactory() override;
void SetAutoDetectProxy() {
autodetect_proxy_ = true;
}
void SetForceConnect(bool force) {
force_connect_ = force;
}
void SetProxy(const ProxyInfo& proxy) {
autodetect_proxy_ = false;
proxy_ = proxy;
}
bool autodetect_proxy() const { return autodetect_proxy_; }
const ProxyInfo& proxy() const { return proxy_; }
void UseSSL(const char* hostname) { hostname_ = hostname; }
void DisableSSL() { hostname_.clear(); }
void SetIgnoreBadCert(bool ignore) { ignore_bad_cert_ = ignore; }
bool ignore_bad_cert() const { return ignore_bad_cert_; }
void SetLogging(LoggingSeverity level, const std::string& label,
bool binary_mode = false) {
logging_level_ = level;
logging_label_ = label;
binary_mode_ = binary_mode;
}
// SocketFactory Interface
Socket* CreateSocket(int type) override;
Socket* CreateSocket(int family, int type) override;
AsyncSocket* CreateAsyncSocket(int type) override;
AsyncSocket* CreateAsyncSocket(int family, int type) override;
private:
friend class ProxySocketAdapter;
AsyncSocket* CreateProxySocket(const ProxyInfo& proxy, int family, int type);
SocketFactory* factory_;
std::string agent_;
bool autodetect_proxy_, force_connect_;
ProxyInfo proxy_;
std::string hostname_, logging_label_;
LoggingSeverity logging_level_;
bool binary_mode_;
bool ignore_bad_cert_;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace rtc
#endif // WEBRTC_BASE_SSLSOCKETFACTORY_H__