فهرست منبع

Save downloads added by aria2.addTorrent or aria2.addMetalink in
--save-session file.

Uploaded data are saved as file named hex string of sha1 hash of
uploaded data plus extension(".torrent" for torrent and ".metalink"
for metalink). For example,
0a3893293e27ac0490424c06de4d09242215f0a6.torrent. The directory where
these files are saved is specified by --dir option. These file paths
are written in --save-session file.

Tatsuhiro Tsujikawa 14 سال پیش
والد
کامیت
1698b2c7b1
2فایلهای تغییر یافته به همراه79 افزوده شده و 15 حذف شده
  1. 45 3
      src/XmlRpcMethodImpl.cc
  2. 34 12
      test/XmlRpcMethodTest.cc

+ 45 - 3
src/XmlRpcMethodImpl.cc

@@ -70,6 +70,8 @@
 # include "Peer.h"
 # include "Peer.h"
 # include "BtRuntime.h"
 # include "BtRuntime.h"
 # include "BtAnnounce.h"
 # include "BtAnnounce.h"
+# include "MessageDigest.h"
+# include "message_digest_helper.h"
 #endif // ENABLE_BITTORRENT
 #endif // ENABLE_BITTORRENT
 
 
 namespace aria2 {
 namespace aria2 {
@@ -244,6 +246,18 @@ SharedHandle<ValueBase> AddUriXmlRpcMethod::process
   }
   }
 }
 }
 
 
+namespace {
+
+std::string getHexSha1(const std::string& s)
+{
+  unsigned char hash[20];
+  message_digest::digest(hash, sizeof(hash), MessageDigest::sha1(),
+                         s.data(), s.size());
+  return util::toHex(hash, sizeof(hash));
+}
+
+} // namespace
+
 #ifdef ENABLE_BITTORRENT
 #ifdef ENABLE_BITTORRENT
 SharedHandle<ValueBase> AddTorrentXmlRpcMethod::process
 SharedHandle<ValueBase> AddTorrentXmlRpcMethod::process
 (const XmlRpcRequest& req, DownloadEngine* e)
 (const XmlRpcRequest& req, DownloadEngine* e)
@@ -263,9 +277,21 @@ SharedHandle<ValueBase> AddTorrentXmlRpcMethod::process
   bool posGiven = false;
   bool posGiven = false;
   getPosParam(req, 3, posGiven, pos);
   getPosParam(req, 3, posGiven, pos);
 
 
+  std::string filename = util::applyDir
+    (requestOption->get(PREF_DIR), getHexSha1(torrentParam->s())+".torrent");
   std::vector<SharedHandle<RequestGroup> > result;
   std::vector<SharedHandle<RequestGroup> > result;
-  createRequestGroupForBitTorrent(result, requestOption,
-                                  uris, torrentParam->s());
+  // Save uploaded data in order to save this download in
+  // --save-session file.
+  if(util::saveAs(filename, torrentParam->s(), true)) {
+    A2_LOG_INFO(fmt("Uploaded torrent data was saved as %s", filename.c_str()));
+    requestOption->put(PREF_TORRENT_FILE, filename);
+    createRequestGroupForBitTorrent(result, requestOption, uris);
+  } else {
+    A2_LOG_INFO(fmt("Uploaded torrent data was not saved."
+                    " Failed to write file %s", filename.c_str()));
+    createRequestGroupForBitTorrent(result, requestOption,
+                                    uris, torrentParam->s());
+  }
 
 
   if(!result.empty()) {
   if(!result.empty()) {
     return addRequestGroup(result.front(), e, posGiven, pos);
     return addRequestGroup(result.front(), e, posGiven, pos);
@@ -291,8 +317,24 @@ SharedHandle<ValueBase> AddMetalinkXmlRpcMethod::process
   bool posGiven = false;
   bool posGiven = false;
   getPosParam(req, 2, posGiven, pos);
   getPosParam(req, 2, posGiven, pos);
 
 
+  // TODO RFC5854 Metalink has the extension .meta4. We use .metalink
+  // for both v3 and RFC5854 Metalink. aria2 can detect which of which
+  // by reading content rather than extension.
+  std::string filename = util::applyDir
+    (requestOption->get(PREF_DIR), getHexSha1(metalinkParam->s())+".metalink");
   std::vector<SharedHandle<RequestGroup> > result;
   std::vector<SharedHandle<RequestGroup> > result;
-  createRequestGroupForMetalink(result, requestOption, metalinkParam->s());
+  // Save uploaded data in order to save this download in
+  // --save-session file.
+  if(util::saveAs(filename, metalinkParam->s(), true)) {
+    A2_LOG_INFO(fmt("Uploaded metalink data was saved as %s",
+                    filename.c_str()));
+    requestOption->put(PREF_METALINK_FILE, filename);
+    createRequestGroupForMetalink(result, requestOption);
+  } else {
+    A2_LOG_INFO(fmt("Uploaded metalink data was not saved."
+                    " Failed to write file %s", filename.c_str()));
+    createRequestGroupForMetalink(result, requestOption, metalinkParam->s());
+  }
   SharedHandle<List> gids = List::g();
   SharedHandle<List> gids = List::g();
   if(!result.empty()) {
   if(!result.empty()) {
     if(posGiven) {
     if(posGiven) {

+ 34 - 12
test/XmlRpcMethodTest.cc

@@ -85,8 +85,9 @@ public:
   {
   {
     RequestGroup::resetGIDCounter();
     RequestGroup::resetGIDCounter();
     option_.reset(new Option());
     option_.reset(new Option());
-    option_->put(PREF_DIR, "/tmp");
+    option_->put(PREF_DIR, A2_TEST_OUT_DIR"/aria2_XmlRpcMethodTest");
     option_->put(PREF_SEGMENT_SIZE, "1048576");
     option_->put(PREF_SEGMENT_SIZE, "1048576");
+    File(option_->get(PREF_DIR)).mkdirs();
     e_.reset
     e_.reset
       (new DownloadEngine(SharedHandle<EventPoll>(new SelectEventPoll())));
       (new DownloadEngine(SharedHandle<EventPoll>(new SelectEventPoll())));
     e_->setOption(option_.get());
     e_->setOption(option_.get());
@@ -255,6 +256,8 @@ void XmlRpcMethodTest::testAddUri_withBadPosition()
 #ifdef ENABLE_BITTORRENT
 #ifdef ENABLE_BITTORRENT
 void XmlRpcMethodTest::testAddTorrent()
 void XmlRpcMethodTest::testAddTorrent()
 {
 {
+  File(e_->getOption()->get(PREF_DIR)+
+       "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").remove();
   AddTorrentXmlRpcMethod m;
   AddTorrentXmlRpcMethod m;
   XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
   XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
   req.params->append(readFile(A2_TEST_DIR"/single.torrent"));
   req.params->append(readFile(A2_TEST_DIR"/single.torrent"));
@@ -263,13 +266,16 @@ void XmlRpcMethodTest::testAddTorrent()
   req.params->append(uris);
   req.params->append(uris);
   {
   {
     XmlRpcResponse res = m.execute(req, e_.get());
     XmlRpcResponse res = m.execute(req, e_.get());
+    CPPUNIT_ASSERT
+      (File(e_->getOption()->get(PREF_DIR)+
+            "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").exists());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
     CPPUNIT_ASSERT_EQUAL(0, res.code);
     CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(res.param)->s());
     CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(res.param)->s());
 
 
     SharedHandle<RequestGroup> group =
     SharedHandle<RequestGroup> group =
       e_->getRequestGroupMan()->findReservedGroup(1);
       e_->getRequestGroupMan()->findReservedGroup(1);
     CPPUNIT_ASSERT(group);
     CPPUNIT_ASSERT(group);
-    CPPUNIT_ASSERT_EQUAL(std::string("/tmp/aria2-0.8.2.tar.bz2"),
+    CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR)+"/aria2-0.8.2.tar.bz2",
                          group->getFirstFilePath());
                          group->getFirstFilePath());
     CPPUNIT_ASSERT_EQUAL((size_t)1,
     CPPUNIT_ASSERT_EQUAL((size_t)1,
                          group->getDownloadContext()->getFirstFileEntry()->
                          group->getDownloadContext()->getFirstFileEntry()->
@@ -279,15 +285,20 @@ void XmlRpcMethodTest::testAddTorrent()
                          getRemainingUris()[0]);
                          getRemainingUris()[0]);
   }
   }
   // with options
   // with options
+  std::string dir = A2_TEST_OUT_DIR"/aria2_XmlRpcMethodTest_testAddTorrent";
+  File(dir).mkdirs();
   SharedHandle<Dict> opt = Dict::g();
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_DIR, "/sink");
+  opt->put(PREF_DIR, dir);
+  File(dir+"/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").remove();
   req.params->append(opt);
   req.params->append(opt);
   {
   {
     XmlRpcResponse res = m.execute(req, e_.get());
     XmlRpcResponse res = m.execute(req, e_.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    CPPUNIT_ASSERT_EQUAL(std::string("/sink/aria2-0.8.2.tar.bz2"),
-                         e_->getRequestGroupMan()->findReservedGroup(2)->
-                         getFirstFilePath());
+    CPPUNIT_ASSERT_EQUAL
+      (dir+"/aria2-0.8.2.tar.bz2",
+       e_->getRequestGroupMan()->findReservedGroup(2)->getFirstFilePath());
+    CPPUNIT_ASSERT
+      (File(dir+"/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").exists());
   }
   }
 }
 }
 
 
@@ -335,6 +346,8 @@ void XmlRpcMethodTest::testAddTorrent_withPosition()
 #ifdef ENABLE_METALINK
 #ifdef ENABLE_METALINK
 void XmlRpcMethodTest::testAddMetalink()
 void XmlRpcMethodTest::testAddMetalink()
 {
 {
+  File(e_->getOption()->get(PREF_DIR)+
+       "/c908634fbc257fd56f0114912c2772aeeb4064f4.metalink").remove();
   AddMetalinkXmlRpcMethod m;
   AddMetalinkXmlRpcMethod m;
   XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), List::g());
   XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), List::g());
   req.params->append(readFile(A2_TEST_DIR"/2files.metalink"));
   req.params->append(readFile(A2_TEST_DIR"/2files.metalink"));
@@ -345,28 +358,36 @@ void XmlRpcMethodTest::testAddMetalink()
     CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
     CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
     CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(resParams->get(0))->s());
     CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(resParams->get(0))->s());
     CPPUNIT_ASSERT_EQUAL(std::string("2"), asString(resParams->get(1))->s());
     CPPUNIT_ASSERT_EQUAL(std::string("2"), asString(resParams->get(1))->s());
+    CPPUNIT_ASSERT
+      (File(e_->getOption()->get(PREF_DIR)+
+            "/c908634fbc257fd56f0114912c2772aeeb4064f4.metalink").exists());
 
 
     SharedHandle<RequestGroup> tar =
     SharedHandle<RequestGroup> tar =
       e_->getRequestGroupMan()->findReservedGroup(1);
       e_->getRequestGroupMan()->findReservedGroup(1);
     CPPUNIT_ASSERT(tar);
     CPPUNIT_ASSERT(tar);
-    CPPUNIT_ASSERT_EQUAL(std::string("/tmp/aria2-5.0.0.tar.bz2"),
+    CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR)+"/aria2-5.0.0.tar.bz2",
                          tar->getFirstFilePath());
                          tar->getFirstFilePath());
     SharedHandle<RequestGroup> deb =
     SharedHandle<RequestGroup> deb =
       e_->getRequestGroupMan()->findReservedGroup(2);
       e_->getRequestGroupMan()->findReservedGroup(2);
     CPPUNIT_ASSERT(deb);
     CPPUNIT_ASSERT(deb);
-    CPPUNIT_ASSERT_EQUAL(std::string("/tmp/aria2-5.0.0.deb"),
+    CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR)+"/aria2-5.0.0.deb",
                          deb->getFirstFilePath());
                          deb->getFirstFilePath());
   }
   }
   // with options
   // with options
+  std::string dir = A2_TEST_OUT_DIR"/aria2_XmlRpcMethodTest_testAddMetalink";
+  File(dir).mkdirs();
   SharedHandle<Dict> opt = Dict::g();
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_DIR, "/sink");
+  opt->put(PREF_DIR, dir);
+  File(dir+"/c908634fbc257fd56f0114912c2772aeeb4064f4.metalink").remove();
   req.params->append(opt);
   req.params->append(opt);
   {
   {
     XmlRpcResponse res = m.execute(req, e_.get());
     XmlRpcResponse res = m.execute(req, e_.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    CPPUNIT_ASSERT_EQUAL(std::string("/sink/aria2-5.0.0.tar.bz2"),
+    CPPUNIT_ASSERT_EQUAL(dir+"/aria2-5.0.0.tar.bz2",
                          e_->getRequestGroupMan()->findReservedGroup(3)->
                          e_->getRequestGroupMan()->findReservedGroup(3)->
                          getFirstFilePath());
                          getFirstFilePath());
+    CPPUNIT_ASSERT
+      (File(dir+"/c908634fbc257fd56f0114912c2772aeeb4064f4.metalink").exists());
   }
   }
 }
 }
 
 
@@ -405,7 +426,7 @@ void XmlRpcMethodTest::testAddMetalink_withPosition()
   XmlRpcResponse res2 = m2.execute(req2, e_.get());
   XmlRpcResponse res2 = m2.execute(req2, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res2.code);
   CPPUNIT_ASSERT_EQUAL(0, res2.code);
 
 
-  CPPUNIT_ASSERT_EQUAL(std::string("/tmp/aria2-5.0.0.tar.bz2"),
+  CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR)+"/aria2-5.0.0.tar.bz2",
                        e_->getRequestGroupMan()->getReservedGroups()[0]->
                        e_->getRequestGroupMan()->getReservedGroups()[0]->
                        getFirstFilePath());
                        getFirstFilePath());
 }
 }
@@ -779,7 +800,8 @@ void XmlRpcMethodTest::testGatherProgressCommon()
                         (asList(file->get("uris"))->get(0))
                         (asList(file->get("uris"))->get(0))
                         ->get("uri"))
                         ->get("uri"))
                        ->s());
                        ->s());
-  CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), asString(entry->get("dir"))->s());
+  CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR),
+                       asString(entry->get("dir"))->s());
 
 
   keys.push_back("gid");
   keys.push_back("gid");
   entry = Dict::g();
   entry = Dict::g();