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