File indexing completed on 2024-05-19 04:55:59
0001 /** 0002 * \file httpclient.h 0003 * Client to connect to HTTP server. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 30 Dec 2008 0008 * 0009 * Copyright (C) 2008-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #pragma once 0028 0029 #include <QObject> 0030 //#include <QString> 0031 #include <QNetworkReply> 0032 #include <QPointer> 0033 #include <QMap> 0034 #include "kid3api.h" 0035 0036 class QByteArray; 0037 class QNetworkAccessManager; 0038 class QDateTime; 0039 class QTimer; 0040 0041 /** 0042 * Client to connect to HTTP server. 0043 */ 0044 class KID3_CORE_EXPORT HttpClient : public QObject { 0045 Q_OBJECT 0046 public: 0047 /** Name-value map for raw HTTP headers. */ 0048 typedef QMap<QByteArray, QByteArray> RawHeaderMap; 0049 0050 /** 0051 * Constructor. 0052 * 0053 * @param netMgr network access manager 0054 */ 0055 explicit HttpClient(QNetworkAccessManager* netMgr); 0056 0057 /** 0058 * Destructor. 0059 */ 0060 ~HttpClient() override; 0061 0062 /** 0063 * Send a HTTP GET request. 0064 * 0065 * @param url URL 0066 * @param headers optional raw headers to send 0067 */ 0068 void sendRequest(const QUrl& url, 0069 const RawHeaderMap& headers = RawHeaderMap()); 0070 0071 /** 0072 * Send a HTTP GET request. 0073 * 0074 * @param server host name 0075 * @param path path of the URL 0076 * @param scheme scheme, default is "http" 0077 * @param headers optional raw headers to send 0078 */ 0079 void sendRequest(const QString& server, const QString& path, 0080 const QString& scheme = QLatin1String("http"), 0081 const RawHeaderMap& headers = RawHeaderMap()); 0082 0083 /** 0084 * Abort request. 0085 */ 0086 void abort(); 0087 0088 /** 0089 * Get content length. 0090 * @return size of body in bytes, 0 if unknown. 0091 */ 0092 unsigned long getContentLength() const { return m_rcvBodyLen; } 0093 0094 /** 0095 * Get content type. 0096 * @return MIME type, empty if unknown. 0097 */ 0098 QString getContentType() const { return m_rcvBodyType; } 0099 0100 /** 0101 * Extract name and port from string. 0102 * 0103 * @param namePort input string with "name:port" 0104 * @param name output string with "name" 0105 * @param port output integer with port 0106 */ 0107 static void splitNamePort(const QString& namePort, 0108 QString& name, int& port); 0109 0110 signals: 0111 /** 0112 * Emitted to report progress. 0113 * Parameter: state text, bytes received, total bytes. 0114 */ 0115 void progress(const QString&, int, int); 0116 0117 /** 0118 * Emitted when response received. 0119 * Parameter: bytes containing result of request 0120 */ 0121 void bytesReceived(const QByteArray&); 0122 0123 private slots: 0124 /** 0125 * Called when the request is finished. 0126 */ 0127 void networkReplyFinished(); 0128 0129 /** 0130 * Called to report connection progress. 0131 * 0132 * @param received bytes received 0133 * @param total total bytes 0134 */ 0135 void networkReplyProgress(qint64 received, qint64 total); 0136 0137 /** 0138 * Called when an error occurred. 0139 * 0140 * @param code error code 0141 */ 0142 void networkReplyError(QNetworkReply::NetworkError code); 0143 0144 /** 0145 * Called to start delayed sendRequest(). 0146 */ 0147 void delayedSendRequest(); 0148 0149 private: 0150 /** 0151 * Emit a progress signal with step/total steps. 0152 * 0153 * @param text state text 0154 * @param step current step 0155 * @param totalSteps total number of steps 0156 */ 0157 void emitProgress(const QString& text, int step, int totalSteps); 0158 0159 /** 0160 * Emit a progress signal with bytes received/total bytes. 0161 * 0162 * @param text state text 0163 */ 0164 void emitProgress(const QString& text); 0165 0166 /** 0167 * Read the available bytes. 0168 */ 0169 void readBytesAvailable(); 0170 0171 /** 0172 * Get string with proxy or destination and port. 0173 * If a proxy is set, the proxy is returned, else the real destination. 0174 * 0175 * @param dst real destination 0176 * 0177 * @return "destinationname:port". 0178 */ 0179 static QString getProxyOrDest(const QString& dst); 0180 0181 /** network access manager */ 0182 QNetworkAccessManager* m_netMgr; 0183 /** network reply if available, else 0 */ 0184 QPointer<QNetworkReply> m_reply; 0185 /** content length of entity-body, 0 if not available */ 0186 unsigned long m_rcvBodyLen; 0187 /** content type */ 0188 QString m_rcvBodyType; 0189 /** Timer used to delay requests */ 0190 QTimer* m_requestTimer; 0191 /** Context for delayedSendRequest() */ 0192 struct { 0193 QUrl url; 0194 RawHeaderMap headers; 0195 } m_delayedSendRequestContext; 0196 0197 friend struct MinimumRequestIntervalInitializer; 0198 0199 /** Time when last request was sent to server */ 0200 static QMap<QString, QDateTime> s_lastRequestTime; 0201 /** Minimum interval between two requests to server in ms */ 0202 static QMap<QString, int> s_minimumRequestInterval; 0203 };