mirror of
https://github.com/aria2/aria2.git
synced 2025-04-04 21:17:41 +03:00
Merge 588ef22bc0
into b519ce04e3
This commit is contained in:
commit
ccf393e89d
15 changed files with 125 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -44,3 +44,4 @@ compile
|
|||
main.log
|
||||
main.trs
|
||||
test-suite.log
|
||||
.vscode/
|
||||
|
|
|
@ -3,7 +3,7 @@ aria2c(1)
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
**aria2c** [<OPTIONS>] [<URI>|<MAGNET>|<TORRENT_FILE>|<METALINK_FILE>] ...
|
||||
**aria2c** [<OPTIONS>] [<URI>|<MAGNET>|<TORRENT_FILE>|<METALINK_FILE>|<ARIA2_CONTROL_FILE>] ...
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -1736,7 +1736,7 @@ Some options takes ``K`` and ``M`` to conveniently represent 1024 and
|
|||
case-insensitive way. In other words, ``k`` and ``m`` can be used as
|
||||
well as ``K`` and ``M`` respectively.
|
||||
|
||||
URI, MAGNET, TORRENT_FILE, METALINK_FILE
|
||||
URI, MAGNET, TORRENT_FILE, METALINK_FILE, ARIA2_CONTROL_FILE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can specify multiple URIs in command-line. Unless you specify
|
||||
|
|
|
@ -1482,7 +1482,7 @@ Algumas opções usam ``K`` e ``M`` para convenientemente representar
|
|||
transparente (maiúsculas e minúsculas), portanto podem ser usados
|
||||
`k`` ou ``K`` e ``m`` ou ``M``.
|
||||
|
||||
URI, MAGNET, TORRENT_FILE, METALINK_FILE
|
||||
URI, MAGNET, TORRENT_FILE, METALINK_FILE, ARIA2_CONTROL_FILE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Podemos especificar múltiplas URIs em uma linha de comando. A menos que seja
|
||||
|
|
|
@ -1836,7 +1836,7 @@ URI, и это не то, что обычно вы ожидаете.
|
|||
регистра. Другими словами, ``k`` и ``m`` могут быть использованы также как
|
||||
``K`` и ``M`` соответственно.
|
||||
|
||||
URI, MAGNET-ССЫЛКА, TORRENT-ФАЙЛ, METALINK-ФАЙЛ
|
||||
URI, MAGNET-ССЫЛКА, TORRENT-ФАЙЛ, METALINK-ФАЙЛ, ARIA2_CONTROL_FILE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Вы можете перечислить несколько URI в командной строке. Пока вы не указали
|
||||
|
|
|
@ -55,9 +55,7 @@
|
|||
#include "fmt.h"
|
||||
#include "array_fun.h"
|
||||
#include "DownloadContext.h"
|
||||
#include "BufferedFile.h"
|
||||
#include "SHA1IOFile.h"
|
||||
#include "BtConstants.h"
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
# include "PeerStorage.h"
|
||||
# include "BtRuntime.h"
|
||||
|
@ -223,23 +221,17 @@ void DefaultBtProgressInfoFile::save()
|
|||
}
|
||||
}
|
||||
|
||||
#define READ_CHECK(fp, ptr, count) \
|
||||
#define READ_CHECK_STATIC(fp, ptr, count, filename) \
|
||||
if (fp.read((ptr), (count)) != (count)) { \
|
||||
throw DL_ABORT_EX(fmt(EX_SEGMENT_FILE_READ, filename_.c_str())); \
|
||||
throw DL_ABORT_EX(fmt(EX_SEGMENT_FILE_READ, filename.c_str())); \
|
||||
}
|
||||
|
||||
// It is assumed that integers are saved as:
|
||||
// 1) host byte order if version == 0000
|
||||
// 2) network byte order if version == 0001
|
||||
void DefaultBtProgressInfoFile::load()
|
||||
#define READ_CHECK(fp, ptr, count) READ_CHECK_STATIC(fp, ptr, count, filename_)
|
||||
|
||||
uint DefaultBtProgressInfoFile::getControlFileVersion(BufferedFile& fp, const std::string& filename)
|
||||
{
|
||||
A2_LOG_INFO(fmt(MSG_LOADING_SEGMENT_FILE, filename_.c_str()));
|
||||
BufferedFile fp(filename_.c_str(), BufferedFile::READ);
|
||||
if (!fp) {
|
||||
throw DL_ABORT_EX(fmt(EX_SEGMENT_FILE_READ, filename_.c_str()));
|
||||
}
|
||||
unsigned char versionBuf[2];
|
||||
READ_CHECK(fp, versionBuf, sizeof(versionBuf));
|
||||
READ_CHECK_STATIC(fp, versionBuf, sizeof(versionBuf), filename);
|
||||
std::string versionHex = util::toHex(versionBuf, sizeof(versionBuf));
|
||||
int version;
|
||||
if ("0000" == versionHex) {
|
||||
|
@ -252,6 +244,53 @@ void DefaultBtProgressInfoFile::load()
|
|||
throw DL_ABORT_EX(
|
||||
fmt("Unsupported ctrl file version: %s", versionHex.c_str()));
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
std::array<unsigned char, INFO_HASH_LENGTH> DefaultBtProgressInfoFile::getInfoHash(const std::string& control_file)
|
||||
{
|
||||
A2_LOG_INFO(fmt(MSG_LOADING_SEGMENT_FILE, control_file.c_str()));
|
||||
BufferedFile fp(control_file.c_str(), BufferedFile::READ);
|
||||
if (!fp) {
|
||||
throw DL_ABORT_EX(fmt(EX_SEGMENT_FILE_READ, control_file.c_str()));
|
||||
}
|
||||
|
||||
const auto version = getControlFileVersion(fp, control_file);
|
||||
|
||||
unsigned char extension[4];
|
||||
READ_CHECK_STATIC(fp, extension, sizeof(extension), control_file);
|
||||
|
||||
uint32_t infoHashLength;
|
||||
READ_CHECK_STATIC(fp, &infoHashLength, sizeof(infoHashLength), control_file);
|
||||
if (version >= 1) {
|
||||
infoHashLength = ntohl(infoHashLength);
|
||||
}
|
||||
if (infoHashLength != INFO_HASH_LENGTH) {
|
||||
throw DL_ABORT_EX(fmt("Invalid info hash length: %d", infoHashLength));
|
||||
}
|
||||
|
||||
std::array<unsigned char, INFO_HASH_LENGTH> savedInfoHash;
|
||||
if (infoHashLength > 0) {
|
||||
READ_CHECK_STATIC(fp, savedInfoHash.data(), infoHashLength, control_file);
|
||||
}
|
||||
|
||||
return savedInfoHash;
|
||||
}
|
||||
|
||||
// It is assumed that integers are saved as:
|
||||
// 1) host byte order if version == 0000
|
||||
// 2) network byte order if version == 0001
|
||||
void DefaultBtProgressInfoFile::load()
|
||||
{
|
||||
A2_LOG_INFO(fmt(MSG_LOADING_SEGMENT_FILE, filename_.c_str()));
|
||||
BufferedFile fp(filename_.c_str(), BufferedFile::READ);
|
||||
if (!fp) {
|
||||
throw DL_ABORT_EX(fmt(EX_SEGMENT_FILE_READ, filename_.c_str()));
|
||||
}
|
||||
|
||||
const auto version = getControlFileVersion(fp, filename_);
|
||||
|
||||
unsigned char extension[4];
|
||||
READ_CHECK(fp, extension, sizeof(extension));
|
||||
bool infoHashCheckEnabled = false;
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define D_DEFAULT_BT_PROGRESS_INFO_FILE_H
|
||||
|
||||
#include "BtProgressInfoFile.h"
|
||||
#include "BufferedFile.h"
|
||||
#include "BtConstants.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -93,6 +95,11 @@ public:
|
|||
void setBtRuntime(const std::shared_ptr<BtRuntime>& btRuntime);
|
||||
#endif // ENABLE_BITTORRENT
|
||||
|
||||
// Assume getting pointer to the start of the file
|
||||
static uint getControlFileVersion(BufferedFile& fp, const std::string& filename);
|
||||
|
||||
static std::array<unsigned char, INFO_HASH_LENGTH> getInfoHash(const std::string& control_file);
|
||||
|
||||
static const std::string& getSuffix()
|
||||
{
|
||||
static std::string suffix = ".aria2";
|
||||
|
|
|
@ -372,6 +372,11 @@ Time File::getModifiedTime()
|
|||
return Time(fstat.st_mtime);
|
||||
}
|
||||
|
||||
std::string File::getExtension() const
|
||||
{
|
||||
return name_.substr(name_.find_last_of("."));
|
||||
}
|
||||
|
||||
std::string File::getCurrentDir()
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
|
|
|
@ -120,6 +120,8 @@ public:
|
|||
|
||||
Time getModifiedTime();
|
||||
|
||||
std::string getExtension() const;
|
||||
|
||||
// Returns the current working directory. If the current working
|
||||
// directory cannot be retrieved or its length is larger than 2048,
|
||||
// returns ".".
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
#ifdef ENABLE_BITTORRENT
|
||||
# include "bittorrent_helper.h"
|
||||
#endif // ENABLE_BITTORRENT
|
||||
#ifdef ENABLE_CONTROL_FILE
|
||||
# include "DefaultBtProgressInfoFile.h"
|
||||
#endif // ENABLE_CONTROL_FILE
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -90,6 +93,22 @@ bool ProtocolDetector::guessTorrentMagnet(const std::string& uri) const
|
|||
#endif // !ENABLE_BITTORRENT
|
||||
}
|
||||
|
||||
bool ProtocolDetector::guessAria2ControlFile(const std::string& uri) const
|
||||
{
|
||||
#ifdef ENABLE_CONTROL_FILE
|
||||
File control_file(uri);
|
||||
|
||||
if(!control_file.isFile())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return control_file.getExtension() == DefaultBtProgressInfoFile::getSuffix();
|
||||
#else // !ENABLE_CONTROL_FILE
|
||||
return false;
|
||||
#endif // !ENABLE_CONTROL_FILE
|
||||
}
|
||||
|
||||
bool ProtocolDetector::guessMetalinkFile(const std::string& uri) const
|
||||
{
|
||||
BufferedFile fp(uri.c_str(), BufferedFile::READ);
|
||||
|
|
|
@ -60,6 +60,10 @@ public:
|
|||
// Returns true if ProtocolDetector thinks uri is a path of Metalink XML
|
||||
// file, otherwise return false.
|
||||
bool guessMetalinkFile(const std::string& uri) const;
|
||||
|
||||
// Returns true if ProtocolDetector thinks uri is a path to aria2 control
|
||||
// file, otherwise return false
|
||||
bool guessAria2ControlFile(const std::string& uri) const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -68,6 +68,10 @@
|
|||
# include "BtConstants.h"
|
||||
# include "ValueBaseBencodeParser.h"
|
||||
#endif // ENABLE_BITTORRENT
|
||||
#ifdef ENABLE_CONTROL_FILE
|
||||
# include "TorrentAttribute.h"
|
||||
# include "DefaultBtProgressInfoFile.h"
|
||||
#endif // ENABLE_CONTROL_FILE
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -445,7 +449,20 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ENABLE_METALINK
|
||||
#ifdef ENABLE_CONTROL_FILE
|
||||
else if (!ignoreLocalPath_ && detector_.guessAria2ControlFile(uri))
|
||||
{
|
||||
// Extract hash and construct a magnet to feed into createBtMagentRequestGroup
|
||||
const auto infoHash = DefaultBtProgressInfoFile::getInfoHash(uri);
|
||||
|
||||
auto torrent_attribute = std::make_unique<TorrentAttribute>();
|
||||
torrent_attribute->infoHash = std::string(std::begin(infoHash), std::end(infoHash));
|
||||
const auto magent = aria2::bittorrent::torrent2Magnet(torrent_attribute.get());
|
||||
|
||||
requestGroups_.push_back(createBtMagnetRequestGroup(magent, option_));
|
||||
}
|
||||
else {
|
||||
if (throwOnError_) {
|
||||
throw DL_ABORT_EX(fmt(MSG_UNRECOGNIZED_URI, uri.c_str()));
|
||||
|
@ -455,6 +472,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_CONTROL_FILE
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ void showUsage(const std::string& keyword,
|
|||
const std::shared_ptr<OptionParser>& oparser, const Console& out)
|
||||
{
|
||||
out->printf(_("Usage: aria2c [OPTIONS] [URI | MAGNET | TORRENT_FILE |"
|
||||
" METALINK_FILE]..."));
|
||||
" METALINK_FILE | ARIA2_CONTROL_FILE]..."));
|
||||
out->printf("\n");
|
||||
if (keyword.empty()) {
|
||||
// Very short version of usage.
|
||||
|
@ -139,7 +139,7 @@ void showUsage(const std::string& keyword,
|
|||
}
|
||||
}
|
||||
if (keyword == strHelpTag(TAG_BASIC)) {
|
||||
out->printf("URI, MAGNET, TORRENT_FILE, METALINK_FILE:\n");
|
||||
out->printf("URI, MAGNET, TORRENT_FILE, METALINK_FILE, ARIA2_CONTROL_FILE:\n");
|
||||
out->printf(
|
||||
_(" You can specify multiple HTTP(S)/FTP URIs. Unless you specify -Z "
|
||||
"option, all\n"
|
||||
|
|
|
@ -14,6 +14,7 @@ class ProtocolDetectorTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testGuessTorrentFile);
|
||||
CPPUNIT_TEST(testGuessTorrentMagnet);
|
||||
CPPUNIT_TEST(testGuessMetalinkFile);
|
||||
CPPUNIT_TEST(testGuessAria2ControlFile);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
|
@ -25,6 +26,7 @@ public:
|
|||
void testGuessTorrentFile();
|
||||
void testGuessTorrentMagnet();
|
||||
void testGuessMetalinkFile();
|
||||
void testGuessAria2ControlFile();
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(ProtocolDetectorTest);
|
||||
|
@ -66,4 +68,12 @@ void ProtocolDetectorTest::testGuessMetalinkFile()
|
|||
CPPUNIT_ASSERT(!detector.guessMetalinkFile(A2_TEST_DIR "/test.torrent"));
|
||||
}
|
||||
|
||||
void ProtocolDetectorTest::testGuessAria2ControlFile()
|
||||
{
|
||||
const ProtocolDetector detector;
|
||||
CPPUNIT_ASSERT(detector.guessAria2ControlFile(A2_TEST_DIR "/control_file.aria2"));
|
||||
CPPUNIT_ASSERT(!detector.guessAria2ControlFile(A2_TEST_DIR));
|
||||
CPPUNIT_ASSERT(!detector.guessAria2ControlFile(A2_TEST_DIR "/control_file.aria"));
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
BIN
test/control_file.aria
Normal file
BIN
test/control_file.aria
Normal file
Binary file not shown.
BIN
test/control_file.aria2
Normal file
BIN
test/control_file.aria2
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue