qBittorrent/src/webui/httpconnection.cpp

655 lines
22 KiB
C++
Raw Normal View History

/*
2009-04-05 22:48:45 +04:00
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Ishan Arora and Christophe Dumez
*
2009-04-05 22:48:45 +04:00
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
2009-04-05 22:48:45 +04:00
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
2009-04-05 22:48:45 +04:00
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*
* Contact : chris@qbittorrent.org
*/
#include "httpconnection.h"
#include "httpserver.h"
#include "eventmanager.h"
#include "preferences.h"
#include "json.h"
#include "qbtsession.h"
#include "misc.h"
#ifndef DISABLE_GUI
#include "iconprovider.h"
#endif
#include <QTcpSocket>
#include <QDateTime>
#include <QStringList>
#include <QHttpRequestHeader>
#include <QHttpResponseHeader>
#include <QFile>
#include <QDebug>
#include <QRegExp>
#include <QTemporaryFile>
#include <queue>
#include <vector>
using namespace libtorrent;
2010-11-14 00:15:52 +03:00
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
2011-09-25 12:18:41 +04:00
: QObject(parent), m_socket(socket), m_httpserver(parent)
{
2011-09-25 12:18:41 +04:00
m_socket->setParent(this);
connect(m_socket, SIGNAL(readyRead()), SLOT(read()));
connect(m_socket, SIGNAL(disconnected()), SLOT(deleteLater()));
}
2011-09-25 12:42:03 +04:00
HttpConnection::~HttpConnection() {
2011-09-25 12:18:41 +04:00
delete m_socket;
}
2011-09-25 12:18:41 +04:00
void HttpConnection::processDownloadedFile(const QString &url,
const QString &file_path) {
qDebug("URL %s successfully downloaded !", qPrintable(url));
2009-08-21 18:05:03 +04:00
emit torrentReadyToBeDownloaded(file_path, false, url, false);
}
2011-09-25 12:18:41 +04:00
void HttpConnection::handleDownloadFailure(const QString& url,
const QString& reason) {
std::cerr << "Could not download " << qPrintable(url) << ", reason: "
<< qPrintable(reason) << std::endl;
}
2011-09-25 12:18:41 +04:00
void HttpConnection::read() {
QByteArray input = m_socket->readAll();
// Parse HTTP request header
int header_end = input.indexOf("\r\n\r\n");
2011-10-02 00:37:30 +04:00
if (header_end < 0) {
qDebug() << Q_FUNC_INFO << "missing double-CRLF";
m_generator.setStatusLine(400, "Bad Request");
write();
return;
}
QByteArray header = input.left(header_end);
m_parser.writeHeader(header);
if (m_parser.isError()) {
2011-10-02 00:37:30 +04:00
qDebug() << Q_FUNC_INFO << "header parsing error";
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(400, "Bad Request");
2009-08-21 18:05:03 +04:00
write();
return;
}
// Parse HTTP request message
if (m_parser.header().hasContentLength()) {
QByteArray message = input.mid(header_end + 4);
int expected_length = m_parser.header().contentLength();
if (expected_length > 100000) {
m_generator.setStatusLine(400, "Bad Request");
write();
return;
}
bool is_reading = true;
while (message.length() < expected_length && is_reading) {
disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(read()));
is_reading = m_socket->waitForReadyRead(2000);
if (is_reading) {
message.append(m_socket->readAll());
}
connect(m_socket, SIGNAL(readyRead()), this, SLOT(read()));
}
m_parser.writeMessage(message);
}
2011-09-25 12:29:29 +04:00
if(m_parser.isError()) {
2011-10-02 00:37:30 +04:00
qDebug() << Q_FUNC_INFO << "message parsing error";
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(400, "Bad Request");
2009-08-21 18:05:03 +04:00
write();
2011-09-25 12:29:29 +04:00
} else {
respond();
2011-09-25 12:29:29 +04:00
}
}
2011-09-25 12:29:29 +04:00
void HttpConnection::write() {
m_socket->write(m_generator.toByteArray());
2011-09-25 12:18:41 +04:00
m_socket->disconnectFromHost();
}
void HttpConnection::translateDocument(QString& data) {
static QRegExp regex(QString::fromUtf8("_\\(([\\w\\s?!:\\/\\(\\),%µ&\\-\\.]+)\\)"));
static QRegExp mnemonic("\\(?&([a-zA-Z]?\\))?");
2011-09-25 15:37:04 +04:00
const std::string contexts[] = {"TransferListFiltersWidget", "TransferListWidget",
2011-09-25 17:22:56 +04:00
"PropertiesWidget", "MainWindow", "HttpServer",
"confirmDeletionDlg", "TrackerList", "TorrentFilesModel",
"options_imp", "Preferences", "TrackersAdditionDlg",
"ScanFoldersModel", "PropTabBar", "TorrentModel",
"downloadFromURL"};
2011-09-25 12:29:29 +04:00
int i = 0;
bool found;
do {
found = false;
i = regex.indexIn(data, i);
if(i >= 0) {
//qDebug("Found translatable string: %s", regex.cap(1).toUtf8().data());
QByteArray word = regex.cap(1).toLocal8Bit();
QString translation = word;
2011-09-29 21:47:51 +04:00
if (m_httpserver->isTranslationNeeded()) {
int context_index = 0;
do {
translation = qApp->translate(contexts[context_index].c_str(), word.constData(), 0, QCoreApplication::UnicodeUTF8, 1);
++context_index;
} while(translation == word && context_index < 15);
}
2010-06-29 12:08:43 +04:00
// Remove keyboard shortcuts
2011-09-25 15:39:01 +04:00
translation.replace(mnemonic, "");
data.replace(i, regex.matchedLength(), translation);
i += translation.length();
found = true;
}
} while(found && i < data.size());
}
void HttpConnection::respond() {
2011-09-25 12:29:29 +04:00
if((m_socket->peerAddress() != QHostAddress::LocalHost
&& m_socket->peerAddress() != QHostAddress::LocalHostIPv6)
|| m_httpserver->isLocalAuthEnabled()) {
// Authentication
2011-09-25 12:18:41 +04:00
const QString peer_ip = m_socket->peerAddress().toString();
const int nb_fail = m_httpserver->NbFailedAttemptsForIp(peer_ip);
if(nb_fail >= MAX_AUTH_FAILED_ATTEMPTS) {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(403, "Forbidden");
m_generator.setMessage(tr("Your IP address has been banned after too many failed authentication attempts."));
write();
return;
}
2011-09-25 18:26:02 +04:00
QString auth = m_parser.header().value("Authorization");
if(auth.isEmpty()) {
// Return unauthorized header
qDebug("Auth is Empty...");
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(401, "Unauthorized");
m_generator.setValue("WWW-Authenticate", "Digest realm=\""+QString(QBT_REALM)+"\", nonce=\""+m_httpserver->generateNonce()+"\", opaque=\""+m_httpserver->generateNonce()+"\", stale=\"false\", algorithm=\"MD5\", qop=\"auth\"");
write();
return;
}
//qDebug("Auth: %s", qPrintable(auth.split(" ").first()));
2011-09-25 17:20:28 +04:00
if (QString::compare(auth.split(" ").first(), "Digest", Qt::CaseInsensitive) != 0
2011-09-25 18:26:02 +04:00
|| !m_httpserver->isAuthorized(auth.toLocal8Bit(), m_parser.header().method())) {
// Update failed attempt counter
2011-09-25 12:18:41 +04:00
m_httpserver->increaseNbFailedAttemptsForIp(peer_ip);
2011-09-25 17:20:28 +04:00
qDebug("client IP: %s (%d failed attempts)", qPrintable(peer_ip), nb_fail);
// Return unauthorized header
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(401, "Unauthorized");
m_generator.setValue("WWW-Authenticate", "Digest realm=\""+QString(QBT_REALM)+"\", nonce=\""+m_httpserver->generateNonce()+"\", opaque=\""+m_httpserver->generateNonce()+"\", stale=\"false\", algorithm=\"MD5\", qop=\"auth\"");
write();
return;
}
// Client successfully authenticated, reset number of failed attempts
2011-09-25 12:18:41 +04:00
m_httpserver->resetNbFailedAttemptsForIp(peer_ip);
2009-08-21 18:05:03 +04:00
}
2011-09-25 12:18:41 +04:00
QString url = m_parser.url();
2010-01-14 15:37:19 +03:00
// Favicon
if(url.endsWith("favicon.ico")) {
qDebug("Returning favicon");
QFile favicon(":/Icons/skin/qbittorrent16.png");
if(favicon.open(QIODevice::ReadOnly)) {
QByteArray data = favicon.readAll();
2011-09-25 17:20:28 +04:00
favicon.close();
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("png");
m_generator.setMessage(data);
2010-01-14 15:37:19 +03:00
write();
} else {
respondNotFound();
}
return;
}
2011-09-25 12:29:29 +04:00
2009-08-21 18:05:03 +04:00
QStringList list = url.split('/', QString::SkipEmptyParts);
2011-09-25 12:29:29 +04:00
if (list.contains(".") || list.contains("..")) {
2009-08-21 18:05:03 +04:00
respondNotFound();
return;
}
2011-09-25 12:29:29 +04:00
if (list.isEmpty())
2009-08-21 18:05:03 +04:00
list.append("index.html");
2011-09-25 12:29:29 +04:00
if (list.size() >= 2) {
if (list[0] == "json") {
if (list[1] == "events") {
2009-08-21 18:05:03 +04:00
respondJson();
return;
}
if(list.size() > 2) {
if(list[1] == "propertiesGeneral") {
2011-09-25 12:29:29 +04:00
const QString& hash = list[2];
respondGenPropertiesJson(hash);
return;
}
if(list[1] == "propertiesTrackers") {
2011-09-25 12:29:29 +04:00
const QString& hash = list[2];
respondTrackersPropertiesJson(hash);
return;
}
2009-11-24 16:10:17 +03:00
if(list[1] == "propertiesFiles") {
2011-09-25 12:29:29 +04:00
const QString& hash = list[2];
2009-11-24 16:10:17 +03:00
respondFilesPropertiesJson(hash);
return;
}
} else {
if(list[1] == "preferences") {
respondPreferencesJson();
2010-12-13 21:22:19 +03:00
return;
} else {
if(list[1] == "transferInfo") {
respondGlobalTransferInfoJson();
2010-12-13 21:22:19 +03:00
return;
}
}
}
2009-08-21 18:05:03 +04:00
}
2011-09-25 12:29:29 +04:00
if (list[0] == "command") {
2011-09-25 12:31:20 +04:00
const QString& command = list[1];
2009-08-21 18:05:03 +04:00
respondCommand(command);
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
2009-08-21 18:05:03 +04:00
write();
return;
}
}
2011-09-25 12:29:29 +04:00
2010-12-13 21:22:19 +03:00
// Icons from theme
qDebug() << "list[0]" << list[0];
if(list[0] == "theme" && list.size() == 2) {
#ifdef DISABLE_GUI
url = ":/Icons/oxygen/"+list[1]+".png";
#else
url = IconProvider::instance()->getIconPath(list[1]);
#endif
2010-12-13 21:22:19 +03:00
qDebug() << "There icon:" << url;
} else {
2010-12-13 21:22:19 +03:00
if (list[0] == "images") {
list[0] = "Icons";
} else {
if(list.last().endsWith(".html"))
list.prepend("html");
list.prepend("webui");
}
url = ":/" + list.join("/");
}
2009-08-21 18:05:03 +04:00
QFile file(url);
2011-09-25 17:20:28 +04:00
if(!file.open(QIODevice::ReadOnly)) {
2010-06-17 15:55:47 +04:00
qDebug("File %s was not found!", qPrintable(url));
2009-08-21 18:05:03 +04:00
respondNotFound();
return;
}
QString ext = list.last();
int index = ext.lastIndexOf('.') + 1;
if (index > 0)
ext.remove(0, index);
else
ext.clear();
QByteArray data = file.readAll();
2011-09-25 17:20:28 +04:00
file.close();
// Translate the page
if(ext == "html" || (ext == "js" && !list.last().startsWith("excanvas"))) {
QString dataStr = QString::fromUtf8(data.constData());
translateDocument(dataStr);
if (url.endsWith("about.html")) {
dataStr.replace("${VERSION}", VERSION);
}
data = dataStr.toUtf8();
}
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt(ext);
m_generator.setMessage(data);
2009-08-21 18:05:03 +04:00
write();
}
2011-09-25 17:20:28 +04:00
void HttpConnection::respondNotFound() {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(404, "File not found");
2009-08-21 18:05:03 +04:00
write();
}
2011-09-25 17:20:28 +04:00
void HttpConnection::respondJson() {
2011-09-25 12:18:41 +04:00
EventManager* manager = m_httpserver->eventManager();
2009-08-21 18:05:03 +04:00
QString string = json::toJson(manager->getEventList());
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
2009-08-21 18:05:03 +04:00
write();
}
2011-09-25 12:29:29 +04:00
void HttpConnection::respondGenPropertiesJson(const QString& hash) {
2011-09-25 12:18:41 +04:00
EventManager* manager = m_httpserver->eventManager();
QString string = json::toJson(manager->getPropGeneralInfo(hash));
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
write();
}
2011-09-25 12:29:29 +04:00
void HttpConnection::respondTrackersPropertiesJson(const QString& hash) {
2011-09-25 12:18:41 +04:00
EventManager* manager = m_httpserver->eventManager();
QString string = json::toJson(manager->getPropTrackersInfo(hash));
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
write();
}
2011-09-25 12:29:29 +04:00
void HttpConnection::respondFilesPropertiesJson(const QString& hash) {
2011-09-25 12:18:41 +04:00
EventManager* manager = m_httpserver->eventManager();
2009-11-24 16:10:17 +03:00
QString string = json::toJson(manager->getPropFilesInfo(hash));
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
2009-11-24 16:10:17 +03:00
write();
}
void HttpConnection::respondPreferencesJson() {
2011-09-25 12:18:41 +04:00
EventManager* manager = m_httpserver->eventManager();
QString string = json::toJson(manager->getGlobalPreferences());
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
write();
}
void HttpConnection::respondGlobalTransferInfoJson() {
QVariantMap info;
2010-11-14 00:15:52 +03:00
session_status sessionStatus = QBtSession::instance()->getSessionStatus();
info["DlInfos"] = tr("D: %1/s - T: %2", "Download speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_download_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_download));
info["UpInfos"] = tr("U: %1/s - T: %2", "Upload speed: x KiB/s - Transferred: x MiB").arg(misc::friendlyUnit(sessionStatus.payload_upload_rate)).arg(misc::friendlyUnit(sessionStatus.total_payload_upload));
QString string = json::toJson(info);
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("js");
m_generator.setMessage(string);
write();
}
2011-09-25 17:20:28 +04:00
void HttpConnection::respondCommand(const QString& command) {
2011-09-25 12:31:20 +04:00
if(command == "download") {
2011-09-25 12:18:41 +04:00
QString urls = m_parser.post("urls");
2009-08-21 18:05:03 +04:00
QStringList list = urls.split('\n');
foreach(QString url, list){
url = url.trimmed();
if(!url.isEmpty()){
if(url.startsWith("bc://bt/", Qt::CaseInsensitive)) {
qDebug("Converting bc link to magnet link");
url = misc::bcLinkToMagnet(url);
}
2009-08-21 18:05:03 +04:00
if(url.startsWith("magnet:", Qt::CaseInsensitive)) {
emit MagnetReadyToBeDownloaded(url);
} else {
qDebug("Downloading url: %s", (const char*)url.toLocal8Bit());
emit UrlReadyToBeDownloaded(url);
2008-12-30 01:46:18 +03:00
}
2009-08-21 18:05:03 +04:00
}
}
return;
}
2011-09-25 12:31:20 +04:00
if(command == "addTrackers") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
if(!hash.isEmpty()) {
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid() && h.has_metadata()) {
2011-09-25 12:18:41 +04:00
QString urls = m_parser.post("urls");
QStringList list = urls.split('\n');
2011-09-25 17:20:28 +04:00
foreach(const QString& url, list) {
announce_entry e(url.toStdString());
h.add_tracker(e);
}
}
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "upload") {
qDebug() << Q_FUNC_INFO << "upload";
// Get a unique filename
2011-02-22 21:37:56 +03:00
// XXX: We need to use a QTemporaryFile pointer here
// and it fails on Windows.
// The file also needs to end with .torrent otherwise
// it fails to load on Windows.
QTemporaryFile *tmpfile = new QTemporaryFile (QDir::temp().absoluteFilePath("qBT-XXXXXX.torrent"));
if (tmpfile->open()) {
2011-09-25 12:18:41 +04:00
tmpfile->write(m_parser.torrent());
tmpfile->close();
emit torrentReadyToBeDownloaded(tmpfile->fileName(), false, QString(), false);
2011-09-30 21:51:29 +04:00
tmpfile->deleteLater();
} else {
std::cerr << "I/O Error: Could not create temporary file" << std::endl;
delete tmpfile;
return;
2009-08-21 18:05:03 +04:00
}
// Prepare response
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("html");
m_generator.setMessage(QString("<script type=\"text/javascript\">window.parent.hideAll();</script>"));
write();
2009-08-21 18:05:03 +04:00
return;
}
if(command == "resumeall") {
emit resumeAllTorrents();
return;
}
if(command == "pauseall") {
emit pauseAllTorrents();
return;
}
if(command == "resume") {
2011-09-25 12:18:41 +04:00
emit resumeTorrent(m_parser.post("hash"));
2009-08-21 18:05:03 +04:00
return;
}
if(command == "setPreferences") {
2011-09-25 12:18:41 +04:00
QString json_str = m_parser.post("json");
EventManager* manager = m_httpserver->eventManager();
manager->setGlobalPreferences(json::fromJson(json_str));
2011-09-25 17:20:28 +04:00
return;
}
if(command == "setFilePrio") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
int file_id = m_parser.post("id").toInt();
int priority = m_parser.post("priority").toInt();
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid() && h.has_metadata()) {
h.file_priority(file_id, priority);
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "getGlobalUpLimit") {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("html");
2011-04-17 14:29:44 +04:00
#if LIBTORRENT_VERSION_MINOR > 15
2011-09-25 12:31:20 +04:00
m_generator.setMessage(QString::number(QBtSession::instance()->getSession()->settings().upload_rate_limit));
2011-04-17 14:29:44 +04:00
#else
2011-09-25 12:18:41 +04:00
m_generator.setMessage(QString::number(QBtSession::instance()->getSession()->upload_rate_limit()));
2011-04-17 14:29:44 +04:00
#endif
write();
2011-09-25 17:20:28 +04:00
return;
}
if(command == "getGlobalDlLimit") {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("html");
2011-04-17 14:29:44 +04:00
#if LIBTORRENT_VERSION_MINOR > 15
2011-09-25 12:31:20 +04:00
m_generator.setMessage(QString::number(QBtSession::instance()->getSession()->settings().download_rate_limit));
2011-04-17 14:29:44 +04:00
#else
2011-09-25 12:18:41 +04:00
m_generator.setMessage(QString::number(QBtSession::instance()->getSession()->download_rate_limit()));
2011-04-17 14:29:44 +04:00
#endif
write();
2011-09-25 17:20:28 +04:00
return;
}
if(command == "getTorrentUpLimit") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("html");
m_generator.setMessage(QString::number(h.upload_limit()));
write();
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "getTorrentDlLimit") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) {
2011-09-25 12:18:41 +04:00
m_generator.setStatusLine(200, "OK");
m_generator.setContentTypeByExt("html");
m_generator.setMessage(QString::number(h.download_limit()));
write();
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "setTorrentUpLimit") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
qlonglong limit = m_parser.post("limit").toLongLong();
if(limit == 0) limit = -1;
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) {
h.set_upload_limit(limit);
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "setTorrentDlLimit") {
2011-09-25 12:18:41 +04:00
QString hash = m_parser.post("hash");
qlonglong limit = m_parser.post("limit").toLongLong();
if(limit == 0) limit = -1;
2010-11-14 00:15:52 +03:00
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) {
h.set_download_limit(limit);
}
2011-09-25 17:20:28 +04:00
return;
}
if(command == "setGlobalUpLimit") {
2011-09-25 12:18:41 +04:00
qlonglong limit = m_parser.post("limit").toLongLong();
if(limit == 0) limit = -1;
2011-04-17 14:29:44 +04:00
QBtSession::instance()->setUploadRateLimit(limit);
Preferences().setGlobalUploadLimit(limit/1024.);
2011-09-25 17:20:28 +04:00
return;
}
if(command == "setGlobalDlLimit") {
2011-09-25 12:18:41 +04:00
qlonglong limit = m_parser.post("limit").toLongLong();
if(limit == 0) limit = -1;
2011-04-17 14:29:44 +04:00
QBtSession::instance()->setDownloadRateLimit(limit);
Preferences().setGlobalDownloadLimit(limit/1024.);
2011-09-25 17:20:28 +04:00
return;
}
2009-08-21 18:05:03 +04:00
if(command == "pause") {
2011-09-25 12:18:41 +04:00
emit pauseTorrent(m_parser.post("hash"));
2009-08-21 18:05:03 +04:00
return;
}
if(command == "delete") {
2011-09-25 12:18:41 +04:00
QStringList hashes = m_parser.post("hashes").split("|");
2011-01-06 12:16:02 +03:00
foreach(const QString &hash, hashes) {
emit deleteTorrent(hash, false);
}
2009-08-21 18:05:03 +04:00
return;
}
if(command == "deletePerm") {
2011-09-25 12:18:41 +04:00
QStringList hashes = m_parser.post("hashes").split("|");
2011-01-06 12:16:02 +03:00
foreach(const QString &hash, hashes) {
emit deleteTorrent(hash, true);
}
2009-08-21 18:05:03 +04:00
return;
}
if(command == "increasePrio") {
2011-09-25 12:18:41 +04:00
increaseTorrentsPriority(m_parser.post("hashes").split("|"));
2009-08-21 18:05:03 +04:00
return;
}
if(command == "decreasePrio") {
2011-09-25 12:18:41 +04:00
decreaseTorrentsPriority(m_parser.post("hashes").split("|"));
2009-08-21 18:05:03 +04:00
return;
}
if(command == "topPrio") {
2011-09-25 12:18:41 +04:00
foreach(const QString &hash, m_parser.post("hashes").split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) h.queue_position_top();
}
return;
}
if(command == "bottomPrio") {
2011-09-25 12:18:41 +04:00
foreach(const QString &hash, m_parser.post("hashes").split("|")) {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(h.is_valid()) h.queue_position_bottom();
}
return;
}
if(command == "recheck"){
2011-09-25 18:26:02 +04:00
QBtSession::instance()->recheckTorrent(m_parser.post("hash"));
return;
}
}
2011-09-25 18:26:02 +04:00
void HttpConnection::decreaseTorrentsPriority(const QStringList &hashes) {
qDebug() << Q_FUNC_INFO << hashes;
2011-09-25 18:26:02 +04:00
std::priority_queue<QPair<int, QTorrentHandle>,
std::vector<QPair<int, QTorrentHandle> >,
std::less<QPair<int, QTorrentHandle> > > torrent_queue;
// Sort torrents by priority
foreach(const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(!h.is_seed()) {
torrent_queue.push(qMakePair(h.queue_position(), h));
}
}catch(invalid_handle&){}
}
// Decrease torrents priority (starting with the ones with lowest priority)
while(!torrent_queue.empty()) {
QTorrentHandle h = torrent_queue.top().second;
try {
h.queue_position_down();
} catch(invalid_handle& h) {}
torrent_queue.pop();
}
}
void HttpConnection::increaseTorrentsPriority(const QStringList &hashes)
{
qDebug() << Q_FUNC_INFO << hashes;
2011-09-25 18:26:02 +04:00
std::priority_queue<QPair<int, QTorrentHandle>,
std::vector<QPair<int, QTorrentHandle> >,
std::greater<QPair<int, QTorrentHandle> > > torrent_queue;
// Sort torrents by priority
foreach(const QString &hash, hashes) {
try {
QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash);
if(!h.is_seed()) {
torrent_queue.push(qMakePair(h.queue_position(), h));
}
}catch(invalid_handle&){}
}
// Increase torrents priority (starting with the ones with highest priority)
while(!torrent_queue.empty()) {
QTorrentHandle h = torrent_queue.top().second;
try {
h.queue_position_up();
} catch(invalid_handle& h) {}
torrent_queue.pop();
}
}