/* * libjingle * Copyright 2004--2011, Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "talk/base/autodetectproxy.h" #include "talk/base/gunit.h" #include "talk/base/httpcommon.h" #include "talk/base/httpcommon-inl.h" namespace talk_base { static const char kUserAgent[] = ""; static const char kPath[] = "/"; static const char kHost[] = "relay.google.com"; static const uint16 kPort = 443; static const bool kSecure = true; // At most, AutoDetectProxy should take ~6 seconds. Each connect step is // allotted 2 seconds, with the initial resolution + connect given an // extra 2 seconds. The slowest case is: // 1) Resolution + HTTPS takes full 4 seconds and fails (but resolution // succeeds). // 2) SOCKS5 takes the full 2 seconds. // Socket creation time seems unbounded, and has been observed to take >1 second // on a linux machine under load. As such, we allow for 10 seconds for timeout, // though could still end up with some flakiness. static const int kTimeoutMs = 10000; class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> { public: AutoDetectProxyTest() : auto_detect_proxy_(NULL), done_(false) {} protected: bool Create(const std::string &user_agent, const std::string &path, const std::string &host, uint16 port, bool secure, bool startnow) { auto_detect_proxy_ = new AutoDetectProxy(user_agent); EXPECT_TRUE(auto_detect_proxy_ != NULL); if (!auto_detect_proxy_) { return false; } Url<char> host_url(path, host, port); host_url.set_secure(secure); auto_detect_proxy_->set_server_url(host_url.url()); auto_detect_proxy_->SignalWorkDone.connect( this, &AutoDetectProxyTest::OnWorkDone); if (startnow) { auto_detect_proxy_->Start(); } return true; } bool Run(int timeout_ms) { EXPECT_TRUE_WAIT(done_, timeout_ms); return done_; } void SetProxy(const SocketAddress& proxy) { auto_detect_proxy_->set_proxy(proxy); } void Start() { auto_detect_proxy_->Start(); } void TestCopesWithProxy(const SocketAddress& proxy) { // Tests that at least autodetect doesn't crash for a given proxy address. ASSERT_TRUE(Create(kUserAgent, kPath, kHost, kPort, kSecure, false)); SetProxy(proxy); Start(); ASSERT_TRUE(Run(kTimeoutMs)); } private: void OnWorkDone(talk_base::SignalThread *thread) { AutoDetectProxy *auto_detect_proxy = static_cast<talk_base::AutoDetectProxy *>(thread); EXPECT_TRUE(auto_detect_proxy == auto_detect_proxy_); auto_detect_proxy_ = NULL; auto_detect_proxy->Release(); done_ = true; } AutoDetectProxy *auto_detect_proxy_; bool done_; }; TEST_F(AutoDetectProxyTest, TestDetectUnresolvedProxy) { TestCopesWithProxy(talk_base::SocketAddress("localhost", 9999)); } TEST_F(AutoDetectProxyTest, TestDetectUnresolvableProxy) { TestCopesWithProxy(talk_base::SocketAddress("invalid", 9999)); } TEST_F(AutoDetectProxyTest, TestDetectIPv6Proxy) { TestCopesWithProxy(talk_base::SocketAddress("::1", 9999)); } TEST_F(AutoDetectProxyTest, TestDetectIPv4Proxy) { TestCopesWithProxy(talk_base::SocketAddress("127.0.0.1", 9999)); } // Test that proxy detection completes successfully. (Does not actually verify // the correct detection result since we don't know what proxy to expect on an // arbitrary machine.) TEST_F(AutoDetectProxyTest, TestProxyDetection) { ASSERT_TRUE(Create(kUserAgent, kPath, kHost, kPort, kSecure, true)); ASSERT_TRUE(Run(kTimeoutMs)); } } // namespace talk_base