147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2009 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/autodetectproxy.h"
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/gunit.h"
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpserver.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/proxyserver.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketadapters.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testclient.h"
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testechoserver.h"
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/virtualsocketserver.h"
20a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgusing rtc::Socket;
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgusing rtc::Thread;
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgusing rtc::SocketAddress;
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080);
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0);
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443);
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0);
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999);
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Used to run a proxy detect on the current thread. Otherwise we would need
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// to make both threads share the same VirtualSocketServer.
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AutoDetectProxyRunner : public rtc::AutoDetectProxy {
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit AutoDetectProxyRunner(const std::string& agent)
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : AutoDetectProxy(agent) {}
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Run() {
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DoWork();
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->Restart();  // needed to reset the messagequeue
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers.
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass ProxyTest : public testing::Test {
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ProxyTest() : ss_(new rtc::VirtualSocketServer(NULL)) {
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->set_socketserver(ss_.get());
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socks_.reset(new rtc::SocksProxyServer(
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ss_.get(), kSocksProxyIntAddr, ss_.get(), kSocksProxyExtAddr));
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    https_.reset(new rtc::HttpListenServer());
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    https_->Listen(kHttpsProxyIntAddr);
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ~ProxyTest() {
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->set_socketserver(NULL);
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::SocketServer* ss() { return ss_.get(); }
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::ProxyType DetectProxyType(const SocketAddress& address) {
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    rtc::ProxyType type;
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0");
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    detect->set_proxy(address);
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    detect->Run();  // blocks until done
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    type = detect->proxy().type;
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    detect->Destroy(false);
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return type;
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::scoped_ptr<rtc::SocketServer> ss_;
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::scoped_ptr<rtc::SocksProxyServer> socks_;
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: Make this a real HTTPS proxy server.
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::scoped_ptr<rtc::HttpListenServer> https_;
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests whether we can use a SOCKS5 proxy to connect to a server.
78a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST_F(ProxyTest, DISABLED_ON_MAC(TestSocks5Connect)) {
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::AsyncSocket* socket =
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss()->CreateAsyncSocket(kSocksProxyIntAddr.family(), SOCK_STREAM);
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::AsyncSocksProxySocket* proxy_socket =
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new rtc::AsyncSocksProxySocket(socket, kSocksProxyIntAddr,
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           "", rtc::CryptString());
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: IPv6-ize these tests when proxy supports IPv6.
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::TestEchoServer server(Thread::Current(),
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                   SocketAddress(INADDR_ANY, 0));
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::AsyncTCPSocket* packet_socket = rtc::AsyncTCPSocket::Create(
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy_socket, SocketAddress(INADDR_ANY, 0), server.address());
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(packet_socket != NULL);
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::TestClient client(packet_socket);
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState());
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckConnected());
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState());
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server.address(), client.remote_address());
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client.Send("foo", 3);
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckNoPacket());
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests whether we can use a HTTPS proxy to connect to a server.
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST_F(ProxyTest, TestHttpsConnect) {
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM);
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket(
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString());
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestClient client(new AsyncTCPSocket(proxy_socket));
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestEchoServer server(Thread::Current(), SocketAddress());
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.Connect(server.address()));
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckConnected());
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server.address(), client.remote_address());
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client.Send("foo", 3);
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client.CheckNoPacket());
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org*/
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests whether we can autodetect a SOCKS5 proxy.
122a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST_F(ProxyTest, DISABLED_ON_MAC(TestAutoDetectSocks5)) {
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr));
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests whether we can autodetect a HTTPS proxy.
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST_F(ProxyTest, TestAutoDetectHttps) {
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr));
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org*/
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests whether we fail properly for no proxy.
134a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST_F(ProxyTest, DISABLED_ON_MAC(TestAutoDetectBogus)) {
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr));
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
137