[libktorrent] backport some upstream fixes, and some .spec cleanup
Rex Dieter
rdieter at fedoraproject.org
Mon Dec 24 18:22:24 UTC 2012
commit c21d7308d10824e18b7c19d9e1f6cfc7a2447851
Author: Rex Dieter <rdieter at math.unl.edu>
Date: Mon Dec 24 12:22:44 2012 -0600
backport some upstream fixes, and some .spec cleanup
...-1.3-Add-workaround-for-broken-handling-o.patch | 138 +++++
...-1.3-Fix-crash-when-preallocating-diskspa.patch | 55 ++
...-1.3-Unbreak-the-non-Linux-case-after-4ff.patch | 29 +
...-1.3-Make-sure-stats-get-updated-properly.patch | 44 ++
...ockets-to-preferred-interface-for-outboun.patch | 646 ++++++++++++++++++++
libktorrent.spec | 27 +-
6 files changed, 927 insertions(+), 12 deletions(-)
---
diff --git a/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch b/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
new file mode 100644
index 0000000..58c2d0e
--- /dev/null
+++ b/0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
@@ -0,0 +1,138 @@
+From f76e1b0b637e53af64ecd813e8541019e50bb8bb Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 24 Sep 2012 11:07:44 +0200
+Subject: [PATCH 1/9] Backport to 1.3: Add workaround for broken handling of
+ btrfs subvolumes by solid
+
+CCBUG: 306825
+---
+ ChangeLog | 3 +++
+ src/util/fileops.cpp | 65 ++++++++++++++++++++++++++++++++++------------------
+ 2 files changed, 46 insertions(+), 22 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index fe2cc21..c037d28 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Changes in 1.3.1:
++- Add workaround for broken handling of btrfs subvolumes by solid (306825)
++
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+
+diff --git a/src/util/fileops.cpp b/src/util/fileops.cpp
+index 637074d..1e5d7d5 100644
+--- a/src/util/fileops.cpp
++++ b/src/util/fileops.cpp
+@@ -30,12 +30,15 @@
+ #include <kio/copyjob.h>
+ #include <solid/device.h>
+ #include <solid/storageaccess.h>
++#include <solid/storagedrive.h>
++#include <solid/storagevolume.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+-#include <qdir.h>
+-#include <qfile.h>
+-#include <qstringlist.h>
++#include <QDir>
++#include <QFile>
++#include <QStringList>
++#include <QSet>
+ #include "error.h"
+ #include "log.h"
+ #include "file.h"
+@@ -73,12 +76,14 @@ typedef int64_t __s64;
+ #endif
+
+ #ifndef Q_WS_WIN
++#include <mntent.h>
+ #include <sys/statvfs.h>
+ #endif
+ #ifdef CopyFile
+ #undef CopyFile
+ #endif
+
++
+ namespace bt
+ {
+ void MakeDir(const QString & dir,bool nothrow)
+@@ -619,38 +624,54 @@ namespace bt
+ return ret;
+ }
+
+- QString MountPoint(const QString& path)
++ QSet<QString> AccessibleMountPoints()
+ {
+- QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+- QString mountpoint;
++ QSet<QString> result;
++#ifndef Q_WS_WIN
++ FILE* fptr = setmntent("/proc/mounts", "r");
++ if(!fptr)
++ return result;
++
++ struct mntent mnt;
++ char buf[PATH_MAX];
++ while(getmntent_r(fptr, &mnt, buf, PATH_MAX))
++ {
++ result.insert(QString(mnt.mnt_dir));
++ }
+
++ endmntent(fptr);
++
++#else
++ QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+ foreach (Solid::Device dev,devs)
+ {
+ Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+- if (path.startsWith(sa->filePath()))
++ if(!sa->filePath().isEmpty() && sa->isAccessible())
++ result.insert(sa->filePa());
++ }
++#endif
++ return result;
++ }
++
++ QString MountPoint(const QString& path)
++ {
++ QSet<QString> mount_points = AccessibleMountPoints();
++ QString mount_point;
++ foreach (const QString & mp, mount_points)
++ {
++ if (path.startsWith(mp) && (mount_point.isEmpty() || mp.startsWith(mount_point)))
+ {
+- if (mountpoint.isEmpty() || sa->filePath().startsWith(mountpoint))
+- mountpoint = sa->filePath();
++ mount_point = mp;
+ }
+ }
+
+- return mountpoint;
++ return mount_point;
+ }
+
++
+ bool IsMounted(const QString& mount_point)
+ {
+- QList<Solid::Device> devs = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
+-
+- foreach (Solid::Device dev,devs)
+- {
+- Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+- if (sa->filePath() == mount_point)
+- {
+- return sa->isAccessible();
+- }
+- }
+-
+- return false;
++ return AccessibleMountPoints().contains(mount_point);
+ }
+
+ }
+--
+1.8.0.2
+
diff --git a/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch b/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
new file mode 100644
index 0000000..4696182
--- /dev/null
+++ b/0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
@@ -0,0 +1,55 @@
+From 30c07792eda0ac656f5173852a059705d8b85163 Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 24 Sep 2012 13:23:41 +0200
+Subject: [PATCH 2/9] Backport to 1.3: Fix crash when preallocating diskspace
+ when a file is enabled during the download of a torrent
+
+CCBUG: 307178
+---
+ ChangeLog | 1 +
+ src/diskio/multifilecache.cpp | 3 ++-
+ src/diskio/preallocationthread.cpp | 3 ++-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index c037d28..7ce9c53 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,6 @@
+ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
++- Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178)
+
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/diskio/multifilecache.cpp b/src/diskio/multifilecache.cpp
+index ce19ffd..8e3d90f 100644
+--- a/src/diskio/multifilecache.cpp
++++ b/src/diskio/multifilecache.cpp
+@@ -783,7 +783,8 @@ namespace bt
+ while(i != files.end())
+ {
+ CacheFile::Ptr cf = i.value();
+- prealloc->add(cf);
++ if(cf)
++ prealloc->add(cf);
+ i++;
+ }
+ }
+diff --git a/src/diskio/preallocationthread.cpp b/src/diskio/preallocationthread.cpp
+index 1a8856c..914d859 100644
+--- a/src/diskio/preallocationthread.cpp
++++ b/src/diskio/preallocationthread.cpp
+@@ -51,7 +51,8 @@ namespace bt
+
+ void PreallocationThread::add(CacheFile::Ptr cache_file)
+ {
+- todo.append(cache_file);
++ if(cache_file)
++ todo.append(cache_file);
+ }
+
+
+--
+1.8.0.2
+
diff --git a/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch b/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
new file mode 100644
index 0000000..7a4b9a3
--- /dev/null
+++ b/0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
@@ -0,0 +1,29 @@
+From 5e4226614361095fc6e83f4abc1dca268de8005b Mon Sep 17 00:00:00 2001
+From: Raphael Kubo da Costa <rakuco at FreeBSD.org>
+Date: Wed, 10 Oct 2012 20:59:36 +0300
+Subject: [PATCH 3/9] Backport to 1.3: Unbreak the non-Linux case after
+ 4ffaa9e.
+
+Use the right method name, filePa() does not exist.
+
+(cherry picked from commit 258ae24d6c6be31362b8877c704ddf3f8b253f62)
+---
+ src/util/fileops.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/util/fileops.cpp b/src/util/fileops.cpp
+index 1e5d7d5..329462e 100644
+--- a/src/util/fileops.cpp
++++ b/src/util/fileops.cpp
+@@ -647,7 +647,7 @@ namespace bt
+ {
+ Solid::StorageAccess* sa = dev.as<Solid::StorageAccess>();
+ if(!sa->filePath().isEmpty() && sa->isAccessible())
+- result.insert(sa->filePa());
++ result.insert(sa->filePath());
+ }
+ #endif
+ return result;
+--
+1.8.0.2
+
diff --git a/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch b/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
new file mode 100644
index 0000000..fb77549
--- /dev/null
+++ b/0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
@@ -0,0 +1,44 @@
+From 92e8fc65cf0bc35be5fa5cd1bb5e76061745a0cd Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Fri, 2 Nov 2012 13:29:06 +0100
+Subject: [PATCH 6/9] Backport to 1.3: Make sure stats get updated properly
+ during data check
+
+CCBUG: 308707
+
+Conflicts:
+
+ src/torrent/torrentcontrol.cpp
+---
+ ChangeLog | 1 +
+ src/torrent/torrentcontrol.cpp | 2 --
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index 7ce9c53..b66d050 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,6 +1,7 @@
+ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
+ - Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178)
++- Make sure stats get updated properly during data check (308707)
+
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/torrent/torrentcontrol.cpp b/src/torrent/torrentcontrol.cpp
+index 7cb4eeb..1a01bf2 100644
+--- a/src/torrent/torrentcontrol.cpp
++++ b/src/torrent/torrentcontrol.cpp
+@@ -134,8 +134,6 @@ namespace bt
+ void TorrentControl::update()
+ {
+ UpdateCurrentTime();
+- if (job_queue->runningJobs())
+- return;
+
+ if (istats.io_error)
+ {
+--
+1.8.0.2
+
diff --git a/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch b/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
new file mode 100644
index 0000000..2e52172
--- /dev/null
+++ b/0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
@@ -0,0 +1,646 @@
+From 495ce3f3cec2337b31bdd4015ed80849affca0fd Mon Sep 17 00:00:00 2001
+From: Joris Guisson <joris.guisson at gmail.com>
+Date: Mon, 17 Dec 2012 12:23:01 +0100
+Subject: [PATCH 7/9] Bind peer sockets to preferred interface for outbound
+ connections
+
+---
+ ChangeLog | 1 +
+ src/diskio/cache.cpp | 3 +
+ src/net/trafficshapedsocket.cpp | 260 ++++++++++++++++++++------------------
+ src/tracker/httpannouncejob.cpp | 272 ++++++++++++++++++++--------------------
+ src/tracker/httptracker.cpp | 8 +-
+ 5 files changed, 279 insertions(+), 265 deletions(-)
+
+diff --git a/ChangeLog b/ChangeLog
+index b66d050..bfa8fbe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -2,6 +2,7 @@ Changes in 1.3.1:
+ - Add workaround for broken handling of btrfs subvolumes by solid (306825)
+ - Fix crash when preallocating diskspace when a file is enabled during the download of a torrent (307178)
+ - Make sure stats get updated properly during data check (308707)
++- Bind peer sockets to preferred interface for outbound connections
+
+ Changes in 1.3:
+ - Do not pass link local IPv6 addresses to ip parameter of tracker (305187)
+diff --git a/src/diskio/cache.cpp b/src/diskio/cache.cpp
+index 703a846..ed43c85 100644
+--- a/src/diskio/cache.cpp
++++ b/src/diskio/cache.cpp
+@@ -203,6 +203,9 @@ namespace bt
+
+ bool Cache::isStorageMounted(QStringList& missing)
+ {
++ if(mount_points.isEmpty())
++ return true;
++
+ missing.clear();
+ foreach(const QString & mount_point, mount_points)
+ {
+diff --git a/src/net/trafficshapedsocket.cpp b/src/net/trafficshapedsocket.cpp
+index d3e6c90..336acac 100644
+--- a/src/net/trafficshapedsocket.cpp
++++ b/src/net/trafficshapedsocket.cpp
+@@ -20,137 +20,147 @@
+
+
+ #include "trafficshapedsocket.h"
++
++#include <QStringList>
++#include <util/functions.h>
+ #include "speed.h"
+ #include "socket.h"
+
+-#define OUTPUT_BUFFER_SIZE 16393
++const bt::Uint32 OUTPUT_BUFFER_SIZE = 16393;
+
+ using namespace bt;
+
+ namespace net
+ {
+
+- TrafficShapedSocket::TrafficShapedSocket(SocketDevice* sock) :
+- rdr(0),
+- up_gid(0),
+- down_gid(0),
+- sock(sock),
+- mutex(QMutex::Recursive)
+- {
+- down_speed = new Speed();
+- up_speed = new Speed();
+- }
+-
+- TrafficShapedSocket::TrafficShapedSocket(int fd, int ip_version) :
+- rdr(0),
+- up_gid(0),
+- down_gid(0),
+- mutex(QMutex::Recursive)
+- {
+- sock = new Socket(fd, ip_version);
+- down_speed = new Speed();
+- up_speed = new Speed();
+- }
+-
+- TrafficShapedSocket::TrafficShapedSocket(bool tcp, int ip_version) :
+- rdr(0),
+- up_gid(0),
+- down_gid(0),
+- mutex(QMutex::Recursive)
+- {
+- sock = new Socket(tcp, ip_version);
+- down_speed = new Speed();
+- up_speed = new Speed();
+- }
+-
+- TrafficShapedSocket::~TrafficShapedSocket()
+- {
+- delete up_speed;
+- delete down_speed;
+- delete sock;
+- }
+-
+- void TrafficShapedSocket::setGroupID(Uint32 gid,bool upload)
+- {
+- if (upload)
+- up_gid = gid;
+- else
+- down_gid = gid;
+- }
+-
+- int TrafficShapedSocket::getDownloadRate() const
+- {
+- // getRate is atomic
+- return down_speed->getRate();
+- }
+-
+- int TrafficShapedSocket::getUploadRate() const
+- {
+- // getRate is atomic
+- return up_speed->getRate();
+- }
+-
+- void TrafficShapedSocket::updateSpeeds(bt::TimeStamp now)
+- {
+- mutex.lock();
+- up_speed->update(now);
+- down_speed->update(now);
+- mutex.unlock();
+- }
+-
+- static bt::Uint8 input_buffer[OUTPUT_BUFFER_SIZE];
+-
+- Uint32 TrafficShapedSocket::read(bt::Uint32 max_bytes_to_read, bt::TimeStamp now)
+- {
+- Uint32 br = 0;
+- bool no_limit = (max_bytes_to_read == 0);
+- Uint32 ba = sock->bytesAvailable();
+- if (ba == 0)
+- {
+- // For some strange reason, sometimes bytesAvailable returns 0, while there are
+- // bytes to read, so give ba the maximum value it can be
+- ba = max_bytes_to_read > 0 ? max_bytes_to_read : OUTPUT_BUFFER_SIZE;
+- }
+-
+- while ((br < max_bytes_to_read || no_limit) && ba > 0)
+- {
+- Uint32 tr = ba;
+- if (tr > OUTPUT_BUFFER_SIZE)
+- tr = OUTPUT_BUFFER_SIZE;
+- if (!no_limit && tr + br > max_bytes_to_read)
+- tr = max_bytes_to_read - br;
+-
+- int ret = sock->recv(input_buffer,tr);
+- if (ret > 0)
+- {
+- mutex.lock();
+- down_speed->onData(ret,now);
+- mutex.unlock();
+- if (rdr)
+- {
+- postProcess(input_buffer, ret);
+- rdr->onDataReady(input_buffer,ret);
+- }
+- br += ret;
+- ba -= ret;
+- }
+- else if (ret < 0)
+- {
+- return br;
+- }
+- else
+- {
+- sock->close();
+- return br;
+- }
+- }
+- return br;
+- }
+-
+-
+- void TrafficShapedSocket::postProcess(Uint8* data, Uint32 size)
+- {
+- Q_UNUSED(data);
+- Q_UNUSED(size);
+- }
+-}
+\ No newline at end of file
++ TrafficShapedSocket::TrafficShapedSocket(SocketDevice* sock) :
++ rdr(0),
++ up_gid(0),
++ down_gid(0),
++ sock(sock),
++ mutex(QMutex::Recursive)
++ {
++ down_speed = new Speed();
++ up_speed = new Speed();
++ }
++
++ TrafficShapedSocket::TrafficShapedSocket(int fd, int ip_version) :
++ rdr(0),
++ up_gid(0),
++ down_gid(0),
++ mutex(QMutex::Recursive)
++ {
++ sock = new Socket(fd, ip_version);
++ down_speed = new Speed();
++ up_speed = new Speed();
++ }
++
++ TrafficShapedSocket::TrafficShapedSocket(bool tcp, int ip_version) :
++ rdr(0),
++ up_gid(0),
++ down_gid(0),
++ mutex(QMutex::Recursive)
++ {
++ Socket* socket = new Socket(tcp, ip_version);
++
++ QString iface = NetworkInterface();
++ QStringList ips = NetworkInterfaceIPAddresses(iface);
++ if (ips.size() > 0)
++ socket->bind(ips.front(), 0, false);
++
++ sock = socket;
++ down_speed = new Speed();
++ up_speed = new Speed();
++ }
++
++ TrafficShapedSocket::~TrafficShapedSocket()
++ {
++ delete up_speed;
++ delete down_speed;
++ delete sock;
++ }
++
++ void TrafficShapedSocket::setGroupID(Uint32 gid, bool upload)
++ {
++ if (upload)
++ up_gid = gid;
++ else
++ down_gid = gid;
++ }
++
++ int TrafficShapedSocket::getDownloadRate() const
++ {
++ // getRate is atomic
++ return down_speed->getRate();
++ }
++
++ int TrafficShapedSocket::getUploadRate() const
++ {
++ // getRate is atomic
++ return up_speed->getRate();
++ }
++
++ void TrafficShapedSocket::updateSpeeds(bt::TimeStamp now)
++ {
++ mutex.lock();
++ up_speed->update(now);
++ down_speed->update(now);
++ mutex.unlock();
++ }
++
++ static bt::Uint8 input_buffer[OUTPUT_BUFFER_SIZE];
++
++ Uint32 TrafficShapedSocket::read(bt::Uint32 max_bytes_to_read, bt::TimeStamp now)
++ {
++ Uint32 br = 0;
++ bool no_limit = (max_bytes_to_read == 0);
++ Uint32 ba = sock->bytesAvailable();
++ if (ba == 0)
++ {
++ // For some strange reason, sometimes bytesAvailable returns 0, while there are
++ // bytes to read, so give ba the maximum value it can be
++ ba = max_bytes_to_read > 0 ? max_bytes_to_read : OUTPUT_BUFFER_SIZE;
++ }
++
++ while ((br < max_bytes_to_read || no_limit) && ba > 0)
++ {
++ Uint32 tr = ba;
++ if (tr > OUTPUT_BUFFER_SIZE)
++ tr = OUTPUT_BUFFER_SIZE;
++ if (!no_limit && tr + br > max_bytes_to_read)
++ tr = max_bytes_to_read - br;
++
++ int ret = sock->recv(input_buffer, tr);
++ if (ret > 0)
++ {
++ mutex.lock();
++ down_speed->onData(ret, now);
++ mutex.unlock();
++ if (rdr)
++ {
++ postProcess(input_buffer, ret);
++ rdr->onDataReady(input_buffer, ret);
++ }
++ br += ret;
++ ba -= ret;
++ }
++ else if (ret < 0)
++ {
++ return br;
++ }
++ else
++ {
++ sock->close();
++ return br;
++ }
++ }
++ return br;
++ }
++
++
++ void TrafficShapedSocket::postProcess(Uint8* data, Uint32 size)
++ {
++ Q_UNUSED(data);
++ Q_UNUSED(size);
++ }
++}
+diff --git a/src/tracker/httpannouncejob.cpp b/src/tracker/httpannouncejob.cpp
+index 0e5d29f..11f760f 100644
+--- a/src/tracker/httpannouncejob.cpp
++++ b/src/tracker/httpannouncejob.cpp
+@@ -20,147 +20,149 @@
+ #include <version.h>
+ #include <KLocalizedString>
+ #include <util/log.h>
++#include <util/functions.h>
+ #include <QTimer>
+ #include <QSslError>
++#include <QTcpSocket>
+
+ namespace bt
+ {
+
+- HTTPAnnounceJob::HTTPAnnounceJob(const KUrl& url) : url(url),get_id(0),proxy_port(-1)
+- {
+- http = new QHttp(this);
+- connect(http,SIGNAL(requestFinished(int,bool)),this,SLOT(requestFinished(int,bool)));
+- connect(http,SIGNAL(readyRead(QHttpResponseHeader)),this,SLOT(readData(QHttpResponseHeader)));
+- connect(http,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sslErrors(QList<QSslError>)));
+- }
+-
+- HTTPAnnounceJob::~HTTPAnnounceJob()
+- {
+- }
+-
+- void HTTPAnnounceJob::start()
+- {
+- sendRequest();
+- }
+-
+- void HTTPAnnounceJob::sendRequest()
+- {
+- QHttp::ConnectionMode mode = url.protocol() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
+- quint16 port = url.port() < 0 ? 0 : url.port();
+- quint16 default_port = mode == QHttp::ConnectionModeHttps ? 443 : 80;
+- http->setHost(url.host(),mode,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(default_port)));
+- get_id = http->request(hdr);
+- Out(SYS_TRK|LOG_DEBUG) << "Request sent" << endl;
+- }
+-
+- 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());
+- emitResult();
+- }
+- else
+- {
+- switch (http->lastResponse().statusCode())
+- {
+- case 300:
+- case 301:
+- case 302:
+- case 303:
+- case 307:
+- handleRedirect(http->lastResponse());
+- break;
+- case 403:
+- setError(KIO::ERR_ACCESS_DENIED);
+- emitResult();
+- break;
+- case 404:
+- setError(KIO::ERR_DOES_NOT_EXIST);
+- emitResult();
+- break;
+- case 500:
+- setError(KIO::ERR_INTERNAL_SERVER);
+- emitResult();
+- break;
+- default:
+- emitResult();
+- break;
+- }
+- }
+- }
+-
+- void HTTPAnnounceJob::readData(const QHttpResponseHeader& hdr)
+- {
+- const int MAX_REPLY_SIZE = 1024 * 1024;
+-
+- int ba = http->bytesAvailable();
+- int current_size = reply_data.size();
+- if (current_size + ba > MAX_REPLY_SIZE)
+- {
+- // If the reply is larger then a mega byte, the server
+- // has probably gone bonkers
+- http->abort();
+- Out(SYS_TRK|LOG_DEBUG) << "Tracker sending back to much data in announce reply, aborting ..." << endl;
+- }
+- else
+- {
+- // enlarge reply data and read data to it
+- reply_data.resize(current_size + ba);
+- http->read(reply_data.data() + current_size,ba);
+- }
+- }
+-
+- void HTTPAnnounceJob::setProxy(const QString& host, int port)
+- {
+- proxy_host = host;
+- proxy_port = port;
+- }
+-
+-
+- void HTTPAnnounceJob::handleRedirect(const QHttpResponseHeader& hdr)
+- {
+- if (!hdr.hasKey("Location"))
+- {
+- setErrorText(i18n("Redirect without a redirect location"));
+- emitResult();
+- }
+- else
+- {
+- reply_data.clear();
+- url = hdr.value("Location");
+- Out(SYS_TRK|LOG_DEBUG) << "Redirected to " << hdr.value("Location") << endl;
+- sendRequest();
+- }
+- }
+-
+- void HTTPAnnounceJob::sslErrors(const QList<QSslError>& errors)
+- {
+- KUrl u = url;
+- u.setQuery(QString());
+- Out(SYS_TRK|LOG_NOTICE) << "SSL errors detected when announcing to " << u.prettyUrl() << ":" << endl;
+- foreach (const QSslError & err,errors)
+- Out(SYS_TRK|LOG_NOTICE) << err.errorString() << endl;
+- Out(SYS_TRK|LOG_NOTICE) << "Errors will be ignored " << endl;
+- http->ignoreSslErrors();
+- }
++ HTTPAnnounceJob::HTTPAnnounceJob(const KUrl& url) : url(url), get_id(0), proxy_port(-1)
++ {
++ http = new QHttp(this);
++ connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(requestFinished(int, bool)));
++ connect(http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(readData(QHttpResponseHeader)));
++ connect(http, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
++ }
++
++ HTTPAnnounceJob::~HTTPAnnounceJob()
++ {
++ }
++
++ void HTTPAnnounceJob::start()
++ {
++ sendRequest();
++ }
++
++ void HTTPAnnounceJob::sendRequest()
++ {
++ QHttp::ConnectionMode mode = url.protocol() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
++ quint16 port = url.port() < 0 ? 0 : url.port();
++ quint16 default_port = mode == QHttp::ConnectionModeHttps ? 443 : 80;
++ http->setHost(url.host(), mode, 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(default_port)));
++ get_id = http->request(hdr);
++ Out(SYS_TRK | LOG_DEBUG) << "Request sent" << endl;
++ }
++
++ 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());
++ emitResult();
++ }
++ else
++ {
++ switch (http->lastResponse().statusCode())
++ {
++ case 300:
++ case 301:
++ case 302:
++ case 303:
++ case 307:
++ handleRedirect(http->lastResponse());
++ break;
++ case 403:
++ setError(KIO::ERR_ACCESS_DENIED);
++ emitResult();
++ break;
++ case 404:
++ setError(KIO::ERR_DOES_NOT_EXIST);
++ emitResult();
++ break;
++ case 500:
++ setError(KIO::ERR_INTERNAL_SERVER);
++ emitResult();
++ break;
++ default:
++ emitResult();
++ break;
++ }
++ }
++ }
++
++ void HTTPAnnounceJob::readData(const QHttpResponseHeader& hdr)
++ {
++ const int MAX_REPLY_SIZE = 1024 * 1024;
++
++ int ba = http->bytesAvailable();
++ int current_size = reply_data.size();
++ if (current_size + ba > MAX_REPLY_SIZE)
++ {
++ // If the reply is larger then a mega byte, the server
++ // has probably gone bonkers
++ http->abort();
++ Out(SYS_TRK | LOG_DEBUG) << "Tracker sending back to much data in announce reply, aborting ..." << endl;
++ }
++ else
++ {
++ // enlarge reply data and read data to it
++ reply_data.resize(current_size + ba);
++ http->read(reply_data.data() + current_size, ba);
++ }
++ }
++
++ void HTTPAnnounceJob::setProxy(const QString& host, int port)
++ {
++ proxy_host = host;
++ proxy_port = port;
++ }
++
++
++ void HTTPAnnounceJob::handleRedirect(const QHttpResponseHeader& hdr)
++ {
++ if (!hdr.hasKey("Location"))
++ {
++ setErrorText(i18n("Redirect without a redirect location"));
++ emitResult();
++ }
++ else
++ {
++ reply_data.clear();
++ url = hdr.value("Location");
++ Out(SYS_TRK | LOG_DEBUG) << "Redirected to " << hdr.value("Location") << endl;
++ sendRequest();
++ }
++ }
++
++ void HTTPAnnounceJob::sslErrors(const QList<QSslError>& errors)
++ {
++ KUrl u = url;
++ u.setQuery(QString());
++ Out(SYS_TRK | LOG_NOTICE) << "SSL errors detected when announcing to " << u.prettyUrl() << ":" << endl;
++ foreach (const QSslError& err, errors)
++ Out(SYS_TRK | LOG_NOTICE) << err.errorString() << endl;
++ Out(SYS_TRK | LOG_NOTICE) << "Errors will be ignored " << endl;
++ http->ignoreSslErrors();
++ }
+
+ }
+
+diff --git a/src/tracker/httptracker.cpp b/src/tracker/httptracker.cpp
+index cef3179..a20f9b5 100644
+--- a/src/tracker/httptracker.cpp
++++ b/src/tracker/httptracker.cpp
+@@ -157,11 +157,11 @@ namespace bt
+
+ KIO::StoredTransferJob* st = (KIO::StoredTransferJob*)j;
+ BDecoder dec(st->data(), false, 0);
+- BNode* n = 0;
++ QScopedPointer<BNode> n;
+
+ try
+ {
+- n = dec.decode();
++ n.reset(dec.decode());
+ }
+ catch (bt::Error & err)
+ {
+@@ -171,7 +171,7 @@ namespace bt
+
+ if (n && n->getType() == BNode::DICT)
+ {
+- BDictNode* d = (BDictNode*)n;
++ BDictNode* d = (BDictNode*)n.data();
+ d = d->getDict(QString("files"));
+ if (d)
+ {
+@@ -198,8 +198,6 @@ namespace bt
+ }
+ }
+ }
+-
+- delete n;
+ }
+
+ void HTTPTracker::doRequest(WaitJob* wjob)
+--
+1.8.0.2
+
diff --git a/libktorrent.spec b/libktorrent.spec
index 1945d06..d124dbf 100644
--- a/libktorrent.spec
+++ b/libktorrent.spec
@@ -2,15 +2,19 @@
Name: libktorrent
Version: 1.3.0
-Release: 1%{?pre}%{?dist}
+Release: 2%{?pre}%{?dist}
Summary: Library providing torrent downloading code
-Group: System Environment/Libraries
License: GPLv2+
URL: http://ktorrent.org/
Source0: http://ktorrent.org/downloads/4.3.0%{?pre}/libktorrent-%{version}%{?pre}.tar.bz2
## upstream patches
+Patch101: 0001-Backport-to-1.3-Add-workaround-for-broken-handling-o.patch
+Patch102: 0002-Backport-to-1.3-Fix-crash-when-preallocating-diskspa.patch
+Patch103: 0003-Backport-to-1.3-Unbreak-the-non-Linux-case-after-4ff.patch
+Patch106: 0006-Backport-to-1.3-Make-sure-stats-get-updated-properly.patch
+Patch107: 0007-Bind-peer-sockets-to-preferred-interface-for-outboun.patch
BuildRequires: boost-devel
BuildRequires: gettext
@@ -26,7 +30,6 @@ BuildRequires: pkgconfig(qca2)
%package devel
Summary: Developer files for %{name}
-Group: Development/Libraries
Obsoletes: ktorrent-devel <= 4.0
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: kdelibs4-devel%{?_isa}
@@ -36,10 +39,15 @@ Requires: gmp-devel%{?_isa}
%{summary}.
-
%prep
%setup -q -n %{name}-%{version}%{?pre}
+%patch101 -p1 -b .0001
+%patch102 -p1 -b .0002
+%patch103 -p1 -b .0003
+%patch106 -p1 -b .0006
+%patch107 -p1 -b .0007
+
%build
mkdir -p %{_target_platform}
@@ -51,33 +59,28 @@ make %{?_smp_mflags} -C %{_target_platform}
%install
-rm -rf %{buildroot}
-
make install/fast DESTDIR=%{buildroot} -C %{_target_platform}
%find_lang %{name} --with-kde
-%clean
-rm -rf %{buildroot}
-
-
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files -f %{name}.lang
-%defattr(-,root,root,-)
%doc ChangeLog COPYING
%{_kde4_libdir}/libktorrent.so.5*
%files devel
-%defattr(-,root,root,-)
%{_kde4_appsdir}/cmake/modules/FindKTorrent.cmake
%{_kde4_includedir}/libktorrent/
%{_kde4_libdir}/libktorrent.so
%changelog
+* Mon Dec 24 2012 Rex Dieter <rdieter at fedoraproject.org> 1.3.0-2
+- backport some upstream fixes, and some .spec cleanup
+
* Sat Sep 1 2012 Alexey Kurov <nucleo at fedoraproject.org> - 1.3.0-1
- libktorrent-1.3.0
More information about the scm-commits
mailing list