diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-01-30 16:12:41 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-01-30 16:12:41 +0000 |
| commit | e5c4b24454a37ad6eb5eae3a0685115e4078a06a (patch) | |
| tree | 16138c045553f9c1df8d71a14a62101640b0bf32 /src/AuthConfigFactory.cc | |
| parent | 120ea4c609b28c7fd3d907f1fa689737df92b8ef (diff) | |
2009-01-31 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Send HTTP Authorization header only if it is requested by the
server(response 401). There are some exceptions. The
authorization header for proxy is always sent if it is available
without request by the server. If username/password is specified
in the URI, it is immediately sent to the server without
request by the server.
AbstractAuthResolver::_defaultAuthConfig is now initialized as
SharedHandle<AuthConfig>().
NetrcAuthResolver::resolveAuthConfig() returns
SharedHandle<AuthConfig>() if no AuthConfig is available.
* src/AbstractAuthResolver.cc
* src/AbstractProxyRequestCommand.cc
* src/AuthConfigFactory.cc
* src/AuthConfigFactory.h
* src/HttpConnection.cc
* src/HttpRequest.cc
* src/HttpRequest.h
* src/HttpResponse.cc
* src/HttpResponseCommand.cc
* src/HttpSkipResponseCommand.cc
* test/AuthConfigFactoryTest.cc
* test/HttpRequestTest.cc
* test/HttpResponseTest.cc
Diffstat (limited to 'src/AuthConfigFactory.cc')
| -rw-r--r-- | src/AuthConfigFactory.cc | 115 |
1 files changed, 112 insertions, 3 deletions
diff --git a/src/AuthConfigFactory.cc b/src/AuthConfigFactory.cc index 1fb61ea5..c5bf4f9f 100644 --- a/src/AuthConfigFactory.cc +++ b/src/AuthConfigFactory.cc @@ -33,6 +33,9 @@ */ /* copyright --> */ #include "AuthConfigFactory.h" + +#include <algorithm> + #include "Option.h" #include "AuthConfig.h" #include "Netrc.h" @@ -40,6 +43,7 @@ #include "NetrcAuthResolver.h" #include "prefs.h" #include "Request.h" +#include "Util.h" namespace aria2 { @@ -53,10 +57,25 @@ AuthConfigFactory::AuthConfigFactory(const Option* option): AuthConfigFactory::~AuthConfigFactory() {} AuthConfigHandle -AuthConfigFactory::createAuthConfig(const RequestHandle& request) const +AuthConfigFactory::createAuthConfig(const RequestHandle& request) { if(request->getProtocol() == Request::PROTO_HTTP || request->getProtocol() == Request::PROTO_HTTPS) { + + if(!request->getUsername().empty()) { + // TODO setting "/" as path. Should we use request->getDir() instead? + updateBasicCred(BasicCred(request->getUsername(), request->getPassword(), + request->getHost(), "/", true)); + return createAuthConfig(request->getUsername(), request->getPassword()); + } + std::deque<BasicCred>::const_iterator i = + findBasicCred(request->getHost(), request->getDir()); + if(i == _basicCreds.end()) { + return SharedHandle<AuthConfig>(); + } else { + return createAuthConfig((*i)._user, (*i)._password); + } + return createHttpAuthResolver()->resolveAuthConfig(request->getHost()); } else if(request->getProtocol() == Request::PROTO_FTP) { if(!request->getUsername().empty()) { @@ -65,7 +84,7 @@ AuthConfigFactory::createAuthConfig(const RequestHandle& request) const return createFtpAuthResolver()->resolveAuthConfig(request->getHost()); } } else { - return SharedHandle<AuthConfig>(new AuthConfig()); + return SharedHandle<AuthConfig>(); } } @@ -73,7 +92,7 @@ AuthConfigHandle AuthConfigFactory::createAuthConfig(const std::string& user, const std::string& password) const { SharedHandle<AuthConfig> ac; - if(user.length() > 0) { + if(!user.empty()) { ac.reset(new AuthConfig(user, password)); } return ac; @@ -117,4 +136,94 @@ void AuthConfigFactory::setNetrc(const NetrcHandle& netrc) _netrc = netrc; } +void AuthConfigFactory::updateBasicCred(const BasicCred& basicCred) +{ + std::deque<BasicCred>::iterator i = + std::lower_bound(_basicCreds.begin(), _basicCreds.end(), basicCred); + + if(i != _basicCreds.end() && (*i) == basicCred) { + (*i) = basicCred; + } else { + _basicCreds.insert(i, basicCred); + } +} + +bool AuthConfigFactory::activateBasicCred +(const std::string& host, const std::string& path) +{ + + std::deque<BasicCred>::iterator i = + findBasicCred(host, path); + if(i == _basicCreds.end()) { + SharedHandle<AuthConfig> authConfig = + createHttpAuthResolver()->resolveAuthConfig(host); + if(authConfig.isNull()) { + return false; + } else { + BasicCred bc("", "", host, path); + i = std::lower_bound(_basicCreds.begin(), _basicCreds.end(), bc); + // TODO setting "/" as path. Should we use path instead? + _basicCreds.insert + (i, BasicCred(authConfig->getUser(), authConfig->getPassword(), + host, "/", true)); + return true; + } + } else { + (*i).activate(); + return true; + } +} + +AuthConfigFactory::BasicCred::BasicCred +(const std::string& user, const std::string& password, + const std::string& host, const std::string& path, + bool activated): + _user(user), _password(password), + _host(host), _path(path), _activated(activated) +{ + if(!Util::endsWith(_path, "/")) { + _path += "/"; + } +} + +void AuthConfigFactory::BasicCred::activate() +{ + _activated = true; +} + +bool AuthConfigFactory::BasicCred::isActivated() const +{ + return _activated; +} + +bool AuthConfigFactory::BasicCred::operator==(const BasicCred& cred) const +{ + return _host == cred._host && _path == cred._path; +} + +bool AuthConfigFactory::BasicCred::operator<(const BasicCred& cred) const +{ + int c = _host.compare(cred._host); + if(c == 0) { + return _path > cred._path; + } else { + return c < 0; + } +} + +std::deque<AuthConfigFactory::BasicCred>::iterator +AuthConfigFactory::findBasicCred(const std::string& host, + const std::string& path) +{ + BasicCred bc("", "", host, path); + std::deque<BasicCred>::iterator i = + std::lower_bound(_basicCreds.begin(), _basicCreds.end(), bc); + for(; i != _basicCreds.end() && (*i)._host == host; ++i) { + if(Util::startsWith(bc._path, (*i)._path)) { + return i; + } + } + return _basicCreds.end(); +} + } // namespace aria2 |
