• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
AutoDetectProxyRunner(const std::string & agent)35   explicit AutoDetectProxyRunner(const std::string& agent)
36       : AutoDetectProxy(agent) {}
Run()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:
ProxyTest()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   }
~ProxyTest()53   ~ProxyTest() {
54     Thread::Current()->set_socketserver(NULL);
55   }
56 
ss()57   rtc::SocketServer* ss() { return ss_.get(); }
58 
DetectProxyType(const SocketAddress & address)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.
TEST_F(ProxyTest,TestSocks5Connect)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.
TEST_F(ProxyTest,TestAutoDetectSocks5)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.
TEST_F(ProxyTest,TestAutoDetectBogus)133 TEST_F(ProxyTest, TestAutoDetectBogus) {
134   EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr));
135 }
136