Kaynağa Gözat

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.
Tatsuhiro Tsujikawa 14 yıl önce
ebeveyn
işleme
67e91c3431
5 değiştirilmiş dosya ile 80 ekleme ve 25 silme
  1. 21 0
      src/Checksum.cc
  2. 9 0
      src/Checksum.h
  3. 26 13
      src/HttpResponse.cc
  4. 5 5
      src/HttpResponse.h
  5. 19 7
      test/HttpResponseTest.cc

+ 21 - 0
src/Checksum.cc

@@ -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

+ 9 - 0
src/Checksum.h

@@ -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

+ 26 - 13
src/HttpResponse.cc

@@ -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));
+    }
+  }
+  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;
   }
-  return res;
+  swap(temp, result);
 }
 #endif // ENABLE_MESSAGE_DIGEST
 

+ 5 - 5
src/HttpResponse.h

@@ -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
 };
 

+ 19 - 7
test/HttpResponseTest.cc

@@ -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