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

Added experimental code to do tracker announces via QHttp instead of KIO.

This will fix the connection to host is broken errors. But seeing that it is still a bit experimental it
currently is a special option you need to enable in in the advanced settings.

svn path=/trunk/extragear/network/ktorrent/; revision=973256
parent 8c83f07c
This diff is collapsed.
......@@ -163,6 +163,7 @@ set(libbtcore_SRC
tracker/udptracker.cpp
tracker/udptrackersocket.cpp
tracker/trackermanager.cpp
tracker/httpannouncejob.cpp
datachecker/datachecker.cpp
datachecker/datacheckerthread.cpp
......
......@@ -101,7 +101,7 @@ namespace bt
BValueNode* announce = dict->getValue("announce");
BListNode* nodes = dict->getList("nodes");
if (!announce && !nodes)
throw Error(i18n("Torrent has no announce or nodes field"));
throw Error(i18n("Torrent has no announce or nodes field."));
if (announce)
loadTrackerURL(dict->getString("announce",text_codec));
......
......@@ -509,12 +509,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));
......@@ -537,12 +539,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;
connect(&timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
}
HTTPTracker::~HTTPTracker()
{
}
......@@ -382,18 +385,29 @@ namespace bt
delete n;
return true;
}
void HTTPTracker::onAnnounceResult(KJob* j)
void HTTPTracker::onKIOAnnounceResult(KJob* j)
{
timer.stop();
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())
if (j->error() && data.size() == 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++;
failed(j->errorString());
......@@ -406,18 +420,18 @@ namespace bt
}
else
{
if (u.queryItem("event") != "stopped")
if (url.queryItem("event") != "stopped")
{
try
{
if (updateData(st->data()))
if (updateData(data))
{
failures = 0;
peersReady(this);
request_time = QDateTime::currentDateTime();
status = TRACKER_OK;
requestOK();
if (u.queryItem("event") == "started")
if (url.queryItem("event") == "started")
started = true;
if (started)
reannounce_timer.start(interval * 1000);
......@@ -481,17 +495,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;
timer.start(60*1000);
status = TRACKER_ANNOUNCING;
requestPending();
......@@ -514,5 +551,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
......@@ -56,9 +57,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();
void onTimeout();
......@@ -70,6 +73,7 @@ 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;
......@@ -78,9 +82,11 @@ namespace bt
Uint32 failures;
QTimer timer;
static bool proxy_on;
static QString proxy;
static Uint16 proxy_port;
static bool use_qhttp;
};
}
......
......@@ -119,6 +119,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());
......
......@@ -302,5 +302,8 @@
<entry name="webseedsEnabled" type="Bool">
<default>true</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