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 #include "webrtc/test/testsupport/gtest_disable.h" 21 22 using rtc::Socket; 23 using rtc::Thread; 24 using rtc::SocketAddress; 25 26 static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080); 27 static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0); 28 static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443); 29 static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0); 30 static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); 31 32 // Used to run a proxy detect on the current thread. Otherwise we would need 33 // to make both threads share the same VirtualSocketServer. 34 class AutoDetectProxyRunner : public rtc::AutoDetectProxy { 35 public: 36 explicit AutoDetectProxyRunner(const std::string& agent) 37 : AutoDetectProxy(agent) {} 38 void Run() { 39 DoWork(); 40 Thread::Current()->Restart(); // needed to reset the messagequeue 41 } 42 }; 43 44 // Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers. 45 class ProxyTest : public testing::Test { 46 public: 47 ProxyTest() : ss_(new rtc::VirtualSocketServer(NULL)) { 48 Thread::Current()->set_socketserver(ss_.get()); 49 socks_.reset(new rtc::SocksProxyServer( 50 ss_.get(), kSocksProxyIntAddr, ss_.get(), kSocksProxyExtAddr)); 51 https_.reset(new rtc::HttpListenServer()); 52 https_->Listen(kHttpsProxyIntAddr); 53 } 54 ~ProxyTest() { 55 Thread::Current()->set_socketserver(NULL); 56 } 57 58 rtc::SocketServer* ss() { return ss_.get(); } 59 60 rtc::ProxyType DetectProxyType(const SocketAddress& address) { 61 rtc::ProxyType type; 62 AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0"); 63 detect->set_proxy(address); 64 detect->Run(); // blocks until done 65 type = detect->proxy().type; 66 detect->Destroy(false); 67 return type; 68 } 69 70 private: 71 rtc::scoped_ptr<rtc::SocketServer> ss_; 72 rtc::scoped_ptr<rtc::SocksProxyServer> socks_; 73 // TODO: Make this a real HTTPS proxy server. 74 rtc::scoped_ptr<rtc::HttpListenServer> https_; 75 }; 76 77 // Tests whether we can use a SOCKS5 proxy to connect to a server. 78 TEST_F(ProxyTest, DISABLED_ON_MAC(TestSocks5Connect)) { 79 rtc::AsyncSocket* socket = 80 ss()->CreateAsyncSocket(kSocksProxyIntAddr.family(), SOCK_STREAM); 81 rtc::AsyncSocksProxySocket* proxy_socket = 82 new rtc::AsyncSocksProxySocket(socket, kSocksProxyIntAddr, 83 "", rtc::CryptString()); 84 // TODO: IPv6-ize these tests when proxy supports IPv6. 85 86 rtc::TestEchoServer server(Thread::Current(), 87 SocketAddress(INADDR_ANY, 0)); 88 89 rtc::AsyncTCPSocket* packet_socket = rtc::AsyncTCPSocket::Create( 90 proxy_socket, SocketAddress(INADDR_ANY, 0), server.address()); 91 EXPECT_TRUE(packet_socket != NULL); 92 rtc::TestClient client(packet_socket); 93 94 EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState()); 95 EXPECT_TRUE(client.CheckConnected()); 96 EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState()); 97 EXPECT_EQ(server.address(), client.remote_address()); 98 client.Send("foo", 3); 99 EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); 100 EXPECT_TRUE(client.CheckNoPacket()); 101 } 102 103 /* 104 // Tests whether we can use a HTTPS proxy to connect to a server. 105 TEST_F(ProxyTest, TestHttpsConnect) { 106 AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM); 107 AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket( 108 socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString()); 109 TestClient client(new AsyncTCPSocket(proxy_socket)); 110 TestEchoServer server(Thread::Current(), SocketAddress()); 111 112 EXPECT_TRUE(client.Connect(server.address())); 113 EXPECT_TRUE(client.CheckConnected()); 114 EXPECT_EQ(server.address(), client.remote_address()); 115 client.Send("foo", 3); 116 EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL)); 117 EXPECT_TRUE(client.CheckNoPacket()); 118 } 119 */ 120 121 // Tests whether we can autodetect a SOCKS5 proxy. 122 TEST_F(ProxyTest, DISABLED_ON_MAC(TestAutoDetectSocks5)) { 123 EXPECT_EQ(rtc::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr)); 124 } 125 126 /* 127 // Tests whether we can autodetect a HTTPS proxy. 128 TEST_F(ProxyTest, TestAutoDetectHttps) { 129 EXPECT_EQ(rtc::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr)); 130 } 131 */ 132 133 // Tests whether we fail properly for no proxy. 134 TEST_F(ProxyTest, DISABLED_ON_MAC(TestAutoDetectBogus)) { 135 EXPECT_EQ(rtc::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr)); 136 } 137