File indexing completed on 2025-02-16 04:37:34

0001 /*
0002     SPDX-FileCopyrightText: 2008 Joris Guisson <joris.guisson@gmail.com>
0003     SPDX-FileCopyrightText: 2008 Ivan Vasic <ivasic@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 #ifndef BTWEBSEED_H
0008 #define BTWEBSEED_H
0009 
0010 #include <QTimer>
0011 #include <QUrl>
0012 #include <diskio/piecedata.h>
0013 #include <interfaces/chunkdownloadinterface.h>
0014 #include <interfaces/webseedinterface.h>
0015 #include <ktorrent_export.h>
0016 #include <peer/connectionlimit.h>
0017 #include <util/constants.h>
0018 
0019 namespace bt
0020 {
0021 class Torrent;
0022 class HttpConnection;
0023 class ChunkManager;
0024 class Chunk;
0025 class WebSeedChunkDownload;
0026 
0027 /**
0028     @author Joris Guisson
0029     Class which handles downloading from a webseed
0030 */
0031 class KTORRENT_EXPORT WebSeed : public QObject, public WebSeedInterface
0032 {
0033     Q_OBJECT
0034 public:
0035     WebSeed(const QUrl &url, bool user, const Torrent &tor, ChunkManager &cman);
0036     ~WebSeed() override;
0037 
0038     /// Is this webseed busy ?
0039     bool busy() const;
0040 
0041     /// Check if a chunk lies in the current range we are downloading
0042     bool inCurrentRange(Uint32 chunk) const
0043     {
0044         return chunk >= first_chunk && chunk <= last_chunk;
0045     }
0046 
0047     /**
0048      * Download a range of chunks
0049      * @param first The first chunk
0050      * @param last The last chunk
0051      */
0052     void download(Uint32 first, Uint32 last);
0053 
0054     /**
0055      * A range has been excluded, if we are fully
0056      * downloading in this range, reset.
0057      * @param from Start of range
0058      * @param to End of range
0059      */
0060     void onExcluded(Uint32 from, Uint32 to);
0061 
0062     /**
0063      * Check if the connection has received some data and handle it.
0064      * @return The number of bytes downloaded
0065      */
0066     Uint32 update();
0067 
0068     /**
0069      * A chunk has been downloaded.
0070      * @param chunk The chunk
0071      */
0072     void chunkDownloaded(Uint32 chunk);
0073 
0074     /**
0075      * Cancel the current download and kill the connection
0076      */
0077     void cancel();
0078 
0079     /// Get the current download rate
0080     Uint32 getDownloadRate() const override;
0081 
0082     /**
0083      * Set the group ID's of the http connection (for speed limits)
0084      * @param up Upload group id
0085      * @param down Download group id
0086      */
0087     void setGroupIDs(Uint32 up, Uint32 down);
0088 
0089     /**
0090      * Set the proxy to use for all WebSeeds
0091      * @param host Hostname or IP address of the proxy
0092      * @param port Port number of the proxy
0093      */
0094     static void setProxy(const QString &host, bt::Uint16 port);
0095 
0096     /**
0097      * Whether or not to enable or disable the use of a proxy.
0098      * When the proxy is disabled, we will use the KDE proxy settings.
0099      * @param on On or not
0100      */
0101     static void setProxyEnabled(bool on);
0102 
0103     /// Get the current webseed download
0104     WebSeedChunkDownload *currentChunkDownload()
0105     {
0106         return current;
0107     }
0108 
0109     void setEnabled(bool on) override;
0110 
0111     /// Disable the webseed
0112     void disable(const QString &reason);
0113 
0114     /// Get the number of failed attempts
0115     Uint32 failedAttempts() const
0116     {
0117         return num_failures;
0118     }
0119 
0120 public Q_SLOTS:
0121     /**
0122      * Reset the webseed (kills the connection)
0123      */
0124     void reset();
0125 
0126 Q_SIGNALS:
0127     /**
0128      * Emitted when a chunk is downloaded
0129      * @param c The chunk
0130      */
0131     void chunkReady(Chunk *c);
0132 
0133     /**
0134      * Emitted when a range has been fully downloaded
0135      */
0136     void finished();
0137 
0138     /**
0139      * A ChunkDownload was started
0140      * @param cd The ChunkDownloadInterface
0141      * @param chunk The chunk which is being started
0142      */
0143     void chunkDownloadStarted(WebSeedChunkDownload *cd, Uint32 chunk);
0144 
0145     /**
0146      * A ChunkDownload was finished
0147      * @param cd The ChunkDownloadInterface
0148      * @param chunk The chunk which is being stopped
0149      */
0150     void chunkDownloadFinished(WebSeedChunkDownload *cd, Uint32 chunk);
0151 
0152 private Q_SLOTS:
0153     void redirected(const QUrl &to_url);
0154 
0155 private:
0156     struct Range {
0157         Uint32 file;
0158         Uint64 off;
0159         Uint64 len;
0160     };
0161 
0162     class AutoDisabled
0163     {
0164     }; // Exception
0165 
0166     void fillRangeList(Uint32 chunk);
0167     void handleData(const QByteArray &data);
0168     void chunkStarted(Uint32 chunk);
0169     void chunkStopped();
0170     void connectToServer();
0171     void continueCurChunk();
0172     void readData();
0173     void retryLater();
0174 
0175 private:
0176     const Torrent &tor;
0177     ChunkManager &cman;
0178     HttpConnection *conn;
0179     QList<QByteArray> chunks;
0180     Uint32 first_chunk;
0181     Uint32 last_chunk;
0182     Uint32 cur_chunk;
0183     Uint32 bytes_of_cur_chunk;
0184     Uint32 num_failures;
0185     Uint32 downloaded;
0186     WebSeedChunkDownload *current;
0187     Uint32 up_gid, down_gid;
0188     QList<Range> range_queue;
0189     QUrl redirected_url;
0190     PieceData::Ptr cur_piece;
0191     QTimer retry_timer;
0192     ConnectionLimit::Token::Ptr token;
0193 
0194     static QString proxy_host;
0195     static Uint16 proxy_port;
0196     static bool proxy_enabled;
0197 };
0198 
0199 class WebSeedChunkDownload : public ChunkDownloadInterface
0200 {
0201 public:
0202     WebSeedChunkDownload(WebSeed *ws, const QString &url, Uint32 index, Uint32 total);
0203     ~WebSeedChunkDownload() override;
0204 
0205     void getStats(Stats &s) override;
0206 
0207     WebSeed *ws;
0208     QString url;
0209     Uint32 chunk;
0210     Uint32 total_pieces;
0211     Uint32 pieces_downloaded;
0212 };
0213 
0214 }
0215 
0216 #endif