mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-16 02:03:07 -07:00
Load torrents that have big metadata file. Closes #1889.
This commit is contained in:
parent
0adb9fcbce
commit
f35e06540e
5 changed files with 115 additions and 76 deletions
|
@ -191,9 +191,14 @@ bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path, const QString
|
||||||
m_hasMetadata = true;
|
m_hasMetadata = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_torrentInfo = new torrent_info(fsutils::toNativePath(m_filePath).toUtf8().data());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(m_filePath, buffer, entry, ec);
|
||||||
|
m_torrentInfo = new torrent_info(entry);
|
||||||
m_hash = misc::toQString(m_torrentInfo->info_hash());
|
m_hash = misc::toQString(m_torrentInfo->info_hash());
|
||||||
} catch(const std::exception& e) {
|
}
|
||||||
|
catch(const std::exception& e) {
|
||||||
MessageBoxRaised::critical(0, tr("Invalid torrent"), tr("Failed to load the torrent: %1").arg(misc::toQStringU(e.what())));
|
MessageBoxRaised::critical(0, tr("Invalid torrent"), tr("Failed to load the torrent: %1").arg(misc::toQStringU(e.what())));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
13
src/misc.cpp
13
src/misc.cpp
|
@ -77,6 +77,7 @@ const int UNLEN = 256;
|
||||||
#include <libtorrent/sha1_hash.hpp>
|
#include <libtorrent/sha1_hash.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include <libtorrent/escape_string.hpp>
|
#include <libtorrent/escape_string.hpp>
|
||||||
|
#include <libtorrent/lazy_entry.hpp>
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
@ -655,6 +656,18 @@ bool misc::slowEquals(const QByteArray &a, const QByteArray &b)
|
||||||
return (diff == 0);
|
return (diff == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void misc::loadBencodedFile(const QString &filename, std::vector<char> &buffer, libtorrent::lazy_entry &entry, libtorrent::error_code &ec)
|
||||||
|
{
|
||||||
|
QFile file(filename);
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) return;
|
||||||
|
const qint64 content_size = file.bytesAvailable();
|
||||||
|
if (content_size <= 0) return;
|
||||||
|
buffer.resize(content_size);
|
||||||
|
file.read(&buffer[0], content_size);
|
||||||
|
// bdecode
|
||||||
|
lazy_bdecode(&buffer[0], &buffer[0] + buffer.size(), entry, ec);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Trick to get a portable sleep() function
|
// Trick to get a portable sleep() function
|
||||||
class SleeperThread : public QThread {
|
class SleeperThread : public QThread {
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libtorrent/version.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
|
#include <libtorrent/error_code.hpp>
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
#if LIBTORRENT_VERSION_NUM < 10000
|
#if LIBTORRENT_VERSION_NUM < 10000
|
||||||
|
@ -52,6 +53,7 @@ namespace libtorrent {
|
||||||
#else
|
#else
|
||||||
class sha1_hash;
|
class sha1_hash;
|
||||||
#endif
|
#endif
|
||||||
|
struct lazy_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qlonglong MAX_ETA = 8640000;
|
const qlonglong MAX_ETA = 8640000;
|
||||||
|
@ -109,6 +111,7 @@ namespace misc
|
||||||
// Implements constant-time comparison to protect against timing attacks
|
// Implements constant-time comparison to protect against timing attacks
|
||||||
// Taken from https://crackstation.net/hashing-security.htm
|
// Taken from https://crackstation.net/hashing-security.htm
|
||||||
bool slowEquals(const QByteArray &a, const QByteArray &b);
|
bool slowEquals(const QByteArray &a, const QByteArray &b);
|
||||||
|
void loadBencodedFile(const QString &filename, std::vector<char> &buffer, libtorrent::lazy_entry &entry, libtorrent::error_code &ec);
|
||||||
|
|
||||||
void msleep(unsigned long msecs);
|
void msleep(unsigned long msecs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1058,7 +1058,11 @@ QTorrentHandle QBtSession::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
try {
|
try {
|
||||||
qDebug() << "Loading torrent at" << path;
|
qDebug() << "Loading torrent at" << path;
|
||||||
// Getting torrent file informations
|
// Getting torrent file informations
|
||||||
t = new torrent_info(fsutils::toNativePath(path).toUtf8().constData());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(path, buffer, entry, ec);
|
||||||
|
t = new torrent_info(entry);
|
||||||
if (!t->is_valid())
|
if (!t->is_valid())
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
} catch(std::exception& e) {
|
} catch(std::exception& e) {
|
||||||
|
@ -1508,17 +1512,10 @@ void QBtSession::loadSessionState() {
|
||||||
fsutils::forceRemove(state_path);
|
fsutils::forceRemove(state_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QFile state_file(state_path);
|
|
||||||
if (!state_file.open(QIODevice::ReadOnly)) return;
|
|
||||||
std::vector<char> in;
|
std::vector<char> in;
|
||||||
const qint64 content_size = state_file.bytesAvailable();
|
|
||||||
if (content_size <= 0) return;
|
|
||||||
in.resize(content_size);
|
|
||||||
state_file.read(&in[0], content_size);
|
|
||||||
// bdecode
|
|
||||||
lazy_entry e;
|
lazy_entry e;
|
||||||
libtorrent::error_code ec;
|
libtorrent::error_code ec;
|
||||||
lazy_bdecode(&in[0], &in[0] + in.size(), e, ec);
|
misc::loadBencodedFile(state_path, in, e, ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
s->load_state(e);
|
s->load_state(e);
|
||||||
}
|
}
|
||||||
|
@ -1752,7 +1749,8 @@ bool QBtSession::isFilePreviewPossible(const QString &hash) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBtSession::addTorrentsFromScanFolder(QStringList &pathList) {
|
void QBtSession::addTorrentsFromScanFolder(QStringList &pathList)
|
||||||
|
{
|
||||||
foreach (const QString &file, pathList) {
|
foreach (const QString &file, pathList) {
|
||||||
qDebug("File %s added", qPrintable(file));
|
qDebug("File %s added", qPrintable(file));
|
||||||
if (file.endsWith(".magnet")) {
|
if (file.endsWith(".magnet")) {
|
||||||
|
@ -1767,7 +1765,11 @@ void QBtSession::addTorrentsFromScanFolder(QStringList &pathList) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
torrent_info t(fsutils::toNativePath(file).toUtf8().constData());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(file, buffer, entry, ec);
|
||||||
|
torrent_info t(entry);
|
||||||
if (t.is_valid())
|
if (t.is_valid())
|
||||||
addTorrent(file, true);
|
addTorrent(file, true);
|
||||||
} catch(std::exception&) {
|
} catch(std::exception&) {
|
||||||
|
@ -2049,7 +2051,8 @@ void QBtSession::disableIPFilter() {
|
||||||
filterPath = "";
|
filterPath = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h) {
|
void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
for (int i=0; i<h.num_files(); ++i) {
|
for (int i=0; i<h.num_files(); ++i) {
|
||||||
const QString torrent_relpath = h.filepath_at(i);
|
const QString torrent_relpath = h.filepath_at(i);
|
||||||
|
@ -2057,14 +2060,19 @@ void QBtSession::recursiveTorrentDownload(const QTorrentHandle &h) {
|
||||||
addConsoleMessage(tr("Recursive download of file %1 embedded in torrent %2", "Recursive download of test.torrent embedded in torrent test2").arg(fsutils::toNativePath(torrent_relpath)).arg(h.name()));
|
addConsoleMessage(tr("Recursive download of file %1 embedded in torrent %2", "Recursive download of test.torrent embedded in torrent test2").arg(fsutils::toNativePath(torrent_relpath)).arg(h.name()));
|
||||||
const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath;
|
const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath;
|
||||||
|
|
||||||
boost::intrusive_ptr<torrent_info> t = new torrent_info(fsutils::toNativePath(torrent_fullpath).toUtf8().constData());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(torrent_fullpath, buffer, entry, ec);
|
||||||
|
boost::intrusive_ptr<torrent_info> t = new torrent_info(entry);
|
||||||
const QString sub_hash = misc::toQString(t->info_hash());
|
const QString sub_hash = misc::toQString(t->info_hash());
|
||||||
// Passing the save path along to the sub torrent file
|
// Passing the save path along to the sub torrent file
|
||||||
TorrentTempData::setSavePath(sub_hash, h.save_path());
|
TorrentTempData::setSavePath(sub_hash, h.save_path());
|
||||||
addTorrent(torrent_fullpath);
|
addTorrent(torrent_fullpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(std::exception&) {
|
}
|
||||||
|
catch(std::exception&) {
|
||||||
qDebug("Caught error loading torrent");
|
qDebug("Caught error loading torrent");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2218,13 +2226,18 @@ void QBtSession::handleTorrentFinishedAlert(libtorrent::torrent_finished_alert*
|
||||||
const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath;
|
const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath;
|
||||||
qDebug("Full subtorrent path is %s", qPrintable(torrent_fullpath));
|
qDebug("Full subtorrent path is %s", qPrintable(torrent_fullpath));
|
||||||
try {
|
try {
|
||||||
boost::intrusive_ptr<torrent_info> t = new torrent_info(fsutils::toNativePath(torrent_fullpath).toUtf8().constData());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(torrent_fullpath, buffer, entry, ec);
|
||||||
|
boost::intrusive_ptr<torrent_info> t = new torrent_info(entry);
|
||||||
if (t->is_valid()) {
|
if (t->is_valid()) {
|
||||||
qDebug("emitting recursiveTorrentDownloadPossible()");
|
qDebug("emitting recursiveTorrentDownloadPossible()");
|
||||||
emit recursiveTorrentDownloadPossible(h);
|
emit recursiveTorrentDownloadPossible(h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch(std::exception&) {
|
}
|
||||||
|
catch(std::exception&) {
|
||||||
qDebug("Caught error loading torrent");
|
qDebug("Caught error loading torrent");
|
||||||
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(fsutils::toNativePath(torrent_fullpath)), QString::fromUtf8("red"));
|
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(fsutils::toNativePath(torrent_fullpath)), QString::fromUtf8("red"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,10 +217,15 @@ void TorrentImportDlg::loadTorrent(const QString &torrent_path)
|
||||||
{
|
{
|
||||||
// Load the torrent file
|
// Load the torrent file
|
||||||
try {
|
try {
|
||||||
t = new torrent_info(fsutils::toNativePath(torrent_path).toUtf8().constData());
|
std::vector<char> buffer;
|
||||||
|
lazy_entry entry;
|
||||||
|
libtorrent::error_code ec;
|
||||||
|
misc::loadBencodedFile(torrent_path, buffer, entry, ec);
|
||||||
|
t = new torrent_info(entry);
|
||||||
if (!t->is_valid() || t->num_files() == 0)
|
if (!t->is_valid() || t->num_files() == 0)
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
} catch(std::exception&) {
|
}
|
||||||
|
catch(std::exception&) {
|
||||||
ui->browseContentBtn->setEnabled(false);
|
ui->browseContentBtn->setEnabled(false);
|
||||||
ui->lineTorrent->clear();
|
ui->lineTorrent->clear();
|
||||||
QMessageBox::warning(this, tr("Invalid torrent file"), tr("This is not a valid torrent file."));
|
QMessageBox::warning(this, tr("Invalid torrent file"), tr("This is not a valid torrent file."));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue