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