mirror of
https://github.com/pocoproject/poco.git
synced 2025-07-04 01:27:11 +02:00
added support for global HTTP proxy configuration
This commit is contained in:
parent
9dfffed94a
commit
420c3b55a7
@ -64,6 +64,20 @@ class Net_API HTTPClientSession: public HTTPSession
|
|||||||
/// set up a session through a proxy.
|
/// set up a session through a proxy.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct ProxyConfig
|
||||||
|
/// HTTP proxy server configuration.
|
||||||
|
{
|
||||||
|
ProxyConfig():
|
||||||
|
port(HTTP_PORT)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string host; /// Proxy server host name or IP address.
|
||||||
|
Poco::UInt16 port; /// Proxy server TCP port.
|
||||||
|
std::string username; /// Proxy server username.
|
||||||
|
std::string password; /// Proxy server password.
|
||||||
|
};
|
||||||
|
|
||||||
HTTPClientSession();
|
HTTPClientSession();
|
||||||
/// Creates an unconnected HTTPClientSession.
|
/// Creates an unconnected HTTPClientSession.
|
||||||
|
|
||||||
@ -133,6 +147,25 @@ public:
|
|||||||
const std::string& getProxyPassword() const;
|
const std::string& getProxyPassword() const;
|
||||||
/// Returns the password for proxy authentication.
|
/// Returns the password for proxy authentication.
|
||||||
|
|
||||||
|
void setProxyConfig(const ProxyConfig& config);
|
||||||
|
/// Sets the proxy configuration.
|
||||||
|
|
||||||
|
const ProxyConfig& getProxyConfig() const;
|
||||||
|
/// Returns the proxy configuration.
|
||||||
|
|
||||||
|
static void setGlobalProxyConfig(const ProxyConfig& config);
|
||||||
|
/// Sets the global proxy configuration.
|
||||||
|
///
|
||||||
|
/// The global proxy configuration is used by all HTTPClientSession
|
||||||
|
/// instances, unless a different proxy configuration is explicitly set.
|
||||||
|
///
|
||||||
|
/// Warning: Setting the global proxy configuration is not thread safe.
|
||||||
|
/// The global proxy configuration should be set at start up, before
|
||||||
|
/// the first HTTPClientSession instance is created.
|
||||||
|
|
||||||
|
static const ProxyConfig& getGlobalProxyConfig();
|
||||||
|
/// Returns the global proxy configuration.
|
||||||
|
|
||||||
void setKeepAliveTimeout(const Poco::Timespan& timeout);
|
void setKeepAliveTimeout(const Poco::Timespan& timeout);
|
||||||
/// Sets the connection timeout for HTTP connections.
|
/// Sets the connection timeout for HTTP connections.
|
||||||
|
|
||||||
@ -237,10 +270,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
std::string _host;
|
std::string _host;
|
||||||
Poco::UInt16 _port;
|
Poco::UInt16 _port;
|
||||||
std::string _proxyHost;
|
ProxyConfig _proxyConfig;
|
||||||
Poco::UInt16 _proxyPort;
|
|
||||||
std::string _proxyUsername;
|
|
||||||
std::string _proxyPassword;
|
|
||||||
Poco::Timespan _keepAliveTimeout;
|
Poco::Timespan _keepAliveTimeout;
|
||||||
Poco::Timestamp _lastRequest;
|
Poco::Timestamp _lastRequest;
|
||||||
bool _reconnect;
|
bool _reconnect;
|
||||||
@ -249,6 +279,8 @@ private:
|
|||||||
Poco::SharedPtr<std::ostream> _pRequestStream;
|
Poco::SharedPtr<std::ostream> _pRequestStream;
|
||||||
Poco::SharedPtr<std::istream> _pResponseStream;
|
Poco::SharedPtr<std::istream> _pResponseStream;
|
||||||
|
|
||||||
|
static ProxyConfig _globalProxyConfig;
|
||||||
|
|
||||||
HTTPClientSession(const HTTPClientSession&);
|
HTTPClientSession(const HTTPClientSession&);
|
||||||
HTTPClientSession& operator = (const HTTPClientSession&);
|
HTTPClientSession& operator = (const HTTPClientSession&);
|
||||||
|
|
||||||
@ -273,25 +305,37 @@ inline Poco::UInt16 HTTPClientSession::getPort() const
|
|||||||
|
|
||||||
inline const std::string& HTTPClientSession::getProxyHost() const
|
inline const std::string& HTTPClientSession::getProxyHost() const
|
||||||
{
|
{
|
||||||
return _proxyHost;
|
return _proxyConfig.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Poco::UInt16 HTTPClientSession::getProxyPort() const
|
inline Poco::UInt16 HTTPClientSession::getProxyPort() const
|
||||||
{
|
{
|
||||||
return _proxyPort;
|
return _proxyConfig.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& HTTPClientSession::getProxyUsername() const
|
inline const std::string& HTTPClientSession::getProxyUsername() const
|
||||||
{
|
{
|
||||||
return _proxyUsername;
|
return _proxyConfig.username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::string& HTTPClientSession::getProxyPassword() const
|
inline const std::string& HTTPClientSession::getProxyPassword() const
|
||||||
{
|
{
|
||||||
return _proxyPassword;
|
return _proxyConfig.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const HTTPClientSession::ProxyConfig& HTTPClientSession::getProxyConfig() const
|
||||||
|
{
|
||||||
|
return _proxyConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const HTTPClientSession::ProxyConfig& HTTPClientSession::getGlobalProxyConfig()
|
||||||
|
{
|
||||||
|
return _globalProxyConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,9 +37,12 @@ namespace Poco {
|
|||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
|
||||||
|
HTTPClientSession::ProxyConfig HTTPClientSession::_globalProxyConfig;
|
||||||
|
|
||||||
|
|
||||||
HTTPClientSession::HTTPClientSession():
|
HTTPClientSession::HTTPClientSession():
|
||||||
_port(HTTPSession::HTTP_PORT),
|
_port(HTTPSession::HTTP_PORT),
|
||||||
_proxyPort(HTTPSession::HTTP_PORT),
|
_proxyConfig(_globalProxyConfig),
|
||||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||||
_reconnect(false),
|
_reconnect(false),
|
||||||
_mustReconnect(false),
|
_mustReconnect(false),
|
||||||
@ -51,7 +54,7 @@ HTTPClientSession::HTTPClientSession():
|
|||||||
HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
|
HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
|
||||||
HTTPSession(socket),
|
HTTPSession(socket),
|
||||||
_port(HTTPSession::HTTP_PORT),
|
_port(HTTPSession::HTTP_PORT),
|
||||||
_proxyPort(HTTPSession::HTTP_PORT),
|
_proxyConfig(_globalProxyConfig),
|
||||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||||
_reconnect(false),
|
_reconnect(false),
|
||||||
_mustReconnect(false),
|
_mustReconnect(false),
|
||||||
@ -63,7 +66,7 @@ HTTPClientSession::HTTPClientSession(const StreamSocket& socket):
|
|||||||
HTTPClientSession::HTTPClientSession(const SocketAddress& address):
|
HTTPClientSession::HTTPClientSession(const SocketAddress& address):
|
||||||
_host(address.host().toString()),
|
_host(address.host().toString()),
|
||||||
_port(address.port()),
|
_port(address.port()),
|
||||||
_proxyPort(HTTPSession::HTTP_PORT),
|
_proxyConfig(_globalProxyConfig),
|
||||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||||
_reconnect(false),
|
_reconnect(false),
|
||||||
_mustReconnect(false),
|
_mustReconnect(false),
|
||||||
@ -75,7 +78,7 @@ HTTPClientSession::HTTPClientSession(const SocketAddress& address):
|
|||||||
HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port):
|
HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port):
|
||||||
_host(host),
|
_host(host),
|
||||||
_port(port),
|
_port(port),
|
||||||
_proxyPort(HTTPSession::HTTP_PORT),
|
_proxyConfig(_globalProxyConfig),
|
||||||
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||||
_reconnect(false),
|
_reconnect(false),
|
||||||
_mustReconnect(false),
|
_mustReconnect(false),
|
||||||
@ -111,8 +114,8 @@ void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port)
|
|||||||
{
|
{
|
||||||
if (!connected())
|
if (!connected())
|
||||||
{
|
{
|
||||||
_proxyHost = host;
|
_proxyConfig.host = host;
|
||||||
_proxyPort = port;
|
_proxyConfig.port = port;
|
||||||
}
|
}
|
||||||
else throw IllegalStateException("Cannot set the proxy host and port for an already connected session");
|
else throw IllegalStateException("Cannot set the proxy host and port for an already connected session");
|
||||||
}
|
}
|
||||||
@ -121,7 +124,7 @@ void HTTPClientSession::setProxy(const std::string& host, Poco::UInt16 port)
|
|||||||
void HTTPClientSession::setProxyHost(const std::string& host)
|
void HTTPClientSession::setProxyHost(const std::string& host)
|
||||||
{
|
{
|
||||||
if (!connected())
|
if (!connected())
|
||||||
_proxyHost = host;
|
_proxyConfig.host = host;
|
||||||
else
|
else
|
||||||
throw IllegalStateException("Cannot set the proxy host for an already connected session");
|
throw IllegalStateException("Cannot set the proxy host for an already connected session");
|
||||||
}
|
}
|
||||||
@ -130,7 +133,7 @@ void HTTPClientSession::setProxyHost(const std::string& host)
|
|||||||
void HTTPClientSession::setProxyPort(Poco::UInt16 port)
|
void HTTPClientSession::setProxyPort(Poco::UInt16 port)
|
||||||
{
|
{
|
||||||
if (!connected())
|
if (!connected())
|
||||||
_proxyPort = port;
|
_proxyConfig.port = port;
|
||||||
else
|
else
|
||||||
throw IllegalStateException("Cannot set the proxy port number for an already connected session");
|
throw IllegalStateException("Cannot set the proxy port number for an already connected session");
|
||||||
}
|
}
|
||||||
@ -138,20 +141,32 @@ void HTTPClientSession::setProxyPort(Poco::UInt16 port)
|
|||||||
|
|
||||||
void HTTPClientSession::setProxyCredentials(const std::string& username, const std::string& password)
|
void HTTPClientSession::setProxyCredentials(const std::string& username, const std::string& password)
|
||||||
{
|
{
|
||||||
_proxyUsername = username;
|
_proxyConfig.username = username;
|
||||||
_proxyPassword = password;
|
_proxyConfig.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HTTPClientSession::setProxyUsername(const std::string& username)
|
void HTTPClientSession::setProxyUsername(const std::string& username)
|
||||||
{
|
{
|
||||||
_proxyUsername = username;
|
_proxyConfig.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HTTPClientSession::setProxyPassword(const std::string& password)
|
void HTTPClientSession::setProxyPassword(const std::string& password)
|
||||||
{
|
{
|
||||||
_proxyPassword = password;
|
_proxyConfig.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HTTPClientSession::setProxyConfig(const ProxyConfig& config)
|
||||||
|
{
|
||||||
|
_proxyConfig = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HTTPClientSession::setGlobalProxyConfig(const ProxyConfig& config)
|
||||||
|
{
|
||||||
|
_globalProxyConfig = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,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 (!_proxyHost.empty())
|
if (!_proxyConfig.host.empty())
|
||||||
{
|
{
|
||||||
request.setURI(proxyRequestPrefix() + request.getURI());
|
request.setURI(proxyRequestPrefix() + request.getURI());
|
||||||
proxyAuthenticate(request);
|
proxyAuthenticate(request);
|
||||||
@ -312,14 +327,14 @@ int HTTPClientSession::write(const char* buffer, std::streamsize length)
|
|||||||
|
|
||||||
void HTTPClientSession::reconnect()
|
void HTTPClientSession::reconnect()
|
||||||
{
|
{
|
||||||
if (_proxyHost.empty())
|
if (_proxyConfig.host.empty())
|
||||||
{
|
{
|
||||||
SocketAddress addr(_host, _port);
|
SocketAddress addr(_host, _port);
|
||||||
connect(addr);
|
connect(addr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SocketAddress addr(_proxyHost, _proxyPort);
|
SocketAddress addr(_proxyConfig.host, _proxyConfig.port);
|
||||||
connect(addr);
|
connect(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,9 +369,9 @@ void HTTPClientSession::proxyAuthenticate(HTTPRequest& request)
|
|||||||
|
|
||||||
void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request)
|
void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request)
|
||||||
{
|
{
|
||||||
if (!_proxyUsername.empty())
|
if (!_proxyConfig.username.empty())
|
||||||
{
|
{
|
||||||
HTTPBasicCredentials creds(_proxyUsername, _proxyPassword);
|
HTTPBasicCredentials creds(_proxyConfig.username, _proxyConfig.password);
|
||||||
creds.proxyAuthenticate(request);
|
creds.proxyAuthenticate(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,10 +87,21 @@ std::istream* HTTPStreamFactory::open(const URI& uri)
|
|||||||
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||||
|
|
||||||
if (proxyUri.empty())
|
if (proxyUri.empty())
|
||||||
pSession->setProxy(_proxyHost, _proxyPort);
|
{
|
||||||
|
if (!_proxyHost.empty())
|
||||||
|
{
|
||||||
|
pSession->setProxy(_proxyHost, _proxyPort);
|
||||||
|
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
|
pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
|
||||||
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
if (!_proxyUsername.empty())
|
||||||
|
{
|
||||||
|
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path = resolvedURI.getPathAndQuery();
|
std::string path = resolvedURI.getPathAndQuery();
|
||||||
@ -131,7 +142,8 @@ std::istream* HTTPStreamFactory::open(const URI& uri)
|
|||||||
// single request via the proxy. 305 responses MUST only be generated by origin servers.
|
// single request via the proxy. 305 responses MUST only be generated by origin servers.
|
||||||
// only use for one single request!
|
// only use for one single request!
|
||||||
proxyUri.resolve(res.get("Location"));
|
proxyUri.resolve(res.get("Location"));
|
||||||
delete pSession; pSession = 0;
|
delete pSession;
|
||||||
|
pSession = 0;
|
||||||
retry = true; // only allow useproxy once
|
retry = true; // only allow useproxy once
|
||||||
}
|
}
|
||||||
else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
|
else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
|
||||||
|
@ -89,11 +89,23 @@ std::istream* HTTPSStreamFactory::open(const URI& uri)
|
|||||||
pSession = new HTTPSClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
pSession = new HTTPSClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||||
else
|
else
|
||||||
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort());
|
||||||
|
|
||||||
if (proxyUri.empty())
|
if (proxyUri.empty())
|
||||||
pSession->setProxy(_proxyHost, _proxyPort);
|
{
|
||||||
|
if (!_proxyHost.empty())
|
||||||
|
{
|
||||||
|
pSession->setProxy(_proxyHost, _proxyPort);
|
||||||
|
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
|
pSession->setProxy(proxyUri.getHost(), proxyUri.getPort());
|
||||||
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
if (!_proxyUsername.empty())
|
||||||
|
{
|
||||||
|
pSession->setProxyCredentials(_proxyUsername, _proxyPassword);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string path = resolvedURI.getPathAndQuery();
|
std::string path = resolvedURI.getPathAndQuery();
|
||||||
if (path.empty()) path = "/";
|
if (path.empty()) path = "/";
|
||||||
@ -136,7 +148,8 @@ std::istream* HTTPSStreamFactory::open(const URI& uri)
|
|||||||
// single request via the proxy. 305 responses MUST only be generated by origin servers.
|
// single request via the proxy. 305 responses MUST only be generated by origin servers.
|
||||||
// only use for one single request!
|
// only use for one single request!
|
||||||
proxyUri.resolve(res.get("Location"));
|
proxyUri.resolve(res.get("Location"));
|
||||||
delete pSession; pSession = 0;
|
delete pSession;
|
||||||
|
pSession = 0;
|
||||||
retry = true; // only allow useproxy once
|
retry = true; // only allow useproxy once
|
||||||
}
|
}
|
||||||
else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
|
else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user