Commit f1df0ea6 authored by Joris Guisson's avatar Joris Guisson
Browse files

Backport QHttp based announce from trunk

svn path=/branches/stable/extragear-kde4/network/ktorrent/; revision=975631
parents 8b04d85f d2071717
......@@ -17,6 +17,7 @@ Changes in 3.2.2 :
- Properly check for GeoIP system library (193117)
- Fix crash at exit caused by stopping torrent in it's destructor (193585)
- No longer check if a torrent has to have an announce or a nodes key
- Added experimental option which replaces KIO to announce with a QHttp based solution, this fixes connection to host broken errors
Changes in 3.2.1 :
- Resort torrents if display name is changed
......
This diff is collapsed.
......@@ -161,6 +161,7 @@ set(libbtcore_SRC
tracker/tracker.cpp
tracker/udptracker.cpp
tracker/udptrackersocket.cpp
tracker/httpannouncejob.cpp
datachecker/datachecker.cpp
datachecker/datacheckerthread.cpp
......
......@@ -525,12 +525,14 @@ namespace bt
{
tor->load(torrent,false);
}
catch (...)
catch (bt::Error & err)
{
Out(SYS_GEN|LOG_NOTICE) << "Failed to load torrent: " << err.toString() << endl;
delete tor;
tor = 0;
throw Error(i18n("An error occurred while loading the torrent <b>%1</b>\n"
"The torrent is probably corrupt or is not a torrent file.",torrent));
throw Error(i18n("An error occurred while loading the torrent <b>%1</b>:<br/>"
"<b>%2</b><br/>"
"The torrent is probably corrupt or is not a valid torrent file.",torrent,err.toString()));
}
initInternal(qman,tmpdir,ddir,default_save_dir,torrent.startsWith(tmpdir));
......@@ -553,12 +555,14 @@ namespace bt
{
tor->load(data,false);
}
catch (...)
catch (bt::Error & err)
{
Out(SYS_GEN|LOG_NOTICE) << "Failed to load torrent: " << err.toString() << endl;
delete tor;
tor = 0;
throw Error(i18n("An error occurred while loading the torrent.\n"
"The torrent is probably corrupt or is not a torrent file."));
throw Error(i18n("An error occurred while loading the torrent:<br/>"
"<b>%1</b><br/>"
"The torrent is probably corrupt or is not a valid torrent file.",err.toString()));
}
initInternal(qman,tmpdir,ddir,default_save_dir,true);
......
/*
Copyright (C) 2009 by Joris Guisson (joris.guisson@gmail.com)
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.
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.
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.
*/
#include "httpannouncejob.h"
#include <btversion.h>
namespace bt
{
HTTPAnnounceJob::HTTPAnnounceJob(const KUrl& url) : url(url),get_id(0),proxy_port(-1)
{
output.setBuffer(&reply_data);
http = new QHttp(this);
connect(http,SIGNAL(requestFinished(int,bool)),this,SLOT(requestFinished(int,bool)));
}
HTTPAnnounceJob::~HTTPAnnounceJob()
{
}
void HTTPAnnounceJob::start()
{
http->setHost(url.host(),url.protocol() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp,url.port());
if (!proxy_host.isEmpty() && proxy_port > 0)
http->setProxy(proxy_host,proxy_port);
QHttpRequestHeader hdr("GET",url.encodedPathAndQuery(),1,1);
hdr.setValue("User-Agent",bt::GetVersionString());
hdr.setValue("Connection","close");
hdr.setValue("Host",QString("%1:%2").arg(url.host()).arg(url.port(80)));
get_id = http->request(hdr,0,&output);
}
void HTTPAnnounceJob::kill(bool quietly)
{
http->abort();
if (!quietly)
emitResult();
}
void HTTPAnnounceJob::requestFinished(int id, bool err)
{
if (get_id != id)
return;
if (err)
{
setErrorText(http->errorString());
}
else
{
switch (http->lastResponse().statusCode())
{
case 403:
setError(KIO::ERR_ACCESS_DENIED);
break;
case 404:
setError(KIO::ERR_DOES_NOT_EXIST);
break;
case 500:
setError(KIO::ERR_INTERNAL_SERVER);
break;
}
}
emitResult();
}
void HTTPAnnounceJob::setProxy(const QString& host, int port)
{
proxy_host = host;
proxy_port = port;
}
}
\ No newline at end of file
/*
Copyright (C) 2009 by Joris Guisson (joris.guisson@gmail.com)
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.
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.
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.
*/
#ifndef BT_HTTPANNOUNCEJOB_H
#define BT_HTTPANNOUNCEJOB_H
#include <kio/jobclasses.h>
#include <QHttp>
#include <QBuffer>
namespace bt
{
/**
KIO::Job which uses QHttp to announce to a tracker.
This was added because KIO doesn't handle the (invalid)http of some trackers in a consistent manner.
*/
class HTTPAnnounceJob : public KIO::Job
{
Q_OBJECT
public:
HTTPAnnounceJob(const KUrl & url);
virtual ~HTTPAnnounceJob();
/**
Set the proxy to use.
@param host The proxy hostname or IP
@param port The port of the proxy
*/
void setProxy(const QString & host,int port);
/// Get the announce url
KUrl announceUrl() const {return url;}
/// Get the reply data
QByteArray replyData() const {return reply_data;}
virtual void start();
virtual void kill(bool quietly=true);
private slots:
void requestFinished(int id,bool err);
private:
KUrl url;
QHttp* http;
QByteArray reply_data;
QBuffer output;
int get_id;
QString proxy_host;
int proxy_port;
};
}
#endif // BT_HTTPANNOUNCEJOB_H
......@@ -39,6 +39,8 @@
#include <torrent/server.h>
#include <torrent/globals.h>
#include "btversion.h"
#include "httpannouncejob.h"
#include <kprotocolmanager.h>
......@@ -47,6 +49,7 @@ namespace bt
bool HTTPTracker::proxy_on = false;
QString HTTPTracker::proxy = QString();
Uint16 HTTPTracker::proxy_port = 8080;
bool HTTPTracker::use_qhttp = false;
HTTPTracker::HTTPTracker(const KUrl & url,TorrentInterface* tor,const PeerID & id,int tier)
: Tracker(url,tor,id,tier)
......@@ -56,9 +59,9 @@ namespace bt
interval = 5 * 60; // default interval 5 minutes
failures = 0;
seeders = leechers = 0;
}
HTTPTracker::~HTTPTracker()
{
}
......@@ -256,7 +259,7 @@ namespace bt
Out(SYS_TRK|LOG_DEBUG) << QString(data) << endl;
#endif
// search for dictionary, there might be random garbage infront of the data
Uint32 i = 0;
int i = 0;
while (i < data.size())
{
if (data[i] == 'd')
......@@ -332,7 +335,7 @@ namespace bt
}
QByteArray arr = vn->data().toByteArray();
for (Uint32 i = 0;i < arr.size();i+=6)
for (int i = 0;i < arr.size();i+=6)
{
Uint8 buf[6];
for (int j = 0;j < 6;j++)
......@@ -372,7 +375,7 @@ namespace bt
if (vn && vn->data().getType() == Value::STRING)
{
QByteArray arr = vn->data().toByteArray();
for (Uint32 i = 0;i < arr.size();i+=18)
for (int i = 0;i < arr.size();i+=18)
{
Uint8 buf[18];
for (int j = 0;j < 18;j++)
......@@ -387,18 +390,29 @@ namespace bt
delete n;
return true;
}
void HTTPTracker::onAnnounceResult(KJob* j)
void HTTPTracker::onKIOAnnounceResult(KJob* j)
{
if (j->error())
KIO::StoredTransferJob* st = (KIO::StoredTransferJob*)j;
KUrl u = st->url();
onAnnounceResult(u,st->data(),j);
}
void HTTPTracker::onQHttpAnnounceResult(KJob* j)
{
HTTPAnnounceJob* st = (HTTPAnnounceJob*)j;
KUrl u = st->announceUrl();
onAnnounceResult(u,st->replyData(),j);
}
void HTTPTracker::onAnnounceResult(const KUrl& url, const QByteArray& data,KJob* j)
{
timer.stop();
active_job = 0;
if (j->error() && data.size() == 0)
{
KIO::StoredTransferJob* st = (KIO::StoredTransferJob*)j;
KUrl u = st->url();
active_job = 0;
Out(SYS_TRK|LOG_IMPORTANT) << "Error : " << st->errorString() << endl;
if (u.queryItem("event") != "stopped")
Out(SYS_TRK|LOG_IMPORTANT) << "Error : " << j->errorString() << endl;
if (url.queryItem("event") != "stopped")
{
failures++;
requestFailed(j->errorString());
......@@ -410,20 +424,16 @@ namespace bt
}
else
{
KIO::StoredTransferJob* st = (KIO::StoredTransferJob*)j;
KUrl u = st->url();
active_job = 0;
if (u.queryItem("event") != "stopped")
if (url.queryItem("event") != "stopped")
{
try
{
if (updateData(st->data()))
if (updateData(data))
{
failures = 0;
peersReady(this);
requestOK();
if (u.queryItem("event") == "started")
if (url.queryItem("event") == "started")
started = true;
}
}
......@@ -484,17 +494,40 @@ namespace bt
void HTTPTracker::doAnnounce(const KUrl & u)
{
Out(SYS_TRK|LOG_NOTICE) << "Doing tracker request to url : " << u.prettyUrl() << endl;
KIO::MetaData md;
setupMetaData(md);
KIO::StoredTransferJob* j = KIO::storedGet(u, KIO::NoReload, KIO::HideProgressInfo);
// set the meta data
j->setMetaData(md);
KIO::Scheduler::scheduleJob(j);
Out(SYS_TRK|LOG_NOTICE) << "Doing tracker request to url (via " << (use_qhttp ? "QHttp" : "KIO") << "): " << u.prettyUrl() << endl;
connect(j,SIGNAL(result(KJob* )),this,SLOT(onAnnounceResult( KJob* )));
if (!use_qhttp)
{
KIO::MetaData md;
setupMetaData(md);
KIO::StoredTransferJob* j = KIO::storedGet(u, KIO::NoReload, KIO::HideProgressInfo);
// set the meta data
j->setMetaData(md);
connect(j,SIGNAL(result(KJob* )),this,SLOT(onKIOAnnounceResult( KJob* )));
KIO::Scheduler::scheduleJob(j);
active_job = j;
}
else
{
HTTPAnnounceJob* j = new HTTPAnnounceJob(u);
connect(j,SIGNAL(result(KJob* )),this,SLOT(onQHttpAnnounceResult(KJob*)));
if (!proxy_on)
{
QString proxy = KProtocolManager::proxyForUrl(u); // Use KDE settings
if (!proxy.isNull() && proxy != "DIRECT")
{
KUrl proxy_url(proxy);
j->setProxy(proxy_url.host(),proxy_url.port() <= 0 ? 80 : proxy_url.port());
}
}
else if (!proxy.isNull())
{
j->setProxy(proxy,proxy_port);
}
active_job = j;
j->start();
}
active_job = j;
requestPending();
}
......@@ -508,5 +541,12 @@ namespace bt
{
proxy_on = on;
}
void HTTPTracker::setUseQHttp(bool on)
{
use_qhttp = on;
}
}
#include "httptracker.moc"
......@@ -24,6 +24,7 @@
#include <btcore_export.h>
#include "tracker.h"
class KJob;
namespace KIO
......@@ -57,9 +58,11 @@ namespace bt
static void setProxy(const QString & proxy,const bt::Uint16 proxy_port);
static void setProxyEnabled(bool on);
static void setUseQHttp(bool on);
private slots:
void onAnnounceResult(KJob* j);
void onKIOAnnounceResult(KJob* j);
void onQHttpAnnounceResult(KJob* j);
void onScrapeResult(KJob* j);
void emitInvalidURLFailure();
......@@ -69,16 +72,20 @@ namespace bt
void setupMetaData(KIO::MetaData & md);
void doAnnounceQueue();
void doAnnounce(const KUrl & u);
void onAnnounceResult(const KUrl & url,const QByteArray & data,KJob* j);
private:
KJob* active_job;
KUrl::List announce_queue;
QString event;
Uint32 failures;
QTimer timer;
static bool proxy_on;
static QString proxy;
static Uint16 proxy_port;
static bool use_qhttp;
};
}
......
......@@ -118,6 +118,7 @@ namespace kt
;
bt::HTTPTracker::setProxyEnabled(!Settings::useKDEProxySettings() && Settings::useProxyForTracker());
bt::HTTPTracker::setProxy(proxy,Settings::httpProxyPort());
bt::HTTPTracker::setUseQHttp(Settings::useQHttpAnnounce());
bt::WebSeed::setProxy(proxy,Settings::httpProxyPort());
bt::WebSeed::setProxyEnabled(!Settings::useKDEProxySettings() && Settings::useProxyForWebSeeds());
bt::Cache::setPreallocationEnabled(Settings::diskPrealloc());
......
......@@ -299,5 +299,8 @@
<entry name="oldTorrentsImported" type="Bool">
<default>false</default>
</entry>
<entry name="useQHttpAnnounce" type="Bool">
<default>false</default>
</entry>
</group>
</kcfg>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment