Don't send basic auth header to service operated on differenct port.

When --http-auth-challenge=true, aria2 only sends basic auth header
when requested. Old implementation sends basic auth header to service
operated in different port in successive request. This change avoid
this bug.
pull/1/head
Tatsuhiro Tsujikawa 2011-07-27 23:28:31 +09:00
parent 02292feaba
commit 4ea28cb837
5 changed files with 56 additions and 33 deletions

View File

@ -66,11 +66,14 @@ AuthConfigFactory::createAuthConfig
if(!request->getUsername().empty()) {
updateBasicCred(BasicCred(request->getUsername(),
request->getPassword(),
request->getHost(), request->getDir(), true));
request->getHost(),
request->getPort(),
request->getDir(), true));
return createAuthConfig(request->getUsername(), request->getPassword());
}
std::deque<BasicCred>::const_iterator i =
findBasicCred(request->getHost(), request->getDir());
findBasicCred(request->getHost(), request->getPort(),
request->getDir());
if(i == basicCreds_.end()) {
return SharedHandle<AuthConfig>();
} else {
@ -180,10 +183,13 @@ void AuthConfigFactory::updateBasicCred(const BasicCred& basicCred)
}
bool AuthConfigFactory::activateBasicCred
(const std::string& host, const std::string& path, const Option* op)
(const std::string& host,
uint16_t port,
const std::string& path,
const Option* op)
{
std::deque<BasicCred>::iterator i = findBasicCred(host, path);
std::deque<BasicCred>::iterator i = findBasicCred(host, port, path);
if(i == basicCreds_.end()) {
SharedHandle<AuthConfig> authConfig =
createHttpAuthResolver(op)->resolveAuthConfig(host);
@ -191,7 +197,7 @@ bool AuthConfigFactory::activateBasicCred
return false;
} else {
BasicCred bc(authConfig->getUser(), authConfig->getPassword(),
host, path, true);
host, port, path, true);
i = std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
basicCreds_.insert(i, bc);
return true;
@ -204,10 +210,10 @@ bool AuthConfigFactory::activateBasicCred
AuthConfigFactory::BasicCred::BasicCred
(const std::string& user, const std::string& password,
const std::string& host, const std::string& path,
const std::string& host, uint16_t port, const std::string& path,
bool activated):
user_(user), password_(password),
host_(host), path_(path), activated_(activated)
host_(host), port_(port), path_(path), activated_(activated)
{
if(!util::endsWith(path_, "/")) {
path_ += "/";
@ -226,27 +232,27 @@ bool AuthConfigFactory::BasicCred::isActivated() const
bool AuthConfigFactory::BasicCred::operator==(const BasicCred& cred) const
{
return host_ == cred.host_ && path_ == cred.path_;
return host_ == cred.host_ && port_ == cred.port_ && 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;
}
return host_ < cred.host_ ||
(!(cred.host_ < host_) && (port_ < cred.port_ ||
(!(cred.port_ < port_) && path_ > cred.path_)));
}
std::deque<AuthConfigFactory::BasicCred>::iterator
AuthConfigFactory::findBasicCred(const std::string& host,
const std::string& path)
AuthConfigFactory::findBasicCred
(const std::string& host,
uint16_t port,
const std::string& path)
{
BasicCred bc("", "", host, path);
BasicCred bc("", "", host, port, path);
std::deque<BasicCred>::iterator i =
std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
for(; i != basicCreds_.end() && (*i).host_ == host; ++i) {
for(; i != basicCreds_.end() && (*i).host_ == host && (*i).port_ == port;
++i) {
if(util::startsWith(bc.path_, (*i).path_)) {
return i;
}

View File

@ -67,11 +67,12 @@ public:
std::string user_;
std::string password_;
std::string host_;
uint16_t port_;
std::string path_;
bool activated_;
BasicCred(const std::string& user, const std::string& password,
const std::string& host, const std::string& path,
const std::string& host, uint16_t port, const std::string& path,
bool activated = false);
void activate();
@ -106,12 +107,19 @@ public:
// using this AuthConfig object with given host and path "/" and
// returns true.
bool activateBasicCred
(const std::string& host, const std::string& path, const Option* op);
(const std::string& host,
uint16_t port,
const std::string& path,
const Option* op);
// Find a BasicCred using host and path and return the iterator
// pointing to it. If not found, then return basicCreds_.end().
// Find a BasicCred using host, port and path and return the
// iterator pointing to it. If not found, then return
// basicCreds_.end().
std::deque<AuthConfigFactory::BasicCred>::iterator
findBasicCred(const std::string& host, const std::string& path);
findBasicCred
(const std::string& host,
uint16_t port,
const std::string& path);
// If the same BasicCred is already added, then it is replaced with
// given basicCred. Otherwise, insert given basicCred to

View File

@ -199,7 +199,8 @@ bool HttpSkipResponseCommand::processResponse()
if(getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) &&
!httpResponse_->getHttpRequest()->authenticationUsed() &&
getDownloadEngine()->getAuthConfigFactory()->activateBasicCred
(getRequest()->getHost(), getRequest()->getDir(), getOption().get())) {
(getRequest()->getHost(), getRequest()->getPort(),
getRequest()->getDir(), getOption().get())) {
return prepareForRetry(0);
} else {
throw DL_ABORT_EX2(EX_AUTH_FAILED,

View File

@ -57,7 +57,7 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
// not activated
CPPUNIT_ASSERT(!factory.createAuthConfig(req, &option));
CPPUNIT_ASSERT(factory.activateBasicCred("localhost", "/", &option));
CPPUNIT_ASSERT(factory.activateBasicCred("localhost", 80, "/", &option));
CPPUNIT_ASSERT_EQUAL(std::string("localhostuser:localhostpass"),
factory.createAuthConfig(req, &option)->getAuthText());
@ -65,7 +65,7 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
// See default token in netrc is ignored.
req->setUri("http://mirror/");
CPPUNIT_ASSERT(!factory.activateBasicCred("mirror", "/", &option));
CPPUNIT_ASSERT(!factory.activateBasicCred("mirror", 80, "/", &option));
CPPUNIT_ASSERT(!factory.createAuthConfig(req, &option));
@ -75,7 +75,7 @@ void AuthConfigFactoryTest::testCreateAuthConfig_http()
CPPUNIT_ASSERT(!factory.createAuthConfig(req, &option));
CPPUNIT_ASSERT(factory.activateBasicCred("mirror", "/", &option));
CPPUNIT_ASSERT(factory.activateBasicCred("mirror", 80, "/", &option));
CPPUNIT_ASSERT_EQUAL(std::string("userDefinedUser:userDefinedPassword"),
factory.createAuthConfig(req, &option)->getAuthText());
@ -204,20 +204,25 @@ void AuthConfigFactoryTest::testUpdateBasicCred()
AuthConfigFactory factory;
factory.updateBasicCred
(AuthConfigFactory::BasicCred("myname", "mypass", "localhost", "/", true));
(AuthConfigFactory::BasicCred("myname", "mypass", "localhost", 80, "/", true));
factory.updateBasicCred
(AuthConfigFactory::BasicCred("price","j38jdc","localhost","/download", true));
(AuthConfigFactory::BasicCred("price", "j38jdc", "localhost", 80, "/download", true));
factory.updateBasicCred
(AuthConfigFactory::BasicCred("alice","ium8","localhost","/documents", true));
(AuthConfigFactory::BasicCred("soap", "planB", "localhost", 80, "/download/beta", true));
factory.updateBasicCred
(AuthConfigFactory::BasicCred("jack", "jackx","mirror", "/doc", true));
(AuthConfigFactory::BasicCred("alice", "ium8", "localhost", 80, "/documents", true));
factory.updateBasicCred
(AuthConfigFactory::BasicCred("jack", "jackx", "mirror", 80, "/doc", true));
SharedHandle<Request> req(new Request());
req->setUri("http://localhost/download/v2.6/Changelog");
CPPUNIT_ASSERT_EQUAL(std::string("price:j38jdc"),
factory.createAuthConfig(req, &option)->getAuthText());
req->setUri("http://localhost/download/beta/v2.7/Changelog");
CPPUNIT_ASSERT_EQUAL(std::string("soap:planB"),
factory.createAuthConfig(req, &option)->getAuthText());
req->setUri("http://localhost/documents/reference.html");
CPPUNIT_ASSERT_EQUAL(std::string("alice:ium8"),
factory.createAuthConfig(req, &option)->getAuthText());
@ -230,6 +235,9 @@ void AuthConfigFactoryTest::testUpdateBasicCred()
CPPUNIT_ASSERT_EQUAL(std::string("myname:mypass"),
factory.createAuthConfig(req, &option)->getAuthText());
req->setUri("http://localhost:8080/doc/readme.txt");
CPPUNIT_ASSERT(!factory.createAuthConfig(req, &option));
req->setUri("http://local/");
CPPUNIT_ASSERT(!factory.createAuthConfig(req, &option));

View File

@ -244,7 +244,7 @@ void HttpRequestTest::testCreateRequest()
option_->put(PREF_HTTP_PASSWD, "aria2passwd");
CPPUNIT_ASSERT(authConfigFactory_->activateBasicCred
("localhost", "/", option_.get()));
("localhost", 8080, "/", option_.get()));
expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"