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

View File

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

View File

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

View File

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

View File

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