35 #include <QCoreApplication>
38 #include <QJsonDocument>
39 #include <QJsonObject>
40 #include <QNetworkInterface>
41 #include <QRegularExpression>
42 #include <QStringList>
44 #include <QTranslator>
60 #include "base/version.h"
61 #include "../webapplication.h"
75 const QJsonObject versions =
77 {
"qt", QT_VERSION_STR},
82 {
"bitness", (QT_POINTER_SIZE * 8)}
89 qDebug() <<
"Shutdown request from Web UI";
94 QTimer::singleShot(100, qApp, &QCoreApplication::quit);
106 data[
"start_paused_enabled"] = session->isAddTorrentPaused();
108 data[
"preallocate_all"] = session->isPreallocationEnabled();
109 data[
"incomplete_files_ext"] = session->isAppendExtensionEnabled();
111 data[
"auto_tmm_enabled"] = !session->isAutoTMMDisabledByDefault();
112 data[
"torrent_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategoryChanged();
113 data[
"save_path_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenDefaultSavePathChanged();
114 data[
"category_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategorySavePathChanged();
116 data[
"temp_path_enabled"] = session->isDownloadPathEnabled();
124 const QHash<QString, TorrentFilesWatcher::WatchedFolderOptions> watchedFolders = fsWatcher->
folders();
125 QJsonObject nativeDirs;
126 for (
auto i = watchedFolders.cbegin(); i != watchedFolders.cend(); ++i)
128 const QString watchedFolder = i.key();
130 if (
params.savePath.isEmpty())
132 else if (
params.savePath == watchedFolder)
137 data[
"scan_dirs"] = nativeDirs;
155 data[
"listen_port"] = session->port();
156 data[
"random_port"] = (session->port() == 0);
159 data[
"max_connec"] = session->maxConnections();
160 data[
"max_connec_per_torrent"] = session->maxConnectionsPerTorrent();
161 data[
"max_uploads"] = session->maxUploads();
162 data[
"max_uploads_per_torrent"] = session->maxUploadsPerTorrent();
167 data[
"proxy_type"] =
static_cast<int>(proxyConf.
type);
168 data[
"proxy_ip"] = proxyConf.
ip;
169 data[
"proxy_port"] = proxyConf.
port;
170 data[
"proxy_auth_enabled"] = proxyManager->isAuthenticationRequired();
174 data[
"proxy_peer_connections"] = session->isProxyPeerConnectionsEnabled();
175 data[
"proxy_torrents_only"] = proxyManager->isProxyOnlyForTorrents();
178 data[
"ip_filter_enabled"] = session->isIPFilteringEnabled();
180 data[
"ip_filter_trackers"] = session->isTrackerFilteringEnabled();
181 data[
"banned_IPs"] = session->bannedIPs().join(
'\n');
185 data[
"dl_limit"] = session->globalDownloadSpeedLimit();
186 data[
"up_limit"] = session->globalUploadSpeedLimit();
187 data[
"alt_dl_limit"] = session->altGlobalDownloadSpeedLimit();
188 data[
"alt_up_limit"] = session->altGlobalUploadSpeedLimit();
189 data[
"bittorrent_protocol"] =
static_cast<int>(session->btProtocol());
190 data[
"limit_utp_rate"] = session->isUTPRateLimited();
191 data[
"limit_tcp_overhead"] = session->includeOverheadInLimits();
192 data[
"limit_lan_peers"] = !session->ignoreLimitsOnLAN();
194 data[
"scheduler_enabled"] = session->isBandwidthSchedulerEnabled();
196 data[
"schedule_from_hour"] = start_time.hour();
197 data[
"schedule_from_min"] = start_time.minute();
199 data[
"schedule_to_hour"] = end_time.hour();
200 data[
"schedule_to_min"] = end_time.minute();
205 data[
"dht"] = session->isDHTEnabled();
206 data[
"pex"] = session->isPeXEnabled();
207 data[
"lsd"] = session->isLSDEnabled();
208 data[
"encryption"] = session->encryption();
209 data[
"anonymous_mode"] = session->isAnonymousModeEnabled();
211 data[
"queueing_enabled"] = session->isQueueingSystemEnabled();
212 data[
"max_active_downloads"] = session->maxActiveDownloads();
213 data[
"max_active_torrents"] = session->maxActiveTorrents();
214 data[
"max_active_uploads"] = session->maxActiveUploads();
215 data[
"dont_count_slow_torrents"] = session->ignoreSlowTorrentsForQueueing();
216 data[
"slow_torrent_dl_rate_threshold"] = session->downloadRateForSlowTorrents();
217 data[
"slow_torrent_ul_rate_threshold"] = session->uploadRateForSlowTorrents();
218 data[
"slow_torrent_inactive_timer"] = session->slowTorrentsInactivityTimer();
220 data[
"max_ratio_enabled"] = (session->globalMaxRatio() >= 0.);
221 data[
"max_ratio"] = session->globalMaxRatio();
222 data[
"max_seeding_time_enabled"] = (session->globalMaxSeedingMinutes() >= 0.);
223 data[
"max_seeding_time"] = session->globalMaxSeedingMinutes();
224 data[
"max_ratio_act"] = session->maxRatioAction();
226 data[
"add_trackers_enabled"] = session->isAddTrackersEnabled();
227 data[
"add_trackers"] = session->additionalTrackers();
244 QStringList authSubnetWhitelistStringList;
247 data[
"bypass_auth_subnet_whitelist"] = authSubnetWhitelistStringList.join(
'\n');
283 data[
"current_network_interface"] = session->networkInterface();
287 data[
"save_resume_data_interval"] = session->saveResumeDataInterval();
293 data[
"reannounce_when_address_changed"] = session->isReannounceWhenAddressChangedEnabled();
297 data[
"async_io_threads"] = session->asyncIOThreads();
299 data[
"hashing_threads"] = session->hashingThreads();
301 data[
"file_pool_size"] = session->filePoolSize();
303 data[
"checking_memory_use"] = session->checkingMemUsage();
305 data[
"disk_cache"] = session->diskCacheSize();
306 data[
"disk_cache_ttl"] = session->diskCacheTTL();
308 data[
"enable_os_cache"] = session->useOSCache();
310 data[
"enable_coalesce_read_write"] = session->isCoalesceReadWriteEnabled();
312 data[
"enable_piece_extent_affinity"] = session->usePieceExtentAffinity();
314 data[
"enable_upload_suggestions"] = session->isSuggestModeEnabled();
316 data[
"send_buffer_watermark"] = session->sendBufferWatermark();
317 data[
"send_buffer_low_watermark"] = session->sendBufferLowWatermark();
318 data[
"send_buffer_watermark_factor"] = session->sendBufferWatermarkFactor();
320 data[
"connection_speed"] = session->connectionSpeed();
322 data[
"socket_backlog_size"] = session->socketBacklogSize();
324 data[
"outgoing_ports_min"] = session->outgoingPortsMin();
325 data[
"outgoing_ports_max"] = session->outgoingPortsMax();
327 data[
"upnp_lease_duration"] = session->UPnPLeaseDuration();
329 data[
"peer_tos"] = session->peerToS();
331 data[
"utp_tcp_mixed_mode"] =
static_cast<int>(session->utpMixedMode());
333 data[
"idn_support_enabled"] = session->isIDNSupportEnabled();
335 data[
"enable_multi_connections_from_same_ip"] = session->multiConnectionsPerIpEnabled();
337 data[
"validate_https_tracker_certificate"] = session->validateHTTPSTrackerCertificate();
339 data[
"ssrf_mitigation"] = session->isSSRFMitigationEnabled();
341 data[
"block_peers_on_privileged_ports"] = session->blockPeersOnPrivilegedPorts();
343 data[
"enable_embedded_tracker"] = session->isTrackerEnabled();
346 data[
"upload_slots_behavior"] =
static_cast<int>(session->chokingAlgorithm());
348 data[
"upload_choking_algorithm"] =
static_cast<int>(session->seedChokingAlgorithm());
350 data[
"announce_to_all_trackers"] = session->announceToAllTrackers();
351 data[
"announce_to_all_tiers"] = session->announceToAllTiers();
352 data[
"announce_ip"] = session->announceIP();
353 data[
"max_concurrent_http_announces"] = session->maxConcurrentHTTPAnnounces();
354 data[
"stop_tracker_timeout"] = session->stopTrackerTimeout();
356 data[
"peer_turnover"] = session->peerTurnover();
357 data[
"peer_turnover_cutoff"] = session->peerTurnoverCutoff();
358 data[
"peer_turnover_interval"] = session->peerTurnoverInterval();
369 const QVariantHash
m = QJsonDocument::fromJson(
params()[
"json"].toUtf8()).toVariant().toHash();
371 QVariantHash::ConstIterator it;
372 const auto hasKey = [&it, &
m](
const char *key) ->
bool
374 it =
m.find(QLatin1String(key));
375 return (it !=
m.constEnd());
380 if (hasKey(
"torrent_content_layout"))
381 session->setTorrentContentLayout(
Utils::String::toEnum(it.value().toString(), BitTorrent::TorrentContentLayout::Original));
382 if (hasKey(
"start_paused_enabled"))
383 session->setAddTorrentPaused(it.value().toBool());
384 if (hasKey(
"auto_delete_mode"))
387 if (hasKey(
"preallocate_all"))
388 session->setPreallocationEnabled(it.value().toBool());
389 if (hasKey(
"incomplete_files_ext"))
390 session->setAppendExtensionEnabled(it.value().toBool());
393 if (hasKey(
"auto_tmm_enabled"))
394 session->setAutoTMMDisabledByDefault(!it.value().toBool());
395 if (hasKey(
"torrent_changed_tmm_enabled"))
396 session->setDisableAutoTMMWhenCategoryChanged(!it.value().toBool());
397 if (hasKey(
"save_path_changed_tmm_enabled"))
398 session->setDisableAutoTMMWhenDefaultSavePathChanged(!it.value().toBool());
399 if (hasKey(
"category_changed_tmm_enabled"))
400 session->setDisableAutoTMMWhenCategorySavePathChanged(!it.value().toBool());
401 if (hasKey(
"save_path"))
402 session->setSavePath(it.value().toString());
403 if (hasKey(
"temp_path_enabled"))
404 session->setDownloadPathEnabled(it.value().toBool());
405 if (hasKey(
"temp_path"))
406 session->setDownloadPath(it.value().toString());
407 if (hasKey(
"export_dir"))
408 session->setTorrentExportDirectory(it.value().toString());
409 if (hasKey(
"export_dir_fin"))
410 session->setFinishedTorrentExportDirectory(it.value().toString());
414 if (hasKey(
"scan_dirs"))
416 QStringList scanDirs;
418 const QStringList oldScanDirs = fsWatcher->
folders().keys();
419 const QVariantHash nativeDirs = it.value().toHash();
420 for (
auto i = nativeDirs.cbegin(); i != nativeDirs.cend(); ++i)
429 const int intVal = i.value().toInt(&isInt);
434 params.savePath = watchedFolder;
435 params.useAutoTMM =
false;
440 const QString customSavePath = i.value().toString();
441 params.savePath = customSavePath;
442 params.useAutoTMM =
false;
446 scanDirs.append(watchedFolder);
454 for (
const QString &path : oldScanDirs)
456 if (!scanDirs.contains(path))
463 if (hasKey(
"mail_notification_enabled"))
464 pref->setMailNotificationEnabled(it.value().toBool());
465 if (hasKey(
"mail_notification_sender"))
466 pref->setMailNotificationSender(it.value().toString());
467 if (hasKey(
"mail_notification_email"))
468 pref->setMailNotificationEmail(it.value().toString());
469 if (hasKey(
"mail_notification_smtp"))
470 pref->setMailNotificationSMTP(it.value().toString());
471 if (hasKey(
"mail_notification_ssl_enabled"))
472 pref->setMailNotificationSMTPSSL(it.value().toBool());
473 if (hasKey(
"mail_notification_auth_enabled"))
474 pref->setMailNotificationSMTPAuth(it.value().toBool());
475 if (hasKey(
"mail_notification_username"))
476 pref->setMailNotificationSMTPUsername(it.value().toString());
477 if (hasKey(
"mail_notification_password"))
478 pref->setMailNotificationSMTPPassword(it.value().toString());
480 if (hasKey(
"autorun_enabled"))
481 pref->setAutoRunEnabled(it.value().toBool());
482 if (hasKey(
"autorun_program"))
483 pref->setAutoRunProgram(it.value().toString());
487 if (hasKey(
"random_port") && it.value().toBool())
491 else if (hasKey(
"listen_port"))
493 session->setPort(it.value().toInt());
498 if (hasKey(
"max_connec"))
499 session->setMaxConnections(it.value().toInt());
500 if (hasKey(
"max_connec_per_torrent"))
501 session->setMaxConnectionsPerTorrent(it.value().toInt());
502 if (hasKey(
"max_uploads"))
503 session->setMaxUploads(it.value().toInt());
504 if (hasKey(
"max_uploads_per_torrent"))
505 session->setMaxUploadsPerTorrent(it.value().toInt());
510 if (hasKey(
"proxy_type"))
512 if (hasKey(
"proxy_ip"))
513 proxyConf.
ip = it.value().toString();
514 if (hasKey(
"proxy_port"))
515 proxyConf.
port = it.value().toUInt();
516 if (hasKey(
"proxy_username"))
517 proxyConf.
username = it.value().toString();
518 if (hasKey(
"proxy_password"))
519 proxyConf.
password = it.value().toString();
520 proxyManager->setProxyConfiguration(proxyConf);
522 if (hasKey(
"proxy_peer_connections"))
523 session->setProxyPeerConnectionsEnabled(it.value().toBool());
524 if (hasKey(
"proxy_torrents_only"))
525 proxyManager->setProxyOnlyForTorrents(it.value().toBool());
528 if (hasKey(
"ip_filter_enabled"))
529 session->setIPFilteringEnabled(it.value().toBool());
530 if (hasKey(
"ip_filter_path"))
531 session->setIPFilterFile(it.value().toString());
532 if (hasKey(
"ip_filter_trackers"))
533 session->setTrackerFilteringEnabled(it.value().toBool());
534 if (hasKey(
"banned_IPs"))
535 session->setBannedIPs(it.value().toString().split(
'\n', Qt::SkipEmptyParts));
539 if (hasKey(
"dl_limit"))
540 session->setGlobalDownloadSpeedLimit(it.value().toInt());
541 if (hasKey(
"up_limit"))
542 session->setGlobalUploadSpeedLimit(it.value().toInt());
543 if (hasKey(
"alt_dl_limit"))
544 session->setAltGlobalDownloadSpeedLimit(it.value().toInt());
545 if (hasKey(
"alt_up_limit"))
546 session->setAltGlobalUploadSpeedLimit(it.value().toInt());
547 if (hasKey(
"bittorrent_protocol"))
549 if (hasKey(
"limit_utp_rate"))
550 session->setUTPRateLimited(it.value().toBool());
551 if (hasKey(
"limit_tcp_overhead"))
552 session->setIncludeOverheadInLimits(it.value().toBool());
553 if (hasKey(
"limit_lan_peers"))
554 session->setIgnoreLimitsOnLAN(!it.value().toBool());
556 if (hasKey(
"scheduler_enabled"))
557 session->setBandwidthSchedulerEnabled(it.value().toBool());
558 if (
m.contains(
"schedule_from_hour") &&
m.contains(
"schedule_from_min"))
559 pref->setSchedulerStartTime(QTime(
m[
"schedule_from_hour"].toInt(),
m[
"schedule_from_min"].toInt()));
560 if (
m.contains(
"schedule_to_hour") &&
m.contains(
"schedule_to_min"))
561 pref->setSchedulerEndTime(QTime(
m[
"schedule_to_hour"].toInt(),
m[
"schedule_to_min"].toInt()));
562 if (hasKey(
"scheduler_days"))
563 pref->setSchedulerDays(
static_cast<Scheduler::Days>(it.value().toInt()));
568 session->setDHTEnabled(it.value().toBool());
570 session->setPeXEnabled(it.value().toBool());
572 session->setLSDEnabled(it.value().toBool());
573 if (hasKey(
"encryption"))
574 session->setEncryption(it.value().toInt());
575 if (hasKey(
"anonymous_mode"))
576 session->setAnonymousModeEnabled(it.value().toBool());
578 if (hasKey(
"queueing_enabled"))
579 session->setQueueingSystemEnabled(it.value().toBool());
580 if (hasKey(
"max_active_downloads"))
581 session->setMaxActiveDownloads(it.value().toInt());
582 if (hasKey(
"max_active_torrents"))
583 session->setMaxActiveTorrents(it.value().toInt());
584 if (hasKey(
"max_active_uploads"))
585 session->setMaxActiveUploads(it.value().toInt());
586 if (hasKey(
"dont_count_slow_torrents"))
587 session->setIgnoreSlowTorrentsForQueueing(it.value().toBool());
588 if (hasKey(
"slow_torrent_dl_rate_threshold"))
589 session->setDownloadRateForSlowTorrents(it.value().toInt());
590 if (hasKey(
"slow_torrent_ul_rate_threshold"))
591 session->setUploadRateForSlowTorrents(it.value().toInt());
592 if (hasKey(
"slow_torrent_inactive_timer"))
593 session->setSlowTorrentsInactivityTimer(it.value().toInt());
595 if (hasKey(
"max_ratio_enabled"))
597 if (it.value().toBool())
598 session->setGlobalMaxRatio(
m[
"max_ratio"].toReal());
600 session->setGlobalMaxRatio(-1);
602 if (hasKey(
"max_seeding_time_enabled"))
604 if (it.value().toBool())
605 session->setGlobalMaxSeedingMinutes(
m[
"max_seeding_time"].toInt());
607 session->setGlobalMaxSeedingMinutes(-1);
609 if (hasKey(
"max_ratio_act"))
610 session->setMaxRatioAction(
static_cast<MaxRatioAction>(it.value().toInt()));
612 if (hasKey(
"add_trackers_enabled"))
613 session->setAddTrackersEnabled(it.value().toBool());
614 if (hasKey(
"add_trackers"))
615 session->setAdditionalTrackers(it.value().toString());
619 if (hasKey(
"locale"))
621 QString locale = it.value().toString();
622 if (pref->getLocale() != locale)
624 auto *translator =
new QTranslator;
625 if (translator->load(QLatin1String(
":/lang/qbittorrent_") + locale))
627 qDebug(
"%s locale recognized, using translation.", qUtf8Printable(locale));
631 qDebug(
"%s locale unrecognized, using default (en).", qUtf8Printable(locale));
633 qApp->installTranslator(translator);
635 pref->setLocale(locale);
639 if (hasKey(
"web_ui_domain_list"))
640 pref->setServerDomains(it.value().toString());
641 if (hasKey(
"web_ui_address"))
642 pref->setWebUiAddress(it.value().toString());
643 if (hasKey(
"web_ui_port"))
644 pref->setWebUiPort(it.value().toUInt());
645 if (hasKey(
"web_ui_upnp"))
646 pref->setUPnPForWebUIPort(it.value().toBool());
647 if (hasKey(
"use_https"))
648 pref->setWebUiHttpsEnabled(it.value().toBool());
649 if (hasKey(
"web_ui_https_cert_path"))
650 pref->setWebUIHttpsCertificatePath(it.value().toString());
651 if (hasKey(
"web_ui_https_key_path"))
652 pref->setWebUIHttpsKeyPath(it.value().toString());
654 if (hasKey(
"web_ui_username"))
655 pref->setWebUiUsername(it.value().toString());
656 if (hasKey(
"web_ui_password"))
658 if (hasKey(
"bypass_local_auth"))
659 pref->setWebUiLocalAuthEnabled(!it.value().toBool());
660 if (hasKey(
"bypass_auth_subnet_whitelist_enabled"))
661 pref->setWebUiAuthSubnetWhitelistEnabled(it.value().toBool());
662 if (hasKey(
"bypass_auth_subnet_whitelist"))
665 pref->setWebUiAuthSubnetWhitelist(it.value().toString().split(QRegularExpression(
"\n|,"), Qt::SkipEmptyParts));
667 if (hasKey(
"web_ui_max_auth_fail_count"))
668 pref->setWebUIMaxAuthFailCount(it.value().toInt());
669 if (hasKey(
"web_ui_ban_duration"))
670 pref->setWebUIBanDuration(std::chrono::seconds {it.value().toInt()});
671 if (hasKey(
"web_ui_session_timeout"))
672 pref->setWebUISessionTimeout(it.value().toInt());
674 if (hasKey(
"alternative_webui_enabled"))
675 pref->setAltWebUiEnabled(it.value().toBool());
676 if (hasKey(
"alternative_webui_path"))
677 pref->setWebUiRootFolder(it.value().toString());
679 if (hasKey(
"web_ui_clickjacking_protection_enabled"))
680 pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
681 if (hasKey(
"web_ui_csrf_protection_enabled"))
682 pref->setWebUiCSRFProtectionEnabled(it.value().toBool());
683 if (hasKey(
"web_ui_secure_cookie_enabled"))
684 pref->setWebUiSecureCookieEnabled(it.value().toBool());
685 if (hasKey(
"web_ui_host_header_validation_enabled"))
686 pref->setWebUIHostHeaderValidationEnabled(it.value().toBool());
688 if (hasKey(
"web_ui_use_custom_http_headers_enabled"))
689 pref->setWebUICustomHTTPHeadersEnabled(it.value().toBool());
690 if (hasKey(
"web_ui_custom_http_headers"))
691 pref->setWebUICustomHTTPHeaders(it.value().toString());
693 if (hasKey(
"web_ui_reverse_proxy_enabled"))
694 pref->setWebUIReverseProxySupportEnabled(it.value().toBool());
695 if (hasKey(
"web_ui_reverse_proxies_list"))
696 pref->setWebUITrustedReverseProxiesList(it.value().toString());
698 if (hasKey(
"dyndns_enabled"))
699 pref->setDynDNSEnabled(it.value().toBool());
700 if (hasKey(
"dyndns_service"))
701 pref->setDynDNSService(
static_cast<DNS::Service>(it.value().toInt()));
702 if (hasKey(
"dyndns_username"))
703 pref->setDynDNSUsername(it.value().toString());
704 if (hasKey(
"dyndns_password"))
705 pref->setDynDNSPassword(it.value().toString());
706 if (hasKey(
"dyndns_domain"))
707 pref->setDynDomainName(it.value().toString());
709 if (hasKey(
"rss_refresh_interval"))
711 if (hasKey(
"rss_max_articles_per_feed"))
713 if (hasKey(
"rss_processing_enabled"))
715 if (hasKey(
"rss_auto_downloading_enabled"))
717 if (hasKey(
"rss_download_repack_proper_episodes"))
719 if (hasKey(
"rss_smart_episode_filters"))
725 if (hasKey(
"current_network_interface"))
727 const QString ifaceValue {it.value().toString()};
729 const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
730 const auto ifacesIter = std::find_if(ifaces.cbegin(), ifaces.cend(), [&ifaceValue](
const QNetworkInterface &iface)
732 return (!iface.addressEntries().isEmpty()) && (iface.name() == ifaceValue);
734 const QString ifaceName = (ifacesIter != ifaces.cend()) ? ifacesIter->humanReadableName() : QString {};
736 session->setNetworkInterface(ifaceValue);
737 session->setNetworkInterfaceName(ifaceName);
740 if (hasKey(
"current_interface_address"))
742 const QHostAddress ifaceAddress {it.value().toString().trimmed()};
743 session->setNetworkInterfaceAddress(ifaceAddress.isNull() ? QString {} : ifaceAddress.toString());
746 if (hasKey(
"save_resume_data_interval"))
747 session->setSaveResumeDataInterval(it.value().toInt());
749 if (hasKey(
"recheck_completed_torrents"))
750 pref->recheckTorrentsOnCompletion(it.value().toBool());
752 if (hasKey(
"resolve_peer_countries"))
753 pref->resolvePeerCountries(it.value().toBool());
755 if (hasKey(
"reannounce_when_address_changed"))
756 session->setReannounceWhenAddressChangedEnabled(it.value().toBool());
760 if (hasKey(
"async_io_threads"))
761 session->setAsyncIOThreads(it.value().toInt());
763 if (hasKey(
"hashing_threads"))
764 session->setHashingThreads(it.value().toInt());
766 if (hasKey(
"file_pool_size"))
767 session->setFilePoolSize(it.value().toInt());
769 if (hasKey(
"checking_memory_use"))
770 session->setCheckingMemUsage(it.value().toInt());
772 if (hasKey(
"disk_cache"))
773 session->setDiskCacheSize(it.value().toInt());
774 if (hasKey(
"disk_cache_ttl"))
775 session->setDiskCacheTTL(it.value().toInt());
777 if (hasKey(
"enable_os_cache"))
778 session->setUseOSCache(it.value().toBool());
780 if (hasKey(
"enable_coalesce_read_write"))
781 session->setCoalesceReadWriteEnabled(it.value().toBool());
783 if (hasKey(
"enable_piece_extent_affinity"))
784 session->setPieceExtentAffinity(it.value().toBool());
786 if (hasKey(
"enable_upload_suggestions"))
787 session->setSuggestMode(it.value().toBool());
789 if (hasKey(
"send_buffer_watermark"))
790 session->setSendBufferWatermark(it.value().toInt());
791 if (hasKey(
"send_buffer_low_watermark"))
792 session->setSendBufferLowWatermark(it.value().toInt());
793 if (hasKey(
"send_buffer_watermark_factor"))
794 session->setSendBufferWatermarkFactor(it.value().toInt());
796 if (hasKey(
"connection_speed"))
797 session->setConnectionSpeed(it.value().toInt());
799 if (hasKey(
"socket_backlog_size"))
800 session->setSocketBacklogSize(it.value().toInt());
802 if (hasKey(
"outgoing_ports_min"))
803 session->setOutgoingPortsMin(it.value().toInt());
804 if (hasKey(
"outgoing_ports_max"))
805 session->setOutgoingPortsMax(it.value().toInt());
807 if (hasKey(
"upnp_lease_duration"))
808 session->setUPnPLeaseDuration(it.value().toInt());
810 if (hasKey(
"peer_tos"))
811 session->setPeerToS(it.value().toInt());
813 if (hasKey(
"utp_tcp_mixed_mode"))
816 if (hasKey(
"idn_support_enabled"))
817 session->setIDNSupportEnabled(it.value().toBool());
819 if (hasKey(
"enable_multi_connections_from_same_ip"))
820 session->setMultiConnectionsPerIpEnabled(it.value().toBool());
822 if (hasKey(
"validate_https_tracker_certificate"))
823 session->setValidateHTTPSTrackerCertificate(it.value().toBool());
825 if (hasKey(
"ssrf_mitigation"))
826 session->setSSRFMitigationEnabled(it.value().toBool());
828 if (hasKey(
"block_peers_on_privileged_ports"))
829 session->setBlockPeersOnPrivilegedPorts(it.value().toBool());
831 if (hasKey(
"embedded_tracker_port"))
832 pref->setTrackerPort(it.value().toInt());
833 if (hasKey(
"enable_embedded_tracker"))
834 session->setTrackerEnabled(it.value().toBool());
836 if (hasKey(
"upload_slots_behavior"))
839 if (hasKey(
"upload_choking_algorithm"))
842 if (hasKey(
"announce_to_all_trackers"))
843 session->setAnnounceToAllTrackers(it.value().toBool());
844 if (hasKey(
"announce_to_all_tiers"))
845 session->setAnnounceToAllTiers(it.value().toBool());
846 if (hasKey(
"announce_ip"))
848 const QHostAddress announceAddr {it.value().toString().trimmed()};
849 session->setAnnounceIP(announceAddr.isNull() ? QString {} : announceAddr.toString());
851 if (hasKey(
"max_concurrent_http_announces"))
852 session->setMaxConcurrentHTTPAnnounces(it.value().toInt());
853 if (hasKey(
"stop_tracker_timeout"))
854 session->setStopTrackerTimeout(it.value().toInt());
856 if (hasKey(
"peer_turnover"))
857 session->setPeerTurnover(it.value().toInt());
858 if (hasKey(
"peer_turnover_cutoff"))
859 session->setPeerTurnoverCutoff(it.value().toInt());
860 if (hasKey(
"peer_turnover_interval"))
861 session->setPeerTurnoverInterval(it.value().toInt());
874 QJsonArray ifaceList;
875 for (
const QNetworkInterface &iface :
asConst(QNetworkInterface::allInterfaces()))
877 if (!iface.addressEntries().isEmpty())
879 ifaceList.append(QJsonObject
881 {
"name", iface.humanReadableName()},
882 {
"value", iface.name()}
894 const QString ifaceName =
params().value(
"iface");
895 QJsonArray addressList;
897 const auto appendAddress = [&addressList](
const QHostAddress &addr)
899 if (addr.protocol() == QAbstractSocket::IPv6Protocol)
902 addressList.append(addr.toString());
905 if (ifaceName.isEmpty())
907 for (
const QHostAddress &addr :
asConst(QNetworkInterface::allAddresses()))
912 const QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName);
913 for (
const QNetworkAddressEntry &entry :
asConst(iface.addressEntries()))
914 appendAddress(entry.ip());
void requireParams(const QVector< QString > &requiredParams) const
const StringMap & params() const
const DataMap & data() const
void setResult(const QString &result)
void defaultSavePathAction()
void networkInterfaceAddressListAction()
void webapiVersionAction()
void networkInterfaceListAction()
void setPreferencesAction()
static Session * instance()
QString networkInterfaceAddress() const
static PortForwarder * instance()
virtual void setEnabled(bool enabled)=0
virtual bool isEnabled() const =0
static ProxyConfigurationManager * instance()
QString getMailNotificationSMTPUsername() const
QString getWebUICustomHTTPHeaders() const
QString getMailNotificationSMTPPassword() const
bool resolvePeerCountries() const
QString getAutoRunProgram() const
static Preferences * instance()
int getWebUIMaxAuthFailCount() const
QString getWebUiRootFolder() const
QString getWebUIHttpsCertificatePath() const
int getTrackerPort() const
std::chrono::seconds getWebUIBanDuration() const
QString getMailNotificationEmail() const
bool isWebUiLocalAuthEnabled() const
QString getWebUiAddress() const
bool getMailNotificationSMTPAuth() const
bool isWebUiSecureCookieEnabled() const
QString getDynDNSUsername() const
QString getMailNotificationSender() const
bool getMailNotificationSMTPSSL() const
QString getDynDNSPassword() const
bool isWebUIHostHeaderValidationEnabled() const
QTime getSchedulerStartTime() const
bool useUPnPForWebUIPort() const
bool isAltWebUiEnabled() const
bool isWebUiAuthSubnetWhitelistEnabled() const
QString getWebUITrustedReverseProxiesList() const
bool recheckTorrentsOnCompletion() const
QTime getSchedulerEndTime() const
bool isWebUICustomHTTPHeadersEnabled() const
bool isWebUiClickjackingProtectionEnabled() const
DNS::Service getDynDNSService() const
bool isDynDNSEnabled() const
QString getLocale() const
quint16 getWebUiPort() const
bool isWebUiCSRFProtectionEnabled() const
bool isWebUIReverseProxySupportEnabled() const
QString getWebUiUsername() const
Scheduler::Days getSchedulerDays() const
QString getServerDomains() const
QString getMailNotificationSMTP() const
int getWebUISessionTimeout() const
QVector< Utils::Net::Subnet > getWebUiAuthSubnetWhitelist() const
bool isMailNotificationEnabled() const
bool isWebUiHttpsEnabled() const
bool isAutoRunEnabled() const
QString getDynDomainName() const
QString getWebUIHttpsKeyPath() const
void setDownloadRepacks(bool enabled)
bool isProcessingEnabled() const
bool downloadRepacks() const
void setSmartEpisodeFilters(const QStringList &filters)
static AutoDownloader * instance()
QStringList smartEpisodeFilters() const
void setProcessingEnabled(bool enabled)
int refreshInterval() const
bool isProcessingEnabled() const
static Session * instance()
int maxArticlesPerFeed() const
void setRefreshInterval(int refreshInterval)
void setMaxArticlesPerFeed(int n)
void setProcessingEnabled(bool enabled)
static AutoDeleteMode autoDeleteMode()
static void setAutoDeleteMode(AutoDeleteMode mode)
void removeWatchedFolder(const QString &path)
QHash< QString, WatchedFolderOptions > folders() const
static TorrentFilesWatcher * instance()
static QString makeCleanPath(const QString &path)
void setWatchedFolder(const QString &path, const WatchedFolderOptions &options)
constexpr std::add_const_t< T > & asConst(T &t) noexcept
QString toNativePath(const QString &path)
QString libtorrentVersionString()
QString opensslVersionString()
QString boostVersionString()
QString zlibVersionString()
QString subnetToString(const Subnet &subnet)
QHostAddress canonicalIPv6Addr(const QHostAddress &addr)
QPair< QHostAddress, int > Subnet
QByteArray generate(const QString &password)
QString fromEnum(const T &value)
T toEnum(const QString &serializedValue, const T &defaultValue)
BitTorrent::AddTorrentParams addTorrentParams
const Utils::Version< int, 3, 2 > API_VERSION