added nonProxyHosts to ProxyConfig to allow bypassing proxy for certain hosts

This commit is contained in:
Guenter Obiltschnig
2014-11-11 22:54:44 +01:00
parent b576a66c4b
commit 781acfa0bd
6 changed files with 63 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
// //
// HTTPClientSession.h // HTTPClientSession.h
// //
// $Id: //poco/1.4/Net/include/Poco/Net/HTTPClientSession.h#5 $ // $Id: //poco/1.4/Net/include/Poco/Net/HTTPClientSession.h#7 $
// //
// Library: Net // Library: Net
// Package: HTTPClient // Package: HTTPClient
@@ -72,10 +72,18 @@ public:
{ {
} }
std::string host; /// Proxy server host name or IP address. std::string host;
Poco::UInt16 port; /// Proxy server TCP port. /// Proxy server host name or IP address.
std::string username; /// Proxy server username. Poco::UInt16 port;
std::string password; /// Proxy server password. /// Proxy server TCP port.
std::string username;
/// Proxy server username.
std::string password;
/// Proxy server password.
std::string nonProxyHosts;
/// A regular expression defining hosts for which the proxy should be bypassed,
/// e.g. "localhost|127\.0\.0\.1|192\.168\.0\.\d+". Can also be an empty
/// string to disable proxy bypassing.
}; };
HTTPClientSession(); HTTPClientSession();
@@ -231,6 +239,10 @@ public:
virtual bool secure() const; virtual bool secure() const;
/// Return true iff the session uses SSL or TLS, /// Return true iff the session uses SSL or TLS,
/// or false otherwise. /// or false otherwise.
bool bypassProxy() const;
/// Returns true if the proxy should be bypassed
/// for the current host.
protected: protected:
enum enum

View File

@@ -1,7 +1,7 @@
// //
// HTTPClientSession.cpp // HTTPClientSession.cpp
// //
// $Id: //poco/1.4/Net/src/HTTPClientSession.cpp#11 $ // $Id: //poco/1.4/Net/src/HTTPClientSession.cpp#14 $
// //
// Library: Net // Library: Net
// Package: HTTPClient // Package: HTTPClient
@@ -25,7 +25,7 @@
#include "Poco/Net/NetException.h" #include "Poco/Net/NetException.h"
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
#include "Poco/CountingStream.h" #include "Poco/CountingStream.h"
#include "Poco/Base64Encoder.h" #include "Poco/RegularExpression.h"
#include <sstream> #include <sstream>
@@ -195,7 +195,7 @@ std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request)
request.setKeepAlive(false); request.setKeepAlive(false);
if (!request.has(HTTPRequest::HOST)) if (!request.has(HTTPRequest::HOST))
request.setHost(_host, _port); request.setHost(_host, _port);
if (!_proxyConfig.host.empty()) if (!_proxyConfig.host.empty() && !bypassProxy())
{ {
request.setURI(proxyRequestPrefix() + request.getURI()); request.setURI(proxyRequestPrefix() + request.getURI());
proxyAuthenticate(request); proxyAuthenticate(request);
@@ -327,7 +327,7 @@ int HTTPClientSession::write(const char* buffer, std::streamsize length)
void HTTPClientSession::reconnect() void HTTPClientSession::reconnect()
{ {
if (_proxyConfig.host.empty()) if (_proxyConfig.host.empty() || bypassProxy())
{ {
SocketAddress addr(_host, _port); SocketAddress addr(_host, _port);
connect(addr); connect(addr);
@@ -405,4 +405,14 @@ void HTTPClientSession::proxyTunnel()
} }
bool HTTPClientSession::bypassProxy() const
{
if (!_proxyConfig.nonProxyHosts.empty())
{
return RegularExpression::match(_host, _proxyConfig.nonProxyHosts, RegularExpression::RE_CASELESS | RegularExpression::RE_ANCHORED);
}
else return false;
}
} } // namespace Poco::Net } } // namespace Poco::Net

View File

@@ -1,7 +1,7 @@
// //
// HTTPClientSessionTest.cpp // HTTPClientSessionTest.cpp
// //
// $Id: //poco/1.4/Net/testsuite/src/HTTPClientSessionTest.cpp#1 $ // $Id: //poco/1.4/Net/testsuite/src/HTTPClientSessionTest.cpp#2 $
// //
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@@ -279,6 +279,27 @@ void HTTPClientSessionTest::testProxyAuth()
} }
void HTTPClientSessionTest::testBypassProxy()
{
HTTPClientSession::ProxyConfig proxyConfig;
proxyConfig.host = "proxy.domain.com";
proxyConfig.port = 80;
proxyConfig.nonProxyHosts = "localhost|127\\.0\\.0\\.1";
HTTPClientSession s1("localhost", 80);
s1.setProxyConfig(proxyConfig);
assert (s1.bypassProxy());
HTTPClientSession s2("127.0.0.1", 80);
s2.setProxyConfig(proxyConfig);
assert (s2.bypassProxy());
HTTPClientSession s3("www.appinf.com", 80);
s3.setProxyConfig(proxyConfig);
assert (!s3.bypassProxy());
}
void HTTPClientSessionTest::setUp() void HTTPClientSessionTest::setUp()
{ {
} }
@@ -305,6 +326,7 @@ CppUnit::Test* HTTPClientSessionTest::suite()
CppUnit_addTest(pSuite, HTTPClientSessionTest, testKeepAlive); CppUnit_addTest(pSuite, HTTPClientSessionTest, testKeepAlive);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxy); CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxy);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxyAuth); CppUnit_addTest(pSuite, HTTPClientSessionTest, testProxyAuth);
CppUnit_addTest(pSuite, HTTPClientSessionTest, testBypassProxy);
return pSuite; return pSuite;
} }

View File

@@ -38,6 +38,7 @@ public:
void testKeepAlive(); void testKeepAlive();
void testProxy(); void testProxy();
void testProxyAuth(); void testProxyAuth();
void testBypassProxy();
void setUp(); void setUp();
void tearDown(); void tearDown();

View File

@@ -1,7 +1,7 @@
// //
// HTTPSClientSession.cpp // HTTPSClientSession.cpp
// //
// $Id: //poco/1.4/NetSSL_OpenSSL/src/HTTPSClientSession.cpp#3 $ // $Id: //poco/1.4/NetSSL_OpenSSL/src/HTTPSClientSession.cpp#4 $
// //
// Library: NetSSL_OpenSSL // Library: NetSSL_OpenSSL
// Package: HTTPSClient // Package: HTTPSClient
@@ -145,7 +145,7 @@ void HTTPSClientSession::proxyAuthenticate(HTTPRequest& request)
void HTTPSClientSession::connect(const SocketAddress& address) void HTTPSClientSession::connect(const SocketAddress& address)
{ {
if (getProxyHost().empty()) if (getProxyHost().empty() || bypassProxy())
{ {
SecureStreamSocket sss(socket()); SecureStreamSocket sss(socket());
if (_pContext->sessionCacheEnabled()) if (_pContext->sessionCacheEnabled())
@@ -176,7 +176,8 @@ int HTTPSClientSession::read(char* buffer, std::streamsize length)
try try
{ {
return HTTPSession::read(buffer, length); return HTTPSession::read(buffer, length);
} catch(SSLConnectionUnexpectedlyClosedException&) }
catch(SSLConnectionUnexpectedlyClosedException&)
{ {
return 0; return 0;
} }

View File

@@ -1,7 +1,7 @@
// //
// HTTPSClientSession.cpp // HTTPSClientSession.cpp
// //
// $Id: //poco/1.4/NetSSL_Win/src/HTTPSClientSession.cpp#3 $ // $Id: //poco/1.4/NetSSL_Win/src/HTTPSClientSession.cpp#4 $
// //
// Library: NetSSL_Win // Library: NetSSL_Win
// Package: HTTPSClient // Package: HTTPSClient
@@ -145,7 +145,7 @@ void HTTPSClientSession::proxyAuthenticate(HTTPRequest& request)
void HTTPSClientSession::connect(const SocketAddress& address) void HTTPSClientSession::connect(const SocketAddress& address)
{ {
if (getProxyHost().empty()) if (getProxyHost().empty() || bypassProxy())
{ {
SecureStreamSocket sss(socket()); SecureStreamSocket sss(socket());
if (_pContext->sessionCacheEnabled()) if (_pContext->sessionCacheEnabled())
@@ -176,7 +176,8 @@ int HTTPSClientSession::read(char* buffer, std::streamsize length)
try try
{ {
return HTTPSession::read(buffer, length); return HTTPSession::read(buffer, length);
} catch(SSLConnectionUnexpectedlyClosedException&) }
catch(SSLConnectionUnexpectedlyClosedException&)
{ {
return 0; return 0;
} }