Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2009 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <string>
     12 #include "webrtc/base/autodetectproxy.h"
     13 #include "webrtc/base/gunit.h"
     14 #include "webrtc/base/httpserver.h"
     15 #include "webrtc/base/proxyserver.h"
     16 #include "webrtc/base/socketadapters.h"
     17 #include "webrtc/base/testclient.h"
     18 #include "webrtc/base/testechoserver.h"
     19 #include "webrtc/base/virtualsocketserver.h"
     20 
     21 using rtc::Socket;
     22 using rtc::Thread;
     23 using rtc::SocketAddress;
     24 
     25 static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080);
     26 static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0);
     27 static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443);
     28 static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0);
     29 static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999);
     30 
     31 // Used to run a proxy detect on the current thread. Otherwise we would need
     32 // to make both threads share the same VirtualSocketServer.
     33 class AutoDetectProxyRunner : public rtc::AutoDetectProxy {
     34  public:
     35   explicit AutoDetectProxyRunner(const std::string& agent)
     36       : AutoDetectProxy(agent) {}
     37   void Run() {
     38     DoWork();
     39     Thread::Current()->Restart();  // needed to reset the messagequeue
     40   }
     41 };
     42 
     43 // Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers.
     44 class ProxyTest : public testing::Test {
     45  public:
     46   ProxyTest() : ss_(new rtc::VirtualSocketServer(NULL)) {
     47     Thread::Current()->set_socketserver(ss_.get());
     48     socks_.reset(new rtc::SocksProxyServer(
     49         ss_.get(), kSocksProxyIntAddr, ss_.get(), kSocksProxyExtAddr));
     50     https_.reset(new rtc::HttpListenServer());
     51     https_->Listen(kHttpsProxyIntAddr);
     52   }
     53   ~ProxyTest() {
     54     Thread::Current()->set_socketserver(NULL);
     55   }
     56 
     57   rtc::SocketServer* ss() { return ss_.get(); }
     58 
     59   rtc::ProxyType DetectProxyType(const SocketAddress& address) {
     60     rtc::ProxyType type;
     61     AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0");
     62     detect->set_proxy(address);
     63     detect->Run();  // blocks until done
     64     type = detect->proxy().type;
     65     detect->Destroy(false);
     66     return type;
     67   }
     68 
     69  private:
     70   rtc::scoped_ptr<rtc::SocketServer> ss_;
     71   rtc::scoped_ptr<rtc::SocksProxyServer> socks_;
     72   // TODO: Make this a real HTTPS proxy server.
     73   rtc::scoped_ptr<rtc::HttpListenServer> https_;
     74 };
     75 
     76 // Tests whether we can use a SOCKS5 proxy to connect to a server.
     77 TEST_F(ProxyTest, TestSocks5Connect) {
     78   rtc::AsyncSocket* socket =
     79       ss()->CreateAsyncSocket(kSocksProxyIntAddr.family(), SOCK_STREAM);
     80   rtc::AsyncSocksProxySocket* proxy_socket =
     81       new rtc::AsyncSocksProxySocket(socket, kSocksProxyIntAddr,
     82                                            "", rtc::CryptString());
     83   // TODO: IPv6-ize these tests when proxy supports IPv6.
     84 
     85   rtc::TestEchoServer server(Thread::Current(),
     86                                    SocketAddress(INADDR_ANY, 0));
     87 
     88   rtc::AsyncTCPSocket* packet_socket = rtc::AsyncTCPSocket::Create(
     89       proxy_socket, SocketAddress(INADDR_ANY, 0), server.address());
     90   EXPECT_TRUE(packet_socket != NULL);
     91   rtc::TestClient client(packet_socket);
     92 
     93   EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState());
     94   EXPECT_TRUE(client.CheckConnected());
     95   EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState());
     96   EXPECT_EQ(server.address(), client.remote_address());
     97   client.Send("foo", 3);
     98   EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
     99   EXPECT_TRUE(client.CheckNoPacket());
    100 }
    101 
    102 /*
    103 // Tests whether we can use a HTTPS proxy to connect to a server.
    104 TEST_F(ProxyTest, TestHttpsConnect) {
    105   AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM);
    106   AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket(
    107       socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString());
    108   TestClient client(new AsyncTCPSocket(proxy_socket));
    109   TestEchoServer server(Thread::Current(), SocketAddress());
    110 
    111   EXPECT_TRUE(client.Connect(server.address()));
    112   EXPECT_TRUE(client.CheckConnected());
    113   EXPECT_EQ(server.address(), client.remote_address());
    114   client.Send("foo", 3);
    115   EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
    116   EXPECT_TRUE(client.CheckNoPacket());
    117 }
    118 */
    119 
    120 // Tests whether we can autodetect a SOCKS5 proxy.
    121 TEST_F(ProxyTest, TestAutoDetectSocks5) {
    122   EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr));
    123 }
    124 
    125 /*
    126 // Tests whether we can autodetect a HTTPS proxy.
    127 TEST_F(ProxyTest, TestAutoDetectHttps) {
    128   EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr));
    129 }
    130 */
    131 
    132 // Tests whether we fail properly for no proxy.
    133 TEST_F(ProxyTest, TestAutoDetectBogus) {
    134   EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr));
    135 }
    136