mirror of https://github.com/aria2/aria2
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
parent
7c317de4e7
commit
67e91c3431
|
@ -33,6 +33,7 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "Checksum.h"
|
#include "Checksum.h"
|
||||||
|
#include "MessageDigest.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -62,4 +63,24 @@ void Checksum::setAlgo(const std::string& algo)
|
||||||
algo_ = 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
|
} // namespace aria2
|
||||||
|
|
|
@ -64,6 +64,15 @@ public:
|
||||||
{
|
{
|
||||||
return algo_;
|
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
|
} // namespace aria2
|
||||||
|
|
|
@ -306,12 +306,11 @@ bool parseMetalinkHttpLink(MetalinkHttpEntry& result, const std::string& s)
|
||||||
if(last == s.end()) {
|
if(last == s.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string uri(first+1, last);
|
std::string uri = util::stripIter(first+1, last);
|
||||||
uri::UriStruct us;
|
if(uri.empty()) {
|
||||||
if(uri::parse(us, uri)) {
|
|
||||||
result.uri = uri;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
result.uri = uri;
|
||||||
}
|
}
|
||||||
last = std::find(last, s.end(), ';');
|
last = std::find(last, s.end(), ';');
|
||||||
if(last != s.end()) {
|
if(last != s.end()) {
|
||||||
|
@ -388,9 +387,9 @@ void HttpResponse::getMetalinKHttpEntries
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
// Digest header field is defined by
|
// Digest header field is defined by
|
||||||
// http://tools.ietf.org/html/rfc3230.
|
// 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::pair<std::multimap<std::string, std::string>::const_iterator,
|
||||||
std::multimap<std::string, std::string>::const_iterator> p =
|
std::multimap<std::string, std::string>::const_iterator> p =
|
||||||
httpHeader_->getIterator(HttpHeader::DIGEST);
|
httpHeader_->getIterator(HttpHeader::DIGEST);
|
||||||
|
@ -413,15 +412,29 @@ SharedHandle<Checksum> HttpResponse::getDigest() const
|
||||||
if(!MessageDigest::isValidHash(hashType, hexDigest)) {
|
if(!MessageDigest::isValidHash(hashType, hexDigest)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!res) {
|
result.push_back(Checksum(hashType, hexDigest));
|
||||||
res.reset(new Checksum(hashType, hexDigest));
|
|
||||||
} else if(MessageDigest::isStronger(hashType, res->getAlgo())) {
|
|
||||||
res->setAlgo(hashType);
|
|
||||||
res->setMessageDigest(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
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
|
||||||
|
|
|
@ -136,11 +136,11 @@ public:
|
||||||
(std::vector<MetalinkHttpEntry>& result,
|
(std::vector<MetalinkHttpEntry>& result,
|
||||||
const SharedHandle<Option>& option) const;
|
const SharedHandle<Option>& option) const;
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
#ifdef ENABLE_MESSAGE_DIGEST
|
||||||
// Returns digest specified in Digest header field. If multiple
|
// Returns all digests specified in Digest header field. Sort
|
||||||
// digest algorithm is available, use strongest one defined in
|
// strong algorithm first. Strength is defined in MessageDigest. If
|
||||||
// MessageDigest. If several same digest algorithms are available,
|
// several same digest algorithms are available, but they have
|
||||||
// but they have different value, they are all ignored.
|
// different value, they are all ignored.
|
||||||
SharedHandle<Checksum> getDigest() const;
|
void getDigest(std::vector<Checksum>& result) const;
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -613,9 +613,8 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
|
||||||
httpHeader->put("Link", "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
|
httpHeader->put("Link", "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
|
||||||
httpHeader->put("Link", "<http://uri4/>;rel=duplicate;=pri=1;pref");
|
httpHeader->put("Link", "<http://uri4/>;rel=duplicate;=pri=1;pref");
|
||||||
httpHeader->put("Link", "<http://describedby>; rel=describedby");
|
httpHeader->put("Link", "<http://describedby>; rel=describedby");
|
||||||
httpHeader->put("Link", "<baduri>; rel=duplicate");
|
|
||||||
httpHeader->put("Link", "<http://norel/>");
|
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;
|
std::vector<MetalinkHttpEntry> result;
|
||||||
httpResponse.getMetalinKHttpEntries(result, option);
|
httpResponse.getMetalinKHttpEntries(result, option);
|
||||||
CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
|
CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
|
||||||
|
@ -645,7 +644,7 @@ void HttpResponseTest::testGetMetalinKHttpEntries()
|
||||||
CPPUNIT_ASSERT(e.geo.empty());
|
CPPUNIT_ASSERT(e.geo.empty());
|
||||||
|
|
||||||
e = result[4];
|
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_EQUAL(999999, e.pri);
|
||||||
CPPUNIT_ASSERT(!e.pref);
|
CPPUNIT_ASSERT(!e.pref);
|
||||||
CPPUNIT_ASSERT(e.geo.empty());
|
CPPUNIT_ASSERT(e.geo.empty());
|
||||||
|
@ -658,15 +657,28 @@ void HttpResponseTest::testGetDigest()
|
||||||
SharedHandle<HttpHeader> httpHeader(new HttpHeader());
|
SharedHandle<HttpHeader> httpHeader(new HttpHeader());
|
||||||
httpResponse.setHttpHeader(httpHeader);
|
httpResponse.setHttpHeader(httpHeader);
|
||||||
SharedHandle<Option> option(new Option());
|
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", "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
|
||||||
httpHeader->put("Digest", "NOT_SUPPORTED");
|
httpHeader->put("Digest", "NOT_SUPPORTED");
|
||||||
|
httpHeader->put("Digest", "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
|
||||||
|
httpHeader->put("Digest", "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
|
||||||
httpHeader->put("Digest",
|
httpHeader->put("Digest",
|
||||||
"SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
|
"SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
|
||||||
"MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
|
"MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
|
||||||
SharedHandle<Checksum> c = httpResponse.getDigest();
|
std::vector<Checksum> result;
|
||||||
CPPUNIT_ASSERT(c);
|
httpResponse.getDigest(result);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), c->getAlgo());
|
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
|
#endif // ENABLE_MESSAGE_DIGEST
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue