diff --git a/src/base/bittorrent/bencoderesumedatastorage.cpp b/src/base/bittorrent/bencoderesumedatastorage.cpp index b82a3d8f6..922e1f678 100644 --- a/src/base/bittorrent/bencoderesumedatastorage.cpp +++ b/src/base/bittorrent/bencoderesumedatastorage.cpp @@ -44,6 +44,7 @@ #include "base/exceptions.h" #include "base/global.h" #include "base/logger.h" +#include "base/preferences.h" #include "base/profile.h" #include "base/tagset.h" #include "base/utils/fs.h" @@ -134,12 +135,13 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::load(cons const QString idString = id.toString(); const Path fastresumePath = path() / Path(idString + u".fastresume"); const Path torrentFilePath = path() / Path(idString + u".torrent"); + const qint64 torrentSizeLimit = Preferences::instance()->getTorrentFileSizeLimit(); - const auto resumeDataReadResult = Utils::IO::readFile(fastresumePath, MAX_TORRENT_SIZE); + const auto resumeDataReadResult = Utils::IO::readFile(fastresumePath, torrentSizeLimit); if (!resumeDataReadResult) return nonstd::make_unexpected(resumeDataReadResult.error().message); - const auto metadataReadResult = Utils::IO::readFile(torrentFilePath, MAX_TORRENT_SIZE); + const auto metadataReadResult = Utils::IO::readFile(torrentFilePath, torrentSizeLimit); if (!metadataReadResult) { if (metadataReadResult.error().status != Utils::IO::ReadError::NotExist) diff --git a/src/base/bittorrent/common.h b/src/base/bittorrent/common.h index 2c8fe75c7..fa46c0d8d 100644 --- a/src/base/bittorrent/common.h +++ b/src/base/bittorrent/common.h @@ -34,6 +34,5 @@ inline const QString QB_EXT = u".!qB"_s; -inline const int MAX_TORRENT_SIZE = 100 * 1024 * 1024; // 100 MiB inline const int BENCODE_DEPTH_LIMIT = 100; inline const int BENCODE_TOKEN_LIMIT = 10'000'000; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index d3c2304a4..45f26e18b 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -96,7 +96,6 @@ #include "base/version.h" #include "bandwidthscheduler.h" #include "bencoderesumedatastorage.h" -#include "common.h" #include "customstorage.h" #include "dbresumedatastorage.h" #include "downloadpriority.h" @@ -2554,9 +2553,10 @@ bool SessionImpl::addTorrent(const QString &source, const AddTorrentParams ¶ if (Net::DownloadManager::hasSupportedScheme(source)) { LogMsg(tr("Downloading torrent, please wait... Source: \"%1\"").arg(source)); + const auto *pref = Preferences::instance(); // Launch downloader - Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE) - , Preferences::instance()->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished); + Net::DownloadManager::instance()->download(Net::DownloadRequest(source).limit(pref->getTorrentFileSizeLimit()) + , pref->useProxyForGeneralPurposes(), this, &SessionImpl::handleDownloadFinished); m_downloadedTorrents[source] = params; return true; } diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index cefc7d770..7d3e440b2 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -42,6 +42,7 @@ #include "base/global.h" #include "base/path.h" +#include "base/preferences.h" #include "base/utils/fs.h" #include "base/utils/io.h" #include "base/utils/misc.h" @@ -104,7 +105,8 @@ nonstd::expected TorrentInfo::loadFromFile(const Path &pat QByteArray data; try { - const auto readResult = Utils::IO::readFile(path, MAX_TORRENT_SIZE); + const qint64 torrentSizeLimit = Preferences::instance()->getTorrentFileSizeLimit(); + const auto readResult = Utils::IO::readFile(path, torrentSizeLimit); if (!readResult) return nonstd::make_unexpected(readResult.error().message); data = readResult.value(); diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 133333a10..be4ef0832 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -304,6 +304,19 @@ void Preferences::setIconsInMenusEnabled(const bool enable) } #endif // Q_OS_MACOS +qint64 Preferences::getTorrentFileSizeLimit() const +{ + return value(u"BitTorrent/TorrentFileSizeLimit"_s, (100 * 1024 * 1024)); +} + +void Preferences::setTorrentFileSizeLimit(const qint64 value) +{ + if (value == getTorrentFileSizeLimit()) + return; + + setValue(u"BitTorrent/TorrentFileSizeLimit"_s, value); +} + bool Preferences::isToolbarDisplayed() const { return value(u"Preferences/General/ToolbarDisplayed"_s, true); diff --git a/src/base/preferences.h b/src/base/preferences.h index b3539b781..7d6c3c1de 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -333,6 +333,8 @@ public: bool iconsInMenusEnabled() const; void setIconsInMenusEnabled(bool enable); #endif // Q_OS_MACOS + qint64 getTorrentFileSizeLimit() const; + void setTorrentFileSizeLimit(qint64 value); // Stuff that don't appear in the Options GUI but are saved // in the same file. diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index e91c84177..840c900ca 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -43,7 +43,6 @@ #include #include -#include "base/bittorrent/common.h" #include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/infohash.h" #include "base/bittorrent/magneturi.h" @@ -489,10 +488,11 @@ void AddNewTorrentDialog::show(const QString &source, const BitTorrent::AddTorre if (Net::DownloadManager::hasSupportedScheme(source)) { + const auto *pref = Preferences::instance(); // Launch downloader Net::DownloadManager::instance()->download( - Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE) - , Preferences::instance()->useProxyForGeneralPurposes() + Net::DownloadRequest(source).limit(pref->getTorrentFileSizeLimit()) + , pref->useProxyForGeneralPurposes() , dlg, &AddNewTorrentDialog::handleDownloadFinished); return; } diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 5de7bac89..882a6abd6 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -75,6 +75,7 @@ namespace NETWORK_IFACE_ADDRESS, // behavior SAVE_RESUME_DATA_INTERVAL, + TORRENT_FILE_SIZE_LIMIT, CONFIRM_RECHECK_TORRENT, RECHECK_COMPLETED, // UI related @@ -244,6 +245,8 @@ void AdvancedSettings::saveAdvancedSettings() const session->setSocketBacklogSize(m_spinBoxSocketBacklogSize.value()); // Save resume data interval session->setSaveResumeDataInterval(m_spinBoxSaveResumeDataInterval.value()); + // .torrent file size limit + pref->setTorrentFileSizeLimit(m_spinBoxTorrentFileSizeLimit.value() * 1024 * 1024); // Outgoing ports session->setOutgoingPortsMin(m_spinBoxOutgoingPortsMin.value()); session->setOutgoingPortsMax(m_spinBoxOutgoingPortsMax.value()); @@ -619,6 +622,12 @@ void AdvancedSettings::loadAdvancedSettings() m_spinBoxSaveResumeDataInterval.setSuffix(tr(" min", " minutes")); m_spinBoxSaveResumeDataInterval.setSpecialValueText(tr("0 (disabled)")); addRow(SAVE_RESUME_DATA_INTERVAL, tr("Save resume data interval [0: disabled]", "How often the fastresume file is saved."), &m_spinBoxSaveResumeDataInterval); + // .torrent file size limit + m_spinBoxTorrentFileSizeLimit.setMinimum(1); + m_spinBoxTorrentFileSizeLimit.setMaximum(std::numeric_limits::max() / 1024 / 1024); + m_spinBoxTorrentFileSizeLimit.setValue(pref->getTorrentFileSizeLimit() / 1024 / 1024); + m_spinBoxTorrentFileSizeLimit.setSuffix(tr(" MiB")); + addRow(TORRENT_FILE_SIZE_LIMIT, tr(".torrent file size limit"), &m_spinBoxTorrentFileSizeLimit); // Outgoing port Min m_spinBoxOutgoingPortsMin.setMinimum(0); m_spinBoxOutgoingPortsMin.setMaximum(65535); diff --git a/src/gui/advancedsettings.h b/src/gui/advancedsettings.h index 2d646f555..fc1a46907 100644 --- a/src/gui/advancedsettings.h +++ b/src/gui/advancedsettings.h @@ -67,8 +67,9 @@ private: void loadAdvancedSettings(); template void addRow(int row, const QString &text, T *widget); - QSpinBox m_spinBoxAsyncIOThreads, m_spinBoxFilePoolSize, m_spinBoxCheckingMemUsage, m_spinBoxDiskQueueSize, - m_spinBoxSaveResumeDataInterval, m_spinBoxOutgoingPortsMin, m_spinBoxOutgoingPortsMax, m_spinBoxUPnPLeaseDuration, m_spinBoxPeerToS, + QSpinBox m_spinBoxSaveResumeDataInterval, m_spinBoxTorrentFileSizeLimit, + m_spinBoxAsyncIOThreads, m_spinBoxFilePoolSize, m_spinBoxCheckingMemUsage, m_spinBoxDiskQueueSize, + m_spinBoxOutgoingPortsMin, m_spinBoxOutgoingPortsMax, m_spinBoxUPnPLeaseDuration, m_spinBoxPeerToS, m_spinBoxListRefresh, m_spinBoxTrackerPort, m_spinBoxSendBufferWatermark, m_spinBoxSendBufferLowWatermark, m_spinBoxSendBufferWatermarkFactor, m_spinBoxConnectionSpeed, m_spinBoxSocketSendBufferSize, m_spinBoxSocketReceiveBufferSize, m_spinBoxSocketBacklogSize, m_spinBoxMaxConcurrentHTTPAnnounces, m_spinBoxStopTrackerTimeout, diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index 1bb67cbe7..c718e5232 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -323,6 +323,8 @@ void AppController::preferencesAction() data[u"current_interface_address"_s] = BitTorrent::Session::instance()->networkInterfaceAddress(); // Save resume data interval data[u"save_resume_data_interval"_s] = session->saveResumeDataInterval(); + // .torrent file size limit + data[u"torrent_file_size_limit"_s] = pref->getTorrentFileSizeLimit(); // Recheck completed torrents data[u"recheck_completed_torrents"_s] = pref->recheckTorrentsOnCompletion(); // Refresh interval @@ -853,6 +855,9 @@ void AppController::setPreferencesAction() // Save resume data interval if (hasKey(u"save_resume_data_interval"_s)) session->setSaveResumeDataInterval(it.value().toInt()); + // .torrent file size limit + if (hasKey(u"torrent_file_size_limit"_s)) + pref->setTorrentFileSizeLimit(it.value().toLongLong()); // Recheck completed torrents if (hasKey(u"recheck_completed_torrents"_s)) pref->recheckTorrentsOnCompletion(it.value().toBool()); diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 4c6d22a0c..253cfcfcf 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -977,6 +977,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD   QBT_TR(min)QBT_TR[CONTEXT=OptionsDialog] + + + + + +   QBT_TR(MiB)QBT_TR[CONTEXT=OptionsDialog] + + @@ -2147,6 +2155,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD updateNetworkInterfaces(pref.current_network_interface); updateInterfaceAddresses(pref.current_network_interface, pref.current_interface_address); $('saveResumeDataInterval').setProperty('value', pref.save_resume_data_interval); + $('torrentFileSizeLimit').setProperty('value', (pref.torrent_file_size_limit / 1024 / 1024)); $('recheckTorrentsOnCompletion').setProperty('checked', pref.recheck_completed_torrents); $('refreshInterval').setProperty('value', pref.refresh_interval); $('resolvePeerCountries').setProperty('checked', pref.resolve_peer_countries); @@ -2563,6 +2572,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings.set('current_network_interface', $('networkInterface').getProperty('value')); settings.set('current_interface_address', $('optionalIPAddressToBind').getProperty('value')); settings.set('save_resume_data_interval', $('saveResumeDataInterval').getProperty('value')); + settings.set('torrent_file_size_limit', ($('torrentFileSizeLimit').getProperty('value') * 1024 * 1024)); settings.set('recheck_completed_torrents', $('recheckTorrentsOnCompletion').getProperty('checked')); settings.set('refresh_interval', $('refreshInterval').getProperty('value')); settings.set('resolve_peer_countries', $('resolvePeerCountries').getProperty('checked'));