From c7fb678e6ee03f1bbfb39c820710c0bf76eb965a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 4 Nov 2008 14:08:26 +0000 Subject: [PATCH] 2008-11-04 Tatsuhiro Tsujikawa Deprecated --http-proxy-user and --http-proxy-passwd options. Added --https-proxy, --ftp-proxy and --all-proxy options. Above 3 options and --http-proxy option can handle proxy in URL format like: http://user:passwd@host:port. If a proxy requires user/password, they must be specified in a URL. Deprecated --ftp-via-http-proxy option. Use --http-proxy-method option instead. * src/AbstractCommand.cc * src/AbstractCommand.h * src/AbstractProxyRequestCommand.cc * src/AbstractProxyRequestCommand.h * src/AuthConfigFactory.cc * src/AuthConfigFactory.h * src/FtpFinishDownloadCommand.cc * src/FtpInitiateConnectionCommand.cc * src/FtpInitiateConnectionCommand.h * src/FtpNegotiationCommand.cc * src/FtpTunnelRequestCommand.cc * src/FtpTunnelRequestCommand.h * src/HttpDownloadCommand.cc * src/HttpInitiateConnectionCommand.cc * src/HttpInitiateConnectionCommand.h * src/HttpProxyRequestCommand.cc * src/HttpProxyRequestCommand.h * src/HttpRequest.cc * src/HttpRequest.h * src/HttpRequestCommand.cc * src/HttpRequestCommand.h * src/HttpSkipResponseCommand.cc * src/InitiateConnectionCommand.cc * src/InitiateConnectionCommand.h * src/OptionHandlerFactory.cc * src/OptionHandlerImpl.h * src/Request.cc * src/option_processing.cc * src/prefs.cc * src/prefs.h * src/usage_text.h * test/AuthConfigFactoryTest.cc * test/HttpRequestTest.cc * test/OptionHandlerTest.cc --- ChangeLog | 44 ++++++++++++ src/AbstractCommand.cc | 80 ++++++++++++++++++--- src/AbstractCommand.h | 12 ++++ src/AbstractProxyRequestCommand.cc | 21 +++--- src/AbstractProxyRequestCommand.h | 4 ++ src/AuthConfigFactory.cc | 20 ------ src/AuthConfigFactory.h | 5 -- src/FtpFinishDownloadCommand.cc | 7 +- src/FtpInitiateConnectionCommand.cc | 38 +++++----- src/FtpInitiateConnectionCommand.h | 6 +- src/FtpNegotiationCommand.cc | 3 +- src/FtpTunnelRequestCommand.cc | 15 ++-- src/FtpTunnelRequestCommand.h | 1 + src/HttpDownloadCommand.cc | 2 +- src/HttpInitiateConnectionCommand.cc | 20 +++--- src/HttpInitiateConnectionCommand.h | 3 +- src/HttpProxyRequestCommand.cc | 15 ++-- src/HttpProxyRequestCommand.h | 1 + src/HttpRequest.cc | 29 ++++---- src/HttpRequest.h | 31 +++----- src/HttpRequestCommand.cc | 17 +++-- src/HttpRequestCommand.h | 4 ++ src/HttpSkipResponseCommand.cc | 3 +- src/InitiateConnectionCommand.cc | 14 ++-- src/InitiateConnectionCommand.h | 5 +- src/OptionHandlerFactory.cc | 67 ++++++++--------- src/OptionHandlerImpl.h | 44 ++++++++---- src/Request.cc | 6 +- src/option_processing.cc | 39 ++++++---- src/prefs.cc | 19 ++--- src/prefs.h | 19 ++--- src/usage_text.h | 25 +++++-- test/AuthConfigFactoryTest.cc | 32 +-------- test/HttpRequestTest.cc | 103 +++++++++++---------------- test/OptionHandlerTest.cc | 50 ++++--------- 35 files changed, 432 insertions(+), 372 deletions(-) diff --git a/ChangeLog b/ChangeLog index f5308b5e..bebbc3f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +2008-11-04 Tatsuhiro Tsujikawa + + Deprecated --http-proxy-user and --http-proxy-passwd options. + Added --https-proxy, --ftp-proxy and --all-proxy options. + Above 3 options and --http-proxy option can handle proxy in URL format + like: http://user:passwd@host:port. + If a proxy requires user/password, they must be specified in a URL. + Deprecated --ftp-via-http-proxy option. Use --http-proxy-method option + instead. + * src/AbstractCommand.cc + * src/AbstractCommand.h + * src/AbstractProxyRequestCommand.cc + * src/AbstractProxyRequestCommand.h + * src/AuthConfigFactory.cc + * src/AuthConfigFactory.h + * src/FtpFinishDownloadCommand.cc + * src/FtpInitiateConnectionCommand.cc + * src/FtpInitiateConnectionCommand.h + * src/FtpNegotiationCommand.cc + * src/FtpTunnelRequestCommand.cc + * src/FtpTunnelRequestCommand.h + * src/HttpDownloadCommand.cc + * src/HttpInitiateConnectionCommand.cc + * src/HttpInitiateConnectionCommand.h + * src/HttpProxyRequestCommand.cc + * src/HttpProxyRequestCommand.h + * src/HttpRequest.cc + * src/HttpRequest.h + * src/HttpRequestCommand.cc + * src/HttpRequestCommand.h + * src/HttpSkipResponseCommand.cc + * src/InitiateConnectionCommand.cc + * src/InitiateConnectionCommand.h + * src/OptionHandlerFactory.cc + * src/OptionHandlerImpl.h + * src/Request.cc + * src/option_processing.cc + * src/prefs.cc + * src/prefs.h + * src/usage_text.h + * test/AuthConfigFactoryTest.cc + * test/HttpRequestTest.cc + * test/OptionHandlerTest.cc + 2008-11-03 Tatsuhiro Tsujikawa Execute choking algorithm when unchoked and interested peer is diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 46c1b9d2..bfc2a610 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -57,6 +57,7 @@ #include "StringFormat.h" #include "ServerStat.h" #include "RequestGroupMan.h" +#include "A2STR.h" namespace aria2 { @@ -291,17 +292,76 @@ void AbstractCommand::setWriteCheckSocketIf } } -static bool isProxyGETRequest(const std::string& protocol, const Option* option) +static const std::string& getProxyStringFor(const std::string& proxyPref, + const Option* option) +{ + if(option->defined(proxyPref)) { + return option->get(proxyPref); + } else { + return option->get(PREF_ALL_PROXY); + } +} + +static bool isProxyUsed(const std::string& proxyPref, + const Option* option) +{ + std::string proxy = getProxyStringFor(proxyPref, option); + if(proxy.empty()) { + return false; + } else { + return Request().setUrl(proxy); + } +} + +static bool isProxyRequest(const std::string& protocol, const Option* option) { return - // For HTTP/HTTPS - ((protocol == Request::PROTO_HTTP || protocol == Request::PROTO_HTTPS) && - (option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - option->get(PREF_HTTP_PROXY_METHOD) == V_GET)) || - // For FTP - (protocol == Request::PROTO_FTP && - (option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - option->get(PREF_FTP_VIA_HTTP_PROXY) == V_GET)); + (protocol == Request::PROTO_HTTP && isProxyUsed(PREF_HTTP_PROXY, option)) || + (protocol == Request::PROTO_HTTPS && isProxyUsed(PREF_HTTPS_PROXY,option))|| + (protocol == Request::PROTO_FTP && isProxyUsed(PREF_FTP_PROXY, option)); +} + +static bool isProxyGETRequest(const std::string& protocol, const Option* option) +{ + if(option->get(PREF_HTTP_PROXY_METHOD) != V_GET) { + return false; + } + return isProxyRequest(protocol, option); +} + +bool AbstractCommand::isProxyDefined() const +{ + return isProxyRequest(req->getProtocol(), e->option); +} + +static const std::string& getProxyString(const SharedHandle& req, + const Option* option) +{ + if(req->getProtocol() == Request::PROTO_HTTP) { + return getProxyStringFor(PREF_HTTP_PROXY, option); + } else if(req->getProtocol() == Request::PROTO_HTTPS) { + return getProxyStringFor(PREF_HTTPS_PROXY, option); + } else if(req->getProtocol() == Request::PROTO_FTP) { + return getProxyStringFor(PREF_FTP_PROXY, option); + } else { + return A2STR::NIL; + } +} + +SharedHandle AbstractCommand::createProxyRequest() const +{ + SharedHandle proxyRequest; + std::string proxy = getProxyString(req, e->option); + if(!proxy.empty()) { + proxyRequest.reset(new Request()); + if(proxyRequest->setUrl(proxy)) { + logger->debug("CUID#%d - Using proxy", cuid); + } else { + logger->debug("CUID#%d - Failed to parse proxy string", cuid); + proxyRequest.reset(); + } + } + return proxyRequest; } #ifdef ENABLE_ASYNC_DNS @@ -325,7 +385,7 @@ bool AbstractCommand::asyncResolveHostname() case AsyncNameResolver::STATUS_SUCCESS: return true; case AsyncNameResolver::STATUS_ERROR: - if(!isProxyGETRequest(req->getProtocol(), e->option)) { + if(!isProxyRequest(req->getProtocol(), e->option)) { e->_requestGroupMan->getOrCreateServerStat (req->getHost(), req->getProtocol())->setError(); } diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h index f3fd93d9..6d3d1f70 100644 --- a/src/AbstractCommand.h +++ b/src/AbstractCommand.h @@ -100,6 +100,18 @@ protected: void prepareForNextAction(Command* nextCommand = 0); void checkIfConnectionEstablished(const SharedHandle& socket); + + /* + * Returns true if proxy for the procol indicated by Request::getProtocol() + * is defined. Otherwise, returns false. + */ + bool isProxyDefined() const; + + /* + * Creates Request object for proxy URI and returns it. + * If no valid proxy is defined, then returns SharedHandle(). + */ + SharedHandle createProxyRequest() const; private: bool checkSocketIsReadable; bool checkSocketIsWritable; diff --git a/src/AbstractProxyRequestCommand.cc b/src/AbstractProxyRequestCommand.cc index 8ade62ea..ce495f23 100644 --- a/src/AbstractProxyRequestCommand.cc +++ b/src/AbstractProxyRequestCommand.cc @@ -47,13 +47,17 @@ namespace aria2 { -AbstractProxyRequestCommand::AbstractProxyRequestCommand(int cuid, - const RequestHandle& req, - RequestGroup* requestGroup, - DownloadEngine* e, - const SocketHandle& s) - :AbstractCommand(cuid, req, requestGroup, e, s), - httpConnection(new HttpConnection(cuid, s, e->option)) +AbstractProxyRequestCommand::AbstractProxyRequestCommand +(int cuid, + const RequestHandle& req, + RequestGroup* requestGroup, + DownloadEngine* e, + const SharedHandle& proxyRequest, + const SocketHandle& s) + : + AbstractCommand(cuid, req, requestGroup, e, s), + _proxyRequest(proxyRequest), + httpConnection(new HttpConnection(cuid, s, e->option)) { setTimeout(e->option->getAsInt(PREF_CONNECT_TIMEOUT)); disableReadCheckSocket(); @@ -69,8 +73,7 @@ bool AbstractProxyRequestCommand::executeInternal() { httpRequest->setUserAgent(e->option->get(PREF_USER_AGENT)); httpRequest->setRequest(req); httpRequest->setAuthConfigFactory(e->getAuthConfigFactory()); - - httpRequest->configure(e->option); + httpRequest->setProxyRequest(_proxyRequest); httpConnection->sendProxyRequest(httpRequest); } else { diff --git a/src/AbstractProxyRequestCommand.h b/src/AbstractProxyRequestCommand.h index 53a80d39..c67318dd 100644 --- a/src/AbstractProxyRequestCommand.h +++ b/src/AbstractProxyRequestCommand.h @@ -44,6 +44,8 @@ class SocketCore; class AbstractProxyRequestCommand : public AbstractCommand { protected: + SharedHandle _proxyRequest; + SharedHandle httpConnection; virtual bool executeInternal(); @@ -52,7 +54,9 @@ public: const SharedHandle& req, RequestGroup* requestGroup, DownloadEngine* e, + const SharedHandle& proxyRequest, const SharedHandle& s); + virtual ~AbstractProxyRequestCommand(); virtual Command* getNextCommand() = 0; diff --git a/src/AuthConfigFactory.cc b/src/AuthConfigFactory.cc index bbcdba1b..1fb61ea5 100644 --- a/src/AuthConfigFactory.cc +++ b/src/AuthConfigFactory.cc @@ -69,12 +69,6 @@ AuthConfigFactory::createAuthConfig(const RequestHandle& request) const } } -AuthConfigHandle -AuthConfigFactory::createAuthConfigForHttpProxy(const RequestHandle& request) const -{ - return createHttpProxyAuthResolver()->resolveAuthConfig(request->getHost()); -} - AuthConfigHandle AuthConfigFactory::createAuthConfig(const std::string& user, const std::string& password) const { @@ -118,20 +112,6 @@ AuthResolverHandle AuthConfigFactory::createFtpAuthResolver() const return resolver; } -AuthResolverHandle AuthConfigFactory::createHttpProxyAuthResolver() const -{ - AbstractAuthResolverHandle resolver; - if(true || _option->getAsBool(PREF_NO_NETRC)) { - resolver.reset(new DefaultAuthResolver()); - } else { - NetrcAuthResolverHandle authResolver(new NetrcAuthResolver()); - authResolver->setNetrc(_netrc); - resolver = authResolver; - } - resolver->setUserDefinedAuthConfig(createAuthConfig(_option->get(PREF_HTTP_PROXY_USER), _option->get(PREF_HTTP_PROXY_PASSWD))); - return resolver; -} - void AuthConfigFactory::setNetrc(const NetrcHandle& netrc) { _netrc = netrc; diff --git a/src/AuthConfigFactory.h b/src/AuthConfigFactory.h index 9ec54140..4a8d7f81 100644 --- a/src/AuthConfigFactory.h +++ b/src/AuthConfigFactory.h @@ -61,8 +61,6 @@ private: SharedHandle createHttpAuthResolver() const; - SharedHandle createHttpProxyAuthResolver() const; - SharedHandle createFtpAuthResolver() const; public: @@ -74,9 +72,6 @@ public: SharedHandle createAuthConfig (const SharedHandle& request) const; - SharedHandle createAuthConfigForHttpProxy - (const SharedHandle& request) const; - void setNetrc(const SharedHandle& netrc); static const std::string ANONYMOUS; diff --git a/src/FtpFinishDownloadCommand.cc b/src/FtpFinishDownloadCommand.cc index ea556f35..9a6cf3b5 100644 --- a/src/FtpFinishDownloadCommand.cc +++ b/src/FtpFinishDownloadCommand.cc @@ -33,6 +33,9 @@ */ /* copyright --> */ #include "FtpFinishDownloadCommand.h" + +#include + #include "Request.h" #include "DownloadEngine.h" #include "prefs.h" @@ -44,7 +47,6 @@ #include "SocketCore.h" #include "RequestGroup.h" #include "Logger.h" -#include namespace aria2 { @@ -82,8 +84,7 @@ bool FtpFinishDownloadCommand::execute() if(status != 226) { throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str()); } - if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) { + if(!isProxyDefined() && e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) { std::pair peerInfo; socket->getPeerInfo(peerInfo); std::map options; diff --git a/src/FtpInitiateConnectionCommand.cc b/src/FtpInitiateConnectionCommand.cc index 389689e3..b63f9906 100644 --- a/src/FtpInitiateConnectionCommand.cc +++ b/src/FtpInitiateConnectionCommand.cc @@ -33,6 +33,9 @@ */ /* copyright --> */ #include "FtpInitiateConnectionCommand.h" + +#include + #include "DownloadEngine.h" #include "Option.h" #include "Request.h" @@ -47,7 +50,6 @@ #include "prefs.h" #include "HttpConnection.h" #include "Socket.h" -#include namespace aria2 { @@ -61,22 +63,28 @@ FtpInitiateConnectionCommand::FtpInitiateConnectionCommand FtpInitiateConnectionCommand::~FtpInitiateConnectionCommand() {} Command* FtpInitiateConnectionCommand::createNextCommand -(const std::deque& resolvedAddresses) +(const std::deque& resolvedAddresses, + const SharedHandle& proxyRequest) { Command* command; - if(useHTTPProxy()) { + if(!proxyRequest.isNull()) { logger->info(MSG_CONNECTING_TO_SERVER, cuid, - e->option->get(PREF_HTTP_PROXY_HOST).c_str(), - e->option->getAsInt(PREF_HTTP_PROXY_PORT)); + proxyRequest->getHost().c_str(), proxyRequest->getPort()); socket.reset(new SocketCore()); socket->establishConnection(resolvedAddresses.front(), - e->option->getAsInt(PREF_HTTP_PROXY_PORT)); + proxyRequest->getPort()); - if(useHTTPProxyGet()) { - SharedHandle hc(new HttpConnection(cuid, socket, e->option)); - command = new HttpRequestCommand(cuid, req, _requestGroup, hc, e, socket); - } else if(useHTTPProxyConnect()) { - command = new FtpTunnelRequestCommand(cuid, req, _requestGroup, e, socket); + if(e->option->get(PREF_HTTP_PROXY_METHOD) == V_GET) { + SharedHandle hc + (new HttpConnection(cuid, socket, e->option)); + + HttpRequestCommand* c = + new HttpRequestCommand(cuid, req, _requestGroup, hc, e, socket); + c->setProxyRequest(proxyRequest); + command = c; + } else if(e->option->get(PREF_HTTP_PROXY_METHOD) == V_TUNNEL) { + command = new FtpTunnelRequestCommand(cuid, req, _requestGroup, e, + proxyRequest, socket); } else { // TODO throw DlAbortEx("ERROR"); @@ -101,12 +109,4 @@ Command* FtpInitiateConnectionCommand::createNextCommand return command; } -bool FtpInitiateConnectionCommand::useHTTPProxyGet() const { - return useHTTPProxy() && e->option->get(PREF_FTP_VIA_HTTP_PROXY) == V_GET; -} - -bool FtpInitiateConnectionCommand::useHTTPProxyConnect() const { - return useHTTPProxy() && e->option->get(PREF_FTP_VIA_HTTP_PROXY) == V_TUNNEL; -} - } // namespace aria2 diff --git a/src/FtpInitiateConnectionCommand.h b/src/FtpInitiateConnectionCommand.h index 6ab962c2..e915753d 100644 --- a/src/FtpInitiateConnectionCommand.h +++ b/src/FtpInitiateConnectionCommand.h @@ -40,12 +40,10 @@ namespace aria2 { class FtpInitiateConnectionCommand : public InitiateConnectionCommand { -private: - bool useHTTPProxyGet() const; - bool useHTTPProxyConnect() const; protected: virtual Command* createNextCommand - (const std::deque& resolvedAddresses); + (const std::deque& resolvedAddresses, + const SharedHandle& proxyRequest); public: FtpInitiateConnectionCommand(int cuid, const SharedHandle& req, RequestGroup* requestGroup, DownloadEngine* e); diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index 827cbb51..39f84c67 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -618,8 +618,7 @@ bool FtpNegotiationCommand::processSequence(const SegmentHandle& segment) { void FtpNegotiationCommand::poolConnection() const { - if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) { + if(!isProxyDefined() && e->option->getAsBool(PREF_FTP_REUSE_CONNECTION)) { std::pair peerInfo; socket->getPeerInfo(peerInfo); std::map options; diff --git a/src/FtpTunnelRequestCommand.cc b/src/FtpTunnelRequestCommand.cc index 403d4e88..09a162c5 100644 --- a/src/FtpTunnelRequestCommand.cc +++ b/src/FtpTunnelRequestCommand.cc @@ -39,12 +39,15 @@ namespace aria2 { -FtpTunnelRequestCommand::FtpTunnelRequestCommand(int cuid, - const RequestHandle& req, - RequestGroup* requestGroup, - DownloadEngine* e, - const SocketHandle& s) - :AbstractProxyRequestCommand(cuid, req, requestGroup, e, s) {} +FtpTunnelRequestCommand::FtpTunnelRequestCommand +(int cuid, + const RequestHandle& req, + RequestGroup* requestGroup, + DownloadEngine* e, + const SharedHandle& proxyRequest, + const SocketHandle& s) + : + AbstractProxyRequestCommand(cuid, req, requestGroup, e, proxyRequest, s) {} FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {} diff --git a/src/FtpTunnelRequestCommand.h b/src/FtpTunnelRequestCommand.h index 535d650b..9a7fc96f 100644 --- a/src/FtpTunnelRequestCommand.h +++ b/src/FtpTunnelRequestCommand.h @@ -47,6 +47,7 @@ public: const SharedHandle& req, RequestGroup* requestGroup, DownloadEngine* e, + const SharedHandle& proxyRequest, const SharedHandle& s); virtual ~FtpTunnelRequestCommand(); diff --git a/src/HttpDownloadCommand.cc b/src/HttpDownloadCommand.cc index e5c9ac30..c6870dc2 100644 --- a/src/HttpDownloadCommand.cc +++ b/src/HttpDownloadCommand.cc @@ -63,7 +63,7 @@ bool HttpDownloadCommand::prepareForNextSegment() { e->commands.push_back(command); return true; } else { - if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED)) { + if(!isProxyDefined()) { if(req->isPipeliningEnabled() || (req->isKeepAliveEnabled() && ((!_transferEncodingDecoder.isNull() && diff --git a/src/HttpInitiateConnectionCommand.cc b/src/HttpInitiateConnectionCommand.cc index 84d8c6d6..8732c8bf 100644 --- a/src/HttpInitiateConnectionCommand.cc +++ b/src/HttpInitiateConnectionCommand.cc @@ -46,6 +46,7 @@ #include "Socket.h" #include "message.h" #include "prefs.h" +#include "A2STR.h" namespace aria2 { @@ -59,22 +60,25 @@ HttpInitiateConnectionCommand::HttpInitiateConnectionCommand HttpInitiateConnectionCommand::~HttpInitiateConnectionCommand() {} Command* HttpInitiateConnectionCommand::createNextCommand -(const std::deque& resolvedAddresses) +(const std::deque& resolvedAddresses, + const SharedHandle& proxyRequest) { Command* command; - if(useHTTPProxy()) { + if(!proxyRequest.isNull()) { logger->info(MSG_CONNECTING_TO_SERVER, cuid, - e->option->get(PREF_HTTP_PROXY_HOST).c_str(), - e->option->getAsInt(PREF_HTTP_PROXY_PORT)); + proxyRequest->getHost().c_str(), proxyRequest->getPort()); socket.reset(new SocketCore()); socket->establishConnection(resolvedAddresses.front(), - e->option->getAsInt(PREF_HTTP_PROXY_PORT)); + proxyRequest->getPort()); if(useProxyTunnel()) { - command = new HttpProxyRequestCommand(cuid, req, _requestGroup, e, socket); + command = new HttpProxyRequestCommand(cuid, req, _requestGroup, e, + proxyRequest, socket); } else if(useProxyGet()) { SharedHandle httpConnection(new HttpConnection(cuid, socket, e->option)); - command = new HttpRequestCommand(cuid, req, _requestGroup, - httpConnection, e, socket); + HttpRequestCommand* c = new HttpRequestCommand(cuid, req, _requestGroup, + httpConnection, e, socket); + c->setProxyRequest(proxyRequest); + command = c; } else { // TODO throw DlAbortEx("ERROR"); diff --git a/src/HttpInitiateConnectionCommand.h b/src/HttpInitiateConnectionCommand.h index c737c6cc..a469b7a1 100644 --- a/src/HttpInitiateConnectionCommand.h +++ b/src/HttpInitiateConnectionCommand.h @@ -45,7 +45,8 @@ private: bool useProxyTunnel() const; protected: virtual Command* createNextCommand - (const std::deque& resolvedAddresses); + (const std::deque& resolvedAddresses, + const SharedHandle& proxyRequest); public: HttpInitiateConnectionCommand(int cuid, const SharedHandle& req, RequestGroup* requestGroup, diff --git a/src/HttpProxyRequestCommand.cc b/src/HttpProxyRequestCommand.cc index bf6621c1..9d0a434b 100644 --- a/src/HttpProxyRequestCommand.cc +++ b/src/HttpProxyRequestCommand.cc @@ -39,12 +39,15 @@ namespace aria2 { -HttpProxyRequestCommand::HttpProxyRequestCommand(int cuid, - const RequestHandle& req, - RequestGroup* requestGroup, - DownloadEngine* e, - const SocketHandle& s) - :AbstractProxyRequestCommand(cuid, req, requestGroup, e, s) {} +HttpProxyRequestCommand::HttpProxyRequestCommand +(int cuid, + const RequestHandle& req, + RequestGroup* requestGroup, + DownloadEngine* e, + const SharedHandle& proxyRequest, + const SocketHandle& s) + : + AbstractProxyRequestCommand(cuid, req, requestGroup, e, proxyRequest, s) {} HttpProxyRequestCommand::~HttpProxyRequestCommand() {} diff --git a/src/HttpProxyRequestCommand.h b/src/HttpProxyRequestCommand.h index efade521..31360e80 100644 --- a/src/HttpProxyRequestCommand.h +++ b/src/HttpProxyRequestCommand.h @@ -47,6 +47,7 @@ public: const SharedHandle& req, RequestGroup* requestGroup, DownloadEngine* e, + const SharedHandle& proxyRequest, const SharedHandle& s); virtual ~HttpProxyRequestCommand(); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 9dd8e976..2b80adaf 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -55,8 +55,6 @@ namespace aria2 { const std::string HttpRequest::USER_AGENT("aria2"); HttpRequest::HttpRequest():entityLength(0), - proxyEnabled(false), - proxyAuthEnabled(false), _contentEncodingEnabled(true), userAgent(USER_AGENT) {} @@ -139,7 +137,7 @@ std::string HttpRequest::createRequest() const SharedHandle authConfig = _authConfigFactory->createAuthConfig(request); std::string requestLine = "GET "; - if(getProtocol() == Request::PROTO_FTP || proxyEnabled) { + if(!_proxyRequest.isNull()) { if(getProtocol() == Request::PROTO_FTP && request->getUsername().empty() && !authConfig->getUser().empty()) { // Insert user into URI, like ftp://USER@host/ @@ -196,14 +194,14 @@ std::string HttpRequest::createRequest() const } requestLine += "\r\n"; } - if(proxyEnabled) { + if(!_proxyRequest.isNull()) { if(request->isKeepAliveEnabled() || request->isPipeliningEnabled()) { requestLine += "Proxy-Connection: Keep-Alive\r\n"; } else { requestLine += "Proxy-Connection: close\r\n"; } } - if(proxyEnabled && proxyAuthEnabled) { + if(!_proxyRequest.isNull() && !_proxyRequest->getUsername().empty()) { requestLine += getProxyAuthString(); } if(!authConfig->getUser().empty()) { @@ -241,6 +239,7 @@ std::string HttpRequest::createRequest() const std::string HttpRequest::createProxyRequest() const { + assert(!_proxyRequest.isNull()); std::string requestLine = std::string("CONNECT ")+getHost()+":"+Util::uitos(getPort())+ std::string(" HTTP/1.1\r\n")+ @@ -251,7 +250,7 @@ std::string HttpRequest::createProxyRequest() const }else { requestLine += "Proxy-Connection: close\r\n"; } - if(proxyAuthEnabled) { + if(!_proxyRequest->getUsername().empty()) { requestLine += getProxyAuthString(); } requestLine += "\r\n"; @@ -261,8 +260,9 @@ std::string HttpRequest::createProxyRequest() const std::string HttpRequest::getProxyAuthString() const { return "Proxy-Authorization: Basic "+ - Base64::encode(_authConfigFactory->createAuthConfigForHttpProxy(request)-> - getAuthText())+"\r\n"; + Base64::encode(_proxyRequest->getUsername()+":"+ + _proxyRequest->getPassword()) + +"\r\n"; } void HttpRequest::enableContentEncoding() @@ -287,14 +287,6 @@ void HttpRequest::addAcceptType(const std::string& type) _acceptTypes.push_back(type); } -void HttpRequest::configure(const Option* option) -{ - proxyEnabled = - option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - option->get(PREF_HTTP_PROXY_METHOD) == V_GET; - proxyAuthEnabled = option->getAsBool(PREF_HTTP_PROXY_AUTH_ENABLED); -} - const std::string& HttpRequest::getPreviousURI() const { return request->getPreviousUrl(); @@ -357,4 +349,9 @@ void HttpRequest::setAuthConfigFactory _authConfigFactory = factory; } +void HttpRequest::setProxyRequest(const SharedHandle& proxyRequest) +{ + _proxyRequest = proxyRequest; +} + } // namespace aria2 diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 8069851c..b80089bb 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -62,10 +62,6 @@ private: uint64_t entityLength; - bool proxyEnabled; - - bool proxyAuthEnabled; - bool _contentEncodingEnabled; std::string userAgent; @@ -78,6 +74,8 @@ private: SharedHandle _authConfigFactory; + SharedHandle _proxyRequest; + std::string getHostText(const std::string& host, uint16_t port) const; std::string getProxyAuthString() const; @@ -147,25 +145,6 @@ public: */ std::string createProxyRequest() const; - /** - * Configures this object with option. - * Following values are evaluated: - * PREF_HTTP_PROXY_ENABLED, - * PREF_HTTP_PROXY_METHOD, PREF_HTTP_PROXY_AUTH_ENABLED, - * The evaluation results are stored in instance variables. - */ - void configure(const Option* option); - - void setProxyEnabled(bool proxyEnabled) - { - this->proxyEnabled = proxyEnabled; - } - - void setProxyAuthEnabled(bool proxyAuthEnabled) - { - this->proxyAuthEnabled = proxyAuthEnabled; - } - void enableContentEncoding(); void disableContentEncoding(); @@ -191,6 +170,12 @@ public: SharedHandle getCookieStorage() const; void setAuthConfigFactory(const SharedHandle& factory); + + /* + * To use proxy, pass proxy string to Request::setUrl() and set it this + * object. + */ + void setProxyRequest(const SharedHandle& proxyRequest); }; typedef SharedHandle HttpRequestHandle; diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc index 6f8be74d..9e39ebb2 100644 --- a/src/HttpRequestCommand.cc +++ b/src/HttpRequestCommand.cc @@ -79,7 +79,8 @@ createHttpRequest(const SharedHandle& req, const Option* option, const RequestGroup* rg, const SharedHandle& cookieStorage, - const SharedHandle& authConfigFactory) + const SharedHandle& authConfigFactory, + const SharedHandle& proxyRequest) { HttpRequestHandle httpRequest(new HttpRequest()); httpRequest->setUserAgent(option->get(PREF_USER_AGENT)); @@ -89,6 +90,7 @@ createHttpRequest(const SharedHandle& req, httpRequest->addHeader(option->get(PREF_HEADER)); httpRequest->setCookieStorage(cookieStorage); httpRequest->setAuthConfigFactory(authConfigFactory); + httpRequest->setProxyRequest(proxyRequest); if(!rg->getAcceptFeatures().empty()) { const std::deque& acceptFeatures = rg->getAcceptFeatures(); std::string acceptFeaturesHeader = "Accept-Features: "; @@ -98,7 +100,6 @@ createHttpRequest(const SharedHandle& req, } httpRequest->addAcceptType(rg->getAcceptTypes().begin(), rg->getAcceptTypes().end()); - httpRequest->configure(option); return httpRequest; } @@ -123,7 +124,8 @@ bool HttpRequestCommand::executeInternal() { _requestGroup->getTotalLength(), e->option, _requestGroup, e->getCookieStorage(), - e->getAuthConfigFactory())); + e->getAuthConfigFactory(), + _proxyRequest)); _httpConnection->sendRequest(httpRequest); } else { for(Segments::iterator itr = _segments.begin(); itr != _segments.end(); ++itr) { @@ -134,7 +136,8 @@ bool HttpRequestCommand::executeInternal() { _requestGroup->getTotalLength(), e->option, _requestGroup, e->getCookieStorage(), - e->getAuthConfigFactory())); + e->getAuthConfigFactory(), + _proxyRequest)); _httpConnection->sendRequest(httpRequest); } } @@ -155,4 +158,10 @@ bool HttpRequestCommand::executeInternal() { } } +void HttpRequestCommand::setProxyRequest +(const SharedHandle& proxyRequest) +{ + _proxyRequest = proxyRequest; +} + } // namespace aria2 diff --git a/src/HttpRequestCommand.h b/src/HttpRequestCommand.h index f406ce34..33ec8c6f 100644 --- a/src/HttpRequestCommand.h +++ b/src/HttpRequestCommand.h @@ -44,6 +44,8 @@ class SocketCore; class HttpRequestCommand:public AbstractCommand { private: + SharedHandle _proxyRequest; + SharedHandle _httpConnection; protected: virtual bool executeInternal(); @@ -55,6 +57,8 @@ public: DownloadEngine* e, const SharedHandle& s); virtual ~HttpRequestCommand(); + + void setProxyRequest(const SharedHandle& proxyRequest); }; } // namespace aria2 diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc index e2ada749..1cacc0b6 100644 --- a/src/HttpSkipResponseCommand.cc +++ b/src/HttpSkipResponseCommand.cc @@ -137,8 +137,7 @@ bool HttpSkipResponseCommand::executeInternal() void HttpSkipResponseCommand::poolConnection() const { - if(!e->option->getAsBool(PREF_HTTP_PROXY_ENABLED) && - req->supportsPersistentConnection()) { + if(!isProxyDefined() && req->supportsPersistentConnection()) { std::pair peerInfo; socket->getPeerInfo(peerInfo); e->poolSocket(peerInfo.first, peerInfo.second, socket); diff --git a/src/InitiateConnectionCommand.cc b/src/InitiateConnectionCommand.cc index 7f56931c..512da0b1 100644 --- a/src/InitiateConnectionCommand.cc +++ b/src/InitiateConnectionCommand.cc @@ -62,10 +62,11 @@ InitiateConnectionCommand::~InitiateConnectionCommand() {} bool InitiateConnectionCommand::executeInternal() { std::string hostname; - if(useHTTPProxy()) { - hostname = e->option->get(PREF_HTTP_PROXY_HOST); - } else { + SharedHandle proxyRequest = createProxyRequest(); + if(proxyRequest.isNull()) { hostname = req->getHost(); + } else { + hostname = proxyRequest->getHost(); } std::deque addrs; std::string ipaddr = e->findCachedIPAddress(hostname); @@ -97,14 +98,9 @@ bool InitiateConnectionCommand::executeInternal() { addrs.push_back(ipaddr); } - Command* command = createNextCommand(addrs); + Command* command = createNextCommand(addrs, proxyRequest); e->commands.push_back(command); return true; } -bool InitiateConnectionCommand::useHTTPProxy() const -{ - return e->option->getAsBool(PREF_HTTP_PROXY_ENABLED); -} - } // namespace aria2 diff --git a/src/InitiateConnectionCommand.h b/src/InitiateConnectionCommand.h index f173abd4..e7d1c901 100644 --- a/src/InitiateConnectionCommand.h +++ b/src/InitiateConnectionCommand.h @@ -41,8 +41,6 @@ namespace aria2 { class InitiateConnectionCommand : public AbstractCommand { protected: - bool useHTTPProxy() const; - /** * Connect to the server. * This method just send connection request to the server. @@ -52,7 +50,8 @@ protected: virtual bool executeInternal(); virtual Command* createNextCommand - (const std::deque& resolvedAddresses) = 0; + (const std::deque& resolvedAddresses, + const SharedHandle& proxyRequest) = 0; public: InitiateConnectionCommand(int cuid, const SharedHandle& req, RequestGroup* requestGroup, diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc index aa55ec6d..c1c4423c 100644 --- a/src/OptionHandlerFactory.cc +++ b/src/OptionHandlerFactory.cc @@ -471,30 +471,6 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() op->addTag(TAG_HTTP); handlers.push_back(op); } - { - SharedHandle op(new HttpProxyOptionHandler - (PREF_HTTP_PROXY, - TEXT_HTTP_PROXY, - NO_DEFAULT_VALUE, - PREF_HTTP_PROXY_HOST, - PREF_HTTP_PROXY_PORT)); - op->addTag(TAG_HTTP); - handlers.push_back(op); - } - { - SharedHandle op(new DefaultOptionHandler - (PREF_HTTP_PROXY_USER, - TEXT_HTTP_PROXY_USER)); - op->addTag(TAG_HTTP); - handlers.push_back(op); - } - { - SharedHandle op(new DefaultOptionHandler - (PREF_HTTP_PROXY_PASSWD, - TEXT_HTTP_PROXY_PASSWD)); - op->addTag(TAG_HTTP); - handlers.push_back(op); - } { SharedHandle op(new ParameterOptionHandler (PREF_HTTP_PROXY_METHOD, @@ -588,15 +564,6 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() op->addTag(TAG_FTP); handlers.push_back(op); } - { - SharedHandle op(new ParameterOptionHandler - (PREF_FTP_VIA_HTTP_PROXY, - TEXT_FTP_VIA_HTTP_PROXY, - V_TUNNEL, - V_GET, V_TUNNEL)); - op->addTag(TAG_FTP); - handlers.push_back(op); - } { SharedHandle op(new DefaultOptionHandler (PREF_NETRC_PATH, @@ -615,6 +582,40 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() op->addTag(TAG_HTTP); handlers.push_back(op); } + // Proxy options + { + SharedHandle op(new HttpProxyOptionHandler + (PREF_HTTP_PROXY, + TEXT_HTTP_PROXY, + NO_DEFAULT_VALUE)); + op->addTag(TAG_HTTP); + handlers.push_back(op); + } + { + SharedHandle op(new HttpProxyOptionHandler + (PREF_HTTPS_PROXY, + TEXT_HTTPS_PROXY, + NO_DEFAULT_VALUE)); + op->addTag(TAG_HTTP); + handlers.push_back(op); + } + { + SharedHandle op(new HttpProxyOptionHandler + (PREF_FTP_PROXY, + TEXT_FTP_PROXY, + NO_DEFAULT_VALUE)); + op->addTag(TAG_FTP); + handlers.push_back(op); + } + { + SharedHandle op(new HttpProxyOptionHandler + (PREF_ALL_PROXY, + TEXT_ALL_PROXY, + NO_DEFAULT_VALUE)); + op->addTag(TAG_HTTP); + op->addTag(TAG_FTP); + handlers.push_back(op); + } // BitTorrent/Metalink Options { SharedHandle op(new IntegerRangeOptionHandler diff --git a/src/OptionHandlerImpl.h b/src/OptionHandlerImpl.h index a59e4bd1..b9160115 100644 --- a/src/OptionHandlerImpl.h +++ b/src/OptionHandlerImpl.h @@ -36,6 +36,14 @@ #define _D_OPTION_HANDLER_IMPL_H_ #include "OptionHandler.h" + +#include +#include +#include +#include +#include +#include + #include "NameMatchOptionHandler.h" #include "Util.h" #include "FatalException.h" @@ -43,12 +51,7 @@ #include "Option.h" #include "StringFormat.h" #include "A2STR.h" -#include -#include -#include -#include -#include -#include +#include "Request.h" namespace aria2 { @@ -439,23 +442,36 @@ public: } }; -class HttpProxyOptionHandler : public HostPortOptionHandler { +class HttpProxyOptionHandler : public NameMatchOptionHandler { public: HttpProxyOptionHandler(const std::string& optName, const std::string& description, - const std::string& defaultValue, - const std::string& hostOptionName, - const std::string& portOptionName): - HostPortOptionHandler(optName, description, defaultValue, - hostOptionName, portOptionName) + const std::string& defaultValue) + : + NameMatchOptionHandler(optName, description, defaultValue) {} virtual ~HttpProxyOptionHandler() {} virtual void parseArg(Option* option, const std::string& optarg) { - HostPortOptionHandler::parseArg(option, optarg); - option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE); + Request req; + std::string url; + if(Util::startsWith(optarg, "http://")) { + url = optarg; + } else { + url = "http://"+optarg; + } + if(req.setUrl(url)) { + option->put(_optName, url); + } else { + throw FatalException(_("unrecognized proxy format")); + } + } + + virtual std::string createPossibleValuesString() const + { + return "[http://][USER:PASSWORD@]HOST[:PORT]"; } }; diff --git a/src/Request.cc b/src/Request.cc index 1fc5ad71..8918d1be 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -197,7 +197,11 @@ bool Request::parseUrl(const std::string& url) { host = hostAndPort.first; if(hostAndPort.second != A2STR::NIL) { try { - port = Util::parseInt(hostAndPort.second); + unsigned int tempPort = Util::parseUInt(hostAndPort.second); + if(65535 < tempPort) { + return false; + } + port = tempPort; } catch(RecoverableException& e) { return false; } diff --git a/src/option_processing.cc b/src/option_processing.cc index a20852c4..19dcc591 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -107,8 +107,8 @@ Option* option_processing(int argc, char* const argv[]) { PREF_HTTP_PROXY.c_str(), required_argument, &lopt, 1 }, { PREF_HTTP_USER.c_str(), required_argument, &lopt, 2 }, { PREF_HTTP_PASSWD.c_str(), required_argument, &lopt, 3 }, - { PREF_HTTP_PROXY_USER.c_str(), required_argument, &lopt, 4 }, - { PREF_HTTP_PROXY_PASSWD.c_str(), required_argument, &lopt, 5 }, + { "http-proxy-user", required_argument, &lopt, 4 }, + { "http-proxy-passwd", required_argument, &lopt, 5 }, { PREF_HTTP_AUTH_SCHEME.c_str(), required_argument, &lopt, 6 }, { PREF_REFERER.c_str(), required_argument, &lopt, 7 }, { PREF_RETRY_WAIT.c_str(), required_argument, &lopt, 8 }, @@ -116,7 +116,7 @@ Option* option_processing(int argc, char* const argv[]) { PREF_FTP_PASSWD.c_str(), required_argument, &lopt, 10 }, { PREF_FTP_TYPE.c_str(), required_argument, &lopt, 11 }, { PREF_FTP_PASV.c_str(), no_argument, NULL, 'p' }, - { PREF_FTP_VIA_HTTP_PROXY.c_str(), required_argument, &lopt, 12 }, + { "ftp-via-http-proxy", required_argument, &lopt, 12 }, { PREF_HTTP_PROXY_METHOD.c_str(), required_argument, &lopt, 14 }, { PREF_LOWEST_SPEED_LIMIT.c_str(), required_argument, &lopt, 200 }, { PREF_MAX_DOWNLOAD_LIMIT.c_str(), required_argument, &lopt, 201 }, @@ -161,6 +161,9 @@ Option* option_processing(int argc, char* const argv[]) { PREF_CONNECT_TIMEOUT.c_str(), required_argument, &lopt, 224 }, { PREF_MAX_FILE_NOT_FOUND.c_str(), required_argument, &lopt, 225 }, { PREF_AUTO_SAVE_INTERVAL.c_str(), required_argument, &lopt, 226 }, + { PREF_HTTPS_PROXY.c_str(), required_argument, &lopt, 227 }, + { PREF_FTP_PROXY.c_str(), required_argument, &lopt, 228 }, + { PREF_ALL_PROXY.c_str(), required_argument, &lopt, 229 }, #if defined ENABLE_BITTORRENT || defined ENABLE_METALINK { PREF_SHOW_FILES.c_str(), no_argument, NULL, 'S' }, { PREF_SELECT_FILE.c_str(), required_argument, &lopt, 21 }, @@ -221,11 +224,15 @@ Option* option_processing(int argc, char* const argv[]) cmdstream << PREF_HTTP_PASSWD << "=" << optarg << "\n"; break; case 4: - cmdstream << PREF_HTTP_PROXY_USER << "=" << optarg << "\n"; - break; + std::cout << "--http-proxy-user was deprecated. See --http-proxy," + << " --https-proxy, --ftp-proxy, --all-proxy options." + << std::endl; + exit(EXIT_FAILURE); case 5: - cmdstream << PREF_HTTP_PROXY_PASSWD << "=" << optarg << "\n"; - break; + std::cout << "--http-proxy-passwd was deprecated. See --http-proxy," + << " --https-proxy, --ftp-proxy, --all-proxy options." + << std::endl; + exit(EXIT_FAILURE); case 6: cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n"; break; @@ -245,8 +252,10 @@ Option* option_processing(int argc, char* const argv[]) cmdstream << PREF_FTP_TYPE << "=" << optarg << "\n"; break; case 12: - cmdstream << PREF_FTP_VIA_HTTP_PROXY << "=" << optarg << "\n"; - break; + std::cout << "--ftp-via-http-proxy was deprecated." + << " Use --http-proxy-method option instead." + << std::endl; + exit(EXIT_FAILURE); case 14: cmdstream << PREF_HTTP_PROXY_METHOD << "=" << optarg << "\n"; break; @@ -409,6 +418,15 @@ Option* option_processing(int argc, char* const argv[]) case 226: cmdstream << PREF_AUTO_SAVE_INTERVAL << "=" << optarg << "\n"; break; + case 227: + cmdstream << PREF_HTTPS_PROXY << "=" << optarg << "\n"; + break; + case 228: + cmdstream << PREF_FTP_PROXY << "=" << optarg << "\n"; + break; + case 229: + cmdstream << PREF_ALL_PROXY << "=" << optarg << "\n"; + break; } break; } @@ -545,9 +563,6 @@ Option* option_processing(int argc, char* const argv[]) exit(EXIT_FAILURE); } } - if(op->defined(PREF_HTTP_PROXY_USER)) { - op->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE); - } if( #ifdef ENABLE_BITTORRENT !op->defined(PREF_TORRENT_FILE) && diff --git a/src/prefs.cc b/src/prefs.cc index e55b7332..8b412fc2 100644 --- a/src/prefs.cc +++ b/src/prefs.cc @@ -155,10 +155,6 @@ const std::string PREF_FTP_PASSWD("ftp-passwd"); const std::string PREF_FTP_TYPE("ftp-type"); const std::string V_BINARY("binary"); const std::string V_ASCII("ascii"); -// values: get | tunnel -const std::string PREF_FTP_VIA_HTTP_PROXY("ftp-via-http-proxy"); -const std::string V_GET("get"); -const std::string V_TUNNEL("tunnel"); // values: true | false const std::string PREF_FTP_PASV("ftp-pasv"); // values: true | false @@ -186,19 +182,16 @@ const std::string PREF_MAX_HTTP_PIPELINING("max-http-pipelining"); const std::string PREF_HEADER("header"); /** - * HTTP proxy related preferences + * Proxy related preferences */ const std::string PREF_HTTP_PROXY("http-proxy"); -const std::string PREF_HTTP_PROXY_USER("http-proxy-user"); -const std::string PREF_HTTP_PROXY_PASSWD("http-proxy-passwd"); -const std::string PREF_HTTP_PROXY_HOST("http-proxy-host"); -const std::string PREF_HTTP_PROXY_PORT("http-proxy-port"); +const std::string PREF_HTTPS_PROXY("https-proxy"); +const std::string PREF_FTP_PROXY("ftp-proxy"); +const std::string PREF_ALL_PROXY("all-proxy"); // values: get | tunnel const std::string PREF_HTTP_PROXY_METHOD("http-proxy-method"); -// values: true | false -const std::string PREF_HTTP_PROXY_ENABLED("http-proxy-enabled"); -// values: true | false -const std::string PREF_HTTP_PROXY_AUTH_ENABLED("http-proxy-auth-enabled"); +const std::string V_GET("get"); +const std::string V_TUNNEL("tunnel"); /** * BitTorrent related preferences diff --git a/src/prefs.h b/src/prefs.h index 75822be6..6dc4847c 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -159,10 +159,6 @@ extern const std::string PREF_FTP_PASSWD; extern const std::string PREF_FTP_TYPE; extern const std::string V_BINARY; extern const std::string V_ASCII; -// values: get | tunnel -extern const std::string PREF_FTP_VIA_HTTP_PROXY; -extern const std::string V_GET; -extern const std::string V_TUNNEL; // values: true | false extern const std::string PREF_FTP_PASV; // values: true | false @@ -190,19 +186,16 @@ extern const std::string PREF_MAX_HTTP_PIPELINING; extern const std::string PREF_HEADER; /**; - * HTTP proxy related preferences + * Proxy related preferences */ extern const std::string PREF_HTTP_PROXY; -extern const std::string PREF_HTTP_PROXY_USER; -extern const std::string PREF_HTTP_PROXY_PASSWD; -extern const std::string PREF_HTTP_PROXY_HOST; -extern const std::string PREF_HTTP_PROXY_PORT; +extern const std::string PREF_HTTPS_PROXY; +extern const std::string PREF_FTP_PROXY; +extern const std::string PREF_ALL_PROXY; // values: get | tunnel extern const std::string PREF_HTTP_PROXY_METHOD; -// values: true | false -extern const std::string PREF_HTTP_PROXY_ENABLED; -// values: true | false -extern const std::string PREF_HTTP_PROXY_AUTH_ENABLED; +extern const std::string V_GET; +extern const std::string V_TUNNEL; /** * BitTorrent related preferences diff --git a/src/usage_text.h b/src/usage_text.h index fdf00dfc..66fa9237 100644 --- a/src/usage_text.h +++ b/src/usage_text.h @@ -57,15 +57,28 @@ _(" -t, --timeout=SEC Set timeout in seconds.") #define TEXT_MAX_TRIES \ _(" -m, --max-tries=N Set number of tries. 0 means unlimited.") #define TEXT_HTTP_PROXY \ -_(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects all URLs.") +_(" --http-proxy=PROXY Use this proxy server for HTTP.\n"\ + " See also --all-proxy option.\n"\ + " This affects all URLs.") +#define TEXT_HTTPS_PROXY \ +_(" --https-proxy=PROXY Use this proxy server for HTTPS.\n"\ + " See also --all-proxy option.\n"\ + " This affects all URLs.") +#define TEXT_FTP_PROXY \ +_(" --ftp-proxy=PROXY Use this proxy server for FTP.\n"\ + " See also --all-proxy option.\n"\ + " This affects all URLs.") +#define TEXT_ALL_PROXY \ +_(" --all-proxy=PROXY Use this proxy server in the all protocols.\n"\ + " You can override this setting and specify a\n"\ + " proxy server for particular proctol using\n"\ + " --http-proxy, --https-proxy and --ftp-proxy\n"\ + " options.\n"\ + " This affects all URLs.") #define TEXT_HTTP_USER \ _(" --http-user=USER Set HTTP user. This affects all URLs.") #define TEXT_HTTP_PASSWD \ _(" --http-passwd=PASSWD Set HTTP password. This affects all URLs.") -#define TEXT_HTTP_PROXY_USER \ -_(" --http-proxy-user=USER Set HTTP proxy user. This affects all URLs.") -#define TEXT_HTTP_PROXY_PASSWD \ -_(" --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects all URLs.") #define TEXT_HTTP_PROXY_METHOD \ _(" --http-proxy-method=METHOD Set the method to use in proxy request.") #define TEXT_HTTP_AUTH_SCHEME \ @@ -81,8 +94,6 @@ _(" --ftp-passwd=PASSWD Set FTP password. This affects all URLs.") _(" --ftp-type=TYPE Set FTP transfer type.") #define TEXT_FTP_PASV \ _(" -p, --ftp-pasv Use passive mode in FTP.") -#define TEXT_FTP_VIA_HTTP_PROXY \ -_(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP.") #define TEXT_LOWEST_SPEED_LIMIT \ _(" --lowest-speed-limit=SPEED Close connection if download speed is lower than\n"\ " or equal to this value(bytes per sec).\n"\ diff --git a/test/AuthConfigFactoryTest.cc b/test/AuthConfigFactoryTest.cc index 67eaac18..6014e052 100644 --- a/test/AuthConfigFactoryTest.cc +++ b/test/AuthConfigFactoryTest.cc @@ -1,10 +1,12 @@ #include "AuthConfigFactory.h" + +#include + #include "Netrc.h" #include "prefs.h" #include "Request.h" #include "AuthConfig.h" #include "Option.h" -#include namespace aria2 { @@ -12,13 +14,11 @@ class AuthConfigFactoryTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(AuthConfigFactoryTest); CPPUNIT_TEST(testCreateAuthConfig_http); - CPPUNIT_TEST(testCreateAuthConfigForHttpProxy); CPPUNIT_TEST(testCreateAuthConfig_ftp); CPPUNIT_TEST_SUITE_END(); public: void testCreateAuthConfig_http(); - void testCreateAuthConfigForHttpProxy(); void testCreateAuthConfig_ftp(); }; @@ -71,32 +71,6 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http() factory.createAuthConfig(req)->getAuthText()); } -void AuthConfigFactoryTest::testCreateAuthConfigForHttpProxy() -{ - SharedHandle req(new Request()); - req->setUrl("http://localhost/download/aria2-1.0.0.tar.bz2"); - // with Netrc - SharedHandle netrc(new Netrc()); - netrc->addAuthenticator - (SharedHandle(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"))); - - Option option; - option.put(PREF_NO_NETRC, V_FALSE); - - AuthConfigFactory factory(&option); - factory.setNetrc(netrc); - - // netrc is not used in http proxy auth - CPPUNIT_ASSERT_EQUAL(std::string(":"), - factory.createAuthConfigForHttpProxy(req)->getAuthText()); - - option.put(PREF_HTTP_PROXY_USER, "userDefinedUser"); - option.put(PREF_HTTP_PROXY_PASSWD, "userDefinedPassword"); - CPPUNIT_ASSERT_EQUAL(std::string("userDefinedUser:userDefinedPassword"), - factory.createAuthConfigForHttpProxy(req)->getAuthText()); - -} - void AuthConfigFactoryTest::testCreateAuthConfig_ftp() { SharedHandle req(new Request()); diff --git a/test/HttpRequestTest.cc b/test/HttpRequestTest.cc index 120cb0d4..62a60d4c 100644 --- a/test/HttpRequestTest.cc +++ b/test/HttpRequestTest.cc @@ -106,12 +106,6 @@ void HttpRequestTest::testCreateRequest() { SharedHandle p; - _option->put(PREF_HTTP_PROXY_ENABLED, V_FALSE); - _option->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL); - _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE); - _option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser"); - _option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd"); - SharedHandle request(new Request()); request->supportsPersistentConnection(true); @@ -225,8 +219,6 @@ void HttpRequestTest::testCreateRequest() _option->put(PREF_HTTP_USER, "aria2user"); _option->put(PREF_HTTP_PASSWD, "aria2passwd"); - httpRequest.configure(_option.get()); - expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n" "User-Agent: aria2\r\n" "Accept: */*\r\n" @@ -240,41 +232,10 @@ void HttpRequestTest::testCreateRequest() CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); // enable http proxy auth - _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE); - - httpRequest.configure(_option.get()); - - expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n" - "User-Agent: aria2\r\n" - "Accept: */*\r\n" - "Host: localhost:8080\r\n" - "Pragma: no-cache\r\n" - "Cache-Control: no-cache\r\n" - "Connection: close\r\n" - "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n" - "\r\n"; - - CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); - - _option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE); - - httpRequest.configure(_option.get()); - - expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n" - "User-Agent: aria2\r\n" - "Accept: */*\r\n" - "Host: localhost:8080\r\n" - "Pragma: no-cache\r\n" - "Cache-Control: no-cache\r\n" - "Connection: close\r\n" - "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n" - "\r\n"; - - CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); - - _option->put(PREF_HTTP_PROXY_METHOD, V_GET); - - httpRequest.configure(_option.get()); + SharedHandle proxyRequest(new Request()); + CPPUNIT_ASSERT(proxyRequest->setUrl + ("http://aria2proxyuser:aria2proxypasswd@localhost:9000")); + httpRequest.setProxyRequest(proxyRequest); expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n" "User-Agent: aria2\r\n" @@ -308,9 +269,8 @@ void HttpRequestTest::testCreateRequest() request->setPipeliningHint(false); - _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE); - - httpRequest.configure(_option.get()); + // turn off proxy auth + CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000")); expectedText = "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n" "User-Agent: aria2\r\n" @@ -328,17 +288,16 @@ void HttpRequestTest::testCreateRequest() void HttpRequestTest::testCreateRequest_ftp() { - _option->put(PREF_HTTP_PROXY_ENABLED, V_FALSE); - _option->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL); - _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_FALSE); - _option->put(PREF_FTP_USER, "aria2user"); - _option->put(PREF_FTP_PASSWD, "aria2passwd"); - _option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser"); - _option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd"); + _option->put(PREF_FTP_USER, "aria2user"); + _option->put(PREF_FTP_PASSWD, "aria2passwd"); SharedHandle request(new Request()); request->setUrl("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2"); + SharedHandle proxyRequest(new Request()); + CPPUNIT_ASSERT(proxyRequest->setUrl + ("http://localhost:9000")); + HttpRequest httpRequest; SharedHandle p(new Piece(0, 1024*1024)); SharedHandle segment @@ -347,8 +306,7 @@ void HttpRequestTest::testCreateRequest_ftp() httpRequest.setRequest(request); httpRequest.setSegment(segment); httpRequest.setAuthConfigFactory(_authConfigFactory); - - httpRequest.configure(_option.get()); + httpRequest.setProxyRequest(proxyRequest); std::string expectedText = "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2" @@ -359,17 +317,15 @@ void HttpRequestTest::testCreateRequest_ftp() "Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n" "Connection: close\r\n" + "Proxy-Connection: close\r\n" "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n" "\r\n"; CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); - // How to enable HTTP proxy authorization in FTP download via HTTP proxy - _option->put(PREF_HTTP_PROXY_ENABLED, V_TRUE); - _option->put(PREF_HTTP_PROXY_METHOD, V_GET); - _option->put(PREF_HTTP_PROXY_AUTH_ENABLED, V_TRUE); - - httpRequest.configure(_option.get()); + // test proxy authorization + CPPUNIT_ASSERT(proxyRequest->setUrl + ("http://aria2proxyuser:aria2proxypasswd@localhost:9000")); expectedText = "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2" @@ -386,7 +342,6 @@ void HttpRequestTest::testCreateRequest_ftp() "\r\n"; CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); - } void HttpRequestTest::testCreateRequest_with_cookie() @@ -502,10 +457,14 @@ void HttpRequestTest::testCreateProxyRequest() SharedHandle p(new Piece(0, 1024*1024)); SharedHandle segment(new PiecedSegment(1024*1024, p)); + SharedHandle proxyRequest(new Request()); + CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000")); + HttpRequest httpRequest; httpRequest.setRequest(request); httpRequest.setSegment(segment); + httpRequest.setProxyRequest(proxyRequest); request->supportsPersistentConnection(true); @@ -538,7 +497,20 @@ void HttpRequestTest::testCreateProxyRequest() "Proxy-Connection: Keep-Alive\r\n" "\r\n"; - CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest()); + CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest()); + + // test proxy authorization + CPPUNIT_ASSERT(proxyRequest->setUrl + ("http://aria2proxyuser:aria2proxypasswd@localhost:9000")); + + expectedText = "CONNECT localhost:80 HTTP/1.1\r\n" + "User-Agent: aria2\r\n" + "Host: localhost:80\r\n" + "Proxy-Connection: Keep-Alive\r\n" + "Proxy-Authorization: Basic YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n" + "\r\n"; + + CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest()); } void HttpRequestTest::testIsRangeSatisfied() @@ -621,6 +593,11 @@ void HttpRequestTest::testUserAgent() CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest()); + SharedHandle proxyRequest(new Request()); + CPPUNIT_ASSERT(proxyRequest->setUrl("http://localhost:9000")); + + httpRequest.setProxyRequest(proxyRequest); + std::string expectedTextForProxy = "CONNECT localhost:8080 HTTP/1.1\r\n" "User-Agent: aria2 (Linux)\r\n" "Host: localhost:8080\r\n" diff --git a/test/OptionHandlerTest.cc b/test/OptionHandlerTest.cc index 22d5fd6c..67d5de35 100644 --- a/test/OptionHandlerTest.cc +++ b/test/OptionHandlerTest.cc @@ -328,51 +328,29 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max() void OptionHandlerTest::testHttpProxyOptionHandler() { - HttpProxyOptionHandler handler(PREF_HTTP_PROXY, - "", - "", - PREF_HTTP_PROXY_HOST, - PREF_HTTP_PROXY_PORT); + HttpProxyOptionHandler handler(PREF_HTTP_PROXY, "", ""); CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY)); CPPUNIT_ASSERT(!handler.canHandle("foobar")); Option option; - handler.parse(&option, "bar:80"); - CPPUNIT_ASSERT_EQUAL(std::string("bar:80"), option.get(PREF_HTTP_PROXY)); - CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get(PREF_HTTP_PROXY_HOST)); - CPPUNIT_ASSERT_EQUAL(std::string("80"), option.get(PREF_HTTP_PROXY_PORT)); - CPPUNIT_ASSERT_EQUAL(std::string(V_TRUE), option.get(PREF_HTTP_PROXY_ENABLED)); + handler.parse(&option, "proxy:65535"); + CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:65535"), + option.get(PREF_HTTP_PROXY)); + + handler.parse(&option, "http://proxy:8080"); + CPPUNIT_ASSERT_EQUAL(std::string("http://proxy:8080"), + option.get(PREF_HTTP_PROXY)); + + handler.parse(&option, "ftp://proxy:8080"); + CPPUNIT_ASSERT_EQUAL(std::string("http://ftp://proxy:8080"), + option.get(PREF_HTTP_PROXY)); try { - handler.parse(&option, "bar"); + handler.parse(&option, "http://bar:65536"); CPPUNIT_FAIL("exception must be thrown."); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; } - try { - handler.parse(&option, "bar:"); - CPPUNIT_FAIL("exception must be thrown."); - } catch(Exception& e) { - std::cerr << e.stackTrace() << std::endl; - } - try { - handler.parse(&option, ":"); - CPPUNIT_FAIL("exception must be thrown."); - } catch(Exception& e) { - std::cerr << e.stackTrace() << std::endl; - } - try { - handler.parse(&option, ":80"); - CPPUNIT_FAIL("exception must be thrown."); - } catch(Exception& e) { - std::cerr << e.stackTrace() << std::endl; - } - try { - handler.parse(&option, "foo:bar"); - CPPUNIT_FAIL("exception must be thrown."); - } catch(Exception& e) { - std::cerr << e.stackTrace() << std::endl; - } - CPPUNIT_ASSERT_EQUAL(std::string("HOST:PORT"), + CPPUNIT_ASSERT_EQUAL(std::string("[http://][USER:PASSWORD@]HOST[:PORT]"), handler.createPossibleValuesString()); }