mirror of https://github.com/aria2/aria2
				
				
				
			Support PREF_DIR change for Metalink files
Reworked previous commit adeead6f03, and
now support changing PREF_DIR for Metalink downloads.
			
			
				pull/235/merge
			
			
		
							parent
							
								
									adeead6f03
								
							
						
					
					
						commit
						4f3c526dcd
					
				| 
						 | 
				
			
			@ -572,6 +572,11 @@ void FileEntry::setOriginalName(std::string originalName)
 | 
			
		|||
  originalName_ = std::move(originalName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void FileEntry::setSuffixPath(std::string suffixPath)
 | 
			
		||||
{
 | 
			
		||||
  suffixPath_ = std::move(suffixPath);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool FileEntry::emptyRequestUri() const
 | 
			
		||||
{
 | 
			
		||||
  return uris_.empty() && inFlightRequests_.empty() && requestPool_.empty();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,9 @@ private:
 | 
			
		|||
  std::string path_;
 | 
			
		||||
  std::string contentType_;
 | 
			
		||||
  std::string originalName_;
 | 
			
		||||
  // path_ without parent directory component.  This is primarily used
 | 
			
		||||
  // to change directory (PREF_DIR option).
 | 
			
		||||
  std::string suffixPath_;
 | 
			
		||||
 | 
			
		||||
  Timer lastFasterReplace_;
 | 
			
		||||
  int maxConnectionPerServer_;
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +267,13 @@ public:
 | 
			
		|||
    return originalName_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void setSuffixPath(std::string suffixPath);
 | 
			
		||||
 | 
			
		||||
  const std::string& getSuffixPath() const
 | 
			
		||||
  {
 | 
			
		||||
    return suffixPath_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool removeUri(const std::string& uri);
 | 
			
		||||
 | 
			
		||||
  bool emptyRequestUri() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,11 +361,13 @@ bool FtpNegotiationCommand::onFileSizeDetermined(int64_t totalLength)
 | 
			
		|||
{
 | 
			
		||||
  getFileEntry()->setLength(totalLength);
 | 
			
		||||
  if(getFileEntry()->getPath().empty()) {
 | 
			
		||||
    auto suffixPath = util::createSafePath
 | 
			
		||||
      (util::percentDecode(std::begin(getRequest()->getFile()),
 | 
			
		||||
                           std::end(getRequest()->getFile())));
 | 
			
		||||
 | 
			
		||||
    getFileEntry()->setPath
 | 
			
		||||
      (util::createSafePath
 | 
			
		||||
       (getOption()->get(PREF_DIR),
 | 
			
		||||
        util::percentDecode(getRequest()->getFile().begin(),
 | 
			
		||||
                            getRequest()->getFile().end())));
 | 
			
		||||
      (util::applyDir(getOption()->get(PREF_DIR), suffixPath));
 | 
			
		||||
    getFileEntry()->setSuffixPath(suffixPath);
 | 
			
		||||
  }
 | 
			
		||||
  getRequestGroup()->preDownloadProcessing();
 | 
			
		||||
  if(totalLength == 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -249,8 +249,11 @@ bool HttpResponseCommand::executeInternal()
 | 
			
		|||
    int64_t totalLength = httpResponse->getEntityLength();
 | 
			
		||||
    fe->setLength(totalLength);
 | 
			
		||||
    if (fe->getPath().empty()) {
 | 
			
		||||
      fe->setPath(util::createSafePath(getOption()->get(PREF_DIR),
 | 
			
		||||
                                       httpResponse->determineFilename()));
 | 
			
		||||
      auto suffixPath =
 | 
			
		||||
        util::createSafePath(httpResponse->determineFilename());
 | 
			
		||||
 | 
			
		||||
      fe->setPath(util::applyDir(getOption()->get(PREF_DIR), suffixPath));
 | 
			
		||||
      fe->setSuffixPath(suffixPath);
 | 
			
		||||
    }
 | 
			
		||||
    fe->setContentType(httpResponse->getContentType());
 | 
			
		||||
    grp->preDownloadProcessing();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -265,6 +265,8 @@ Metalink2RequestGroup::createRequestGroup
 | 
			
		|||
                        entry->file->getPath()));
 | 
			
		||||
      dctx->getFirstFileEntry()->setUris(uris);
 | 
			
		||||
      dctx->getFirstFileEntry()->setMaxConnectionPerServer(maxConn);
 | 
			
		||||
      dctx->getFirstFileEntry()->setSuffixPath(entry->file->getPath());
 | 
			
		||||
 | 
			
		||||
      if(option->getAsBool(PREF_METALINK_ENABLE_UNIQUE_PROTOCOL)) {
 | 
			
		||||
        dctx->getFirstFileEntry()->setUniqueProtocol(true);
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -307,6 +309,7 @@ Metalink2RequestGroup::createRequestGroup
 | 
			
		|||
          fe->setUniqueProtocol(true);
 | 
			
		||||
        }
 | 
			
		||||
        fe->setOriginalName(entry->metaurls[0]->name);
 | 
			
		||||
        fe->setSuffixPath(entry->file->getPath());
 | 
			
		||||
        fileEntries.push_back(fe);
 | 
			
		||||
        if(offset >
 | 
			
		||||
           std::numeric_limits<int64_t>::max() - entry->file->getLength()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1473,22 +1473,35 @@ void changeOption
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if(option.defined(PREF_DIR) || option.defined(PREF_OUT)) {
 | 
			
		||||
    if(dctx->getFileEntries().size() == 1
 | 
			
		||||
#ifdef ENABLE_BITTORRENT
 | 
			
		||||
       && !dctx->hasAttribute(CTX_ATTR_BT)
 | 
			
		||||
#endif // ENABLE_BITTORRENT
 | 
			
		||||
       ) {
 | 
			
		||||
    if(!group->getMetadataInfo()) {
 | 
			
		||||
 | 
			
		||||
      assert(dctx->getFileEntries().size() == 1);
 | 
			
		||||
 | 
			
		||||
      auto& fileEntry = dctx->getFirstFileEntry();
 | 
			
		||||
 | 
			
		||||
      if(grOption->blank(PREF_OUT)) {
 | 
			
		||||
        // We need to reset length to 0, so that we pretend that file
 | 
			
		||||
        // name is unknown and it should be determined at next run.
 | 
			
		||||
        fileEntry->setLength(0);
 | 
			
		||||
      if(!grOption->blank(PREF_OUT)) {
 | 
			
		||||
        fileEntry->setPath
 | 
			
		||||
          (util::applyDir(grOption->get(PREF_DIR), grOption->get(PREF_OUT)));
 | 
			
		||||
        fileEntry->setSuffixPath(A2STR::NIL);
 | 
			
		||||
      } else if(fileEntry->getSuffixPath().empty()) {
 | 
			
		||||
        fileEntry->setPath(A2STR::NIL);
 | 
			
		||||
      } else {
 | 
			
		||||
        fileEntry->setPath
 | 
			
		||||
          (util::applyDir(grOption->get(PREF_DIR), grOption->get(PREF_OUT)));
 | 
			
		||||
          (util::applyDir(grOption->get(PREF_DIR),
 | 
			
		||||
                          fileEntry->getSuffixPath()));
 | 
			
		||||
      }
 | 
			
		||||
    } else if(group->getMetadataInfo()
 | 
			
		||||
#ifdef ENABLE_BITTORRENT
 | 
			
		||||
              && !dctx->hasAttribute(CTX_ATTR_BT)
 | 
			
		||||
#endif // ENABLE_BITTORRENT
 | 
			
		||||
              ) {
 | 
			
		||||
      // In case of Metalink
 | 
			
		||||
      for(auto& fileEntry : dctx->getFileEntries()) {
 | 
			
		||||
        // PREF_OUT is not applicable to Metalink.  We have always
 | 
			
		||||
        // suffixPath set.
 | 
			
		||||
        fileEntry->setPath
 | 
			
		||||
          (util::applyDir(grOption->get(PREF_DIR),
 | 
			
		||||
                          fileEntry->getSuffixPath()));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,11 +278,15 @@ void extractFileEntries
 | 
			
		|||
                             (util::percentEncode)));
 | 
			
		||||
      std::vector<std::string> uris;
 | 
			
		||||
      createUri(urlList.begin(), urlList.end(),std::back_inserter(uris),pePath);
 | 
			
		||||
      std::shared_ptr<FileEntry> fileEntry
 | 
			
		||||
        (new FileEntry(util::applyDir(option->get(PREF_DIR),
 | 
			
		||||
                                      util::escapePath(utf8Path)),
 | 
			
		||||
                       fileLengthData->i(), offset, uris));
 | 
			
		||||
 | 
			
		||||
      auto suffixPath = util::escapePath(utf8Path);
 | 
			
		||||
 | 
			
		||||
      auto fileEntry =
 | 
			
		||||
        std::make_shared<FileEntry>(util::applyDir(option->get(PREF_DIR),
 | 
			
		||||
                                                   suffixPath),
 | 
			
		||||
                                    fileLengthData->i(), offset, uris);
 | 
			
		||||
      fileEntry->setOriginalName(utf8Path);
 | 
			
		||||
      fileEntry->setSuffixPath(suffixPath);
 | 
			
		||||
      fileEntry->setMaxConnectionPerServer(maxConn);
 | 
			
		||||
      fileEntries.push_back(fileEntry);
 | 
			
		||||
      offset += fileEntry->getLength();
 | 
			
		||||
| 
						 | 
				
			
			@ -316,11 +320,15 @@ void extractFileEntries
 | 
			
		|||
        uris.push_back(elem);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    std::shared_ptr<FileEntry> fileEntry
 | 
			
		||||
      (new FileEntry(util::applyDir(option->get(PREF_DIR),
 | 
			
		||||
                                    util::escapePath(utf8Name)),
 | 
			
		||||
                     totalLength, 0, uris));
 | 
			
		||||
 | 
			
		||||
    auto suffixPath = util::escapePath(utf8Name);
 | 
			
		||||
 | 
			
		||||
    auto fileEntry =
 | 
			
		||||
      std::make_shared<FileEntry>(util::applyDir(option->get(PREF_DIR),
 | 
			
		||||
                                                 suffixPath),
 | 
			
		||||
                                  totalLength, 0, uris);
 | 
			
		||||
    fileEntry->setOriginalName(utf8Name);
 | 
			
		||||
    fileEntry->setSuffixPath(suffixPath);
 | 
			
		||||
    fileEntry->setMaxConnectionPerServer(maxConn);
 | 
			
		||||
    fileEntries.push_back(fileEntry);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1878,6 +1878,13 @@ std::string createSafePath
 | 
			
		|||
                        );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string createSafePath(const std::string& filename)
 | 
			
		||||
{
 | 
			
		||||
  return util::isUtf8(filename) ?
 | 
			
		||||
    util::fixTaintedBasename(filename) :
 | 
			
		||||
    util::escapePath(util::percentEncode(filename));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string encodeNonUtf8(const std::string& s)
 | 
			
		||||
{
 | 
			
		||||
  return util::isUtf8(s)?s:util::percentEncode(s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -791,6 +791,8 @@ void executeHookByOptName
 | 
			
		|||
 | 
			
		||||
std::string createSafePath(const std::string& dir, const std::string& filename);
 | 
			
		||||
 | 
			
		||||
std::string createSafePath(const std::string& filename);
 | 
			
		||||
 | 
			
		||||
std::string encodeNonUtf8(const std::string& s);
 | 
			
		||||
 | 
			
		||||
// Create string safely. If str is NULL, returns empty string.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,8 @@ void BittorrentHelperTest::testGetFileEntriesSingle() {
 | 
			
		|||
                       fileEntry1->getPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"),
 | 
			
		||||
                       fileEntry1->getOriginalName());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.8.2.tar.bz2"),
 | 
			
		||||
                       fileEntry1->getSuffixPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(10, fileEntry1->getMaxConnectionPerServer());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -355,6 +357,8 @@ void BittorrentHelperTest::testGetFileEntries_multiFileUrlList() {
 | 
			
		|||
  const std::shared_ptr<FileEntry>& fileEntry1 = *itr;
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("./aria2-test@/aria2@/src@/aria2c@"),
 | 
			
		||||
                       fileEntry1->getPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("aria2-test@/aria2@/src@/aria2c@"),
 | 
			
		||||
                       fileEntry1->getSuffixPath());
 | 
			
		||||
  const std::deque<std::string>& uris1 = fileEntry1->getRemainingUris();
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL((size_t)2, uris1.size());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/dist/aria2-test%40/aria2%40/src%40/aria2c%40"),
 | 
			
		||||
| 
						 | 
				
			
			@ -434,6 +438,9 @@ void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
 | 
			
		|||
  CPPUNIT_ASSERT_EQUAL
 | 
			
		||||
    (std::string("./%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
 | 
			
		||||
     fe->getPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL
 | 
			
		||||
    (std::string("%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
 | 
			
		||||
     fe->getSuffixPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL
 | 
			
		||||
    (std::string("./%1B%24B%25O%25m%21%3C%1B%28B"), dctx->getBasePath());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -452,6 +459,7 @@ void BittorrentHelperTest::testLoadFromMemory_singleFileNonUtf8Path()
 | 
			
		|||
 | 
			
		||||
  const std::shared_ptr<FileEntry>& fe = dctx->getFirstFileEntry();
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("./%90%A2%8AE"), fe->getPath());
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL(std::string("%90%A2%8AE"), fe->getSuffixPath());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BittorrentHelperTest::testLoadFromMemory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,6 +163,8 @@ void Metalink2RequestGroupTest::testGenerate_groupByMetaurl()
 | 
			
		|||
    CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
 | 
			
		||||
    CPPUNIT_ASSERT_EQUAL(std::string("./file1"), fileEntries[0]->getPath());
 | 
			
		||||
    CPPUNIT_ASSERT_EQUAL(std::string("file1"), fileEntries[0]->getOriginalName());
 | 
			
		||||
    CPPUNIT_ASSERT_EQUAL(std::string("file1"),
 | 
			
		||||
                         fileEntries[0]->getSuffixPath());
 | 
			
		||||
    CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries[0]->getRemainingUris().size());
 | 
			
		||||
    CPPUNIT_ASSERT_EQUAL(std::string("http://file1p1"),
 | 
			
		||||
                         fileEntries[0]->getRemainingUris()[0]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue