HttpResponse::getDigest() now returns all Digest.

In addition, HttpResponse::getMetalinkHttpEntries() does not check
validity of URI. It is checked when we add it to FileEntry.
pull/1/head
Tatsuhiro Tsujikawa 2011-07-27 19:32:35 +09:00
parent 7c317de4e7
commit 67e91c3431
5 changed files with 81 additions and 26 deletions

View File

@ -33,6 +33,7 @@
*/
/* copyright --> */
#include "Checksum.h"
#include "MessageDigest.h"
namespace aria2 {
@ -62,4 +63,24 @@ void Checksum::setAlgo(const std::string& algo)
algo_ = algo;
}
void Checksum::swap(Checksum& other)
{
using std::swap;
if(this != &other) {
swap(algo_, other.algo_);
swap(messageDigest_, other.messageDigest_);
}
}
void swap(Checksum& a, Checksum& b)
{
a.swap(b);
}
bool HashTypeStronger::operator()
(const Checksum& lhs, const Checksum& rhs) const
{
return MessageDigest::isStronger(lhs.getAlgo(), rhs.getAlgo());
}
} // namespace aria2

View File

@ -64,6 +64,15 @@ public:
{
return algo_;
}
void swap(Checksum& other);
};
void swap(Checksum& a, Checksum& b);
class HashTypeStronger {
public:
bool operator()(const Checksum& lhs, const Checksum& rhs) const;
};
} // namespace aria2

View File

@ -306,12 +306,11 @@ bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s)
if(last == s.end()) {
return false;
}
std::string uri(first+1, last);
uri::UriStruct us;
if(uri::parse(us, uri)) {
result.uri = uri;
} else {
std::string uri = util::stripIter(first+1, last);
if(uri.empty()) {
return false;
} else {
result.uri = uri;
}
last = std::find(last, s.end(), ';');
if(last != s.end()) {
@ -388,9 +387,9 @@ void HttpResponse::getMetalinKHttpEntries
#ifdef ENABLE_MESSAGE_DIGEST
// Digest header field is defined by
// http://tools.ietf.org/html/rfc3230.
SharedHandle<Checksum> HttpResponse::getDigest() const
void HttpResponse::getDigest(std::vector<Checksum>& result) const
{
SharedHandle<Checksum> res;
using std::swap;
std::pair<std::multimap<std::string, std::string>::const_iterator,
std::multimap<std::string, std::string>::const_iterator> p =
httpHeader_->getIterator(HttpHeader::DIGEST);
@ -413,15 +412,29 @@ SharedHandle<Checksum> HttpResponse::getDigest() const
if(!MessageDigest::isValidHash(hashType, hexDigest)) {
continue;
}
if(!res) {
res.reset(new Checksum(hashType, hexDigest));
} else if(MessageDigest::isStronger(hashType, res->getAlgo())) {
res->setAlgo(hashType);
res->setMessageDigest(hexDigest);
}
result.push_back(Checksum(hashType, hexDigest));
}
}
return res;
std::sort(result.begin(), result.end(), HashTypeStronger());
std::vector<Checksum> temp;
for(std::vector<Checksum>::iterator i = result.begin(),
eoi = result.end(); i != eoi;) {
bool ok = true;
std::vector<Checksum>::iterator j = i+1;
for(; j != eoi; ++j) {
if((*i).getAlgo() != (*j).getAlgo()) {
break;
}
if((*i).getMessageDigest() != (*j).getMessageDigest()) {
ok = false;
}
}
if(ok) {
temp.push_back(*i);
}
i = j;
}
swap(temp, result);
}
#endif // ENABLE_MESSAGE_DIGEST

View File

@ -136,11 +136,11 @@ public:
(std::vector<MetalinkHttpEntry>& result,
const SharedHandle<Option>& option) const;
#ifdef ENABLE_MESSAGE_DIGEST
// Returns digest specified in Digest header field. If multiple
// digest algorithm is available, use strongest one defined in
// MessageDigest. If several same digest algorithms are available,
// but they have different value, they are all ignored.
SharedHandle<Checksum> getDigest() const;
// Returns all digests specified in Digest header field. Sort
// strong algorithm first. Strength is defined in MessageDigest. If
// several same digest algorithms are available, but they have
// different value, they are all ignored.
void getDigest(std::vector<Checksum>& result) const;
#endif // ENABLE_MESSAGE_DIGEST
};

View File

@ -613,9 +613,8 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
httpHeader->put("Link", "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
httpHeader->put("Link", "<http://uri4/>;rel=duplicate;=pri=1;pref");
httpHeader->put("Link", "<http://describedby>; rel=describedby");
httpHeader->put("Link", "<baduri>; rel=duplicate");
httpHeader->put("Link", "<http://norel/>");
httpHeader->put("Link", "<http://badpri/>; rel=duplicate; pri=-1;");
httpHeader->put("Link", "<baduri>; rel=duplicate; pri=-1;");
std::vector<MetalinkHttpEntry> result;
httpResponse.getMetalinKHttpEntries(result, option);
CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
@ -645,7 +644,7 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
CPPUNIT_ASSERT(e.geo.empty());
e = result[4];
CPPUNIT_ASSERT_EQUAL(std::string("http://badpri/"), e.uri);
CPPUNIT_ASSERT_EQUAL(std::string("baduri"), e.uri);
CPPUNIT_ASSERT_EQUAL(999999, e.pri);
CPPUNIT_ASSERT(!e.pref);
CPPUNIT_ASSERT(e.geo.empty());
@ -658,15 +657,28 @@ void HttpResponseTest::testGetDigest()
SharedHandle<HttpHeader> httpHeader(new HttpHeader());
httpResponse.setHttpHeader(httpHeader);
SharedHandle<Option> option(new Option());
// Python binascii.hexlify(base64.b64decode(B64ED_HASH)) is handy to
// retrieve ascii hex hash string.
httpHeader->put("Digest", "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
httpHeader->put("Digest", "NOT_SUPPORTED");
httpHeader->put("Digest", "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
httpHeader->put("Digest", "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
httpHeader->put("Digest",
"SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
"MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
SharedHandle<Checksum> c = httpResponse.getDigest();
CPPUNIT_ASSERT(c);
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), c->getAlgo());
std::vector<Checksum> result;
httpResponse.getDigest(result);
CPPUNIT_ASSERT_EQUAL((size_t)3, result.size());
Checksum c = result[0];
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), c.getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("f83f271ae773dc6fe4a6454a41e0eb237c43e7bbf451e426cc60993a4d379ec5"),
c.getMessageDigest());
c = result[1];
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c.getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
c.getMessageDigest());
}
#endif // ENABLE_MESSAGE_DIGEST