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