File indexing completed on 2024-04-28 04:57:37
0001 /*************************************************************************** 0002 * Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net> * 0003 * Copyright (C) 2012 Aish Raj Dahal <dahalaishraj@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 0019 ***************************************************************************/ 0020 0021 #ifndef Metalinker_H 0022 #define Metalinker_H 0023 0024 #include <KIO/Global> 0025 #include <KIO/Job> 0026 0027 #include <QDate> 0028 #include <QDomElement> 0029 #include <QEventLoop> 0030 #include <QObject> 0031 #include <QString> 0032 #include <QUrl> 0033 0034 /** 0035 * The following classes try to resemble the structure of a Metalink-document, they partially support 0036 * the Metalink specification version 3.0 2nd ed and Draft 09 0037 * It is possible to load and save metalinks and to edit them inbetween, you could also create a metalink 0038 * from scratch 0039 */ 0040 0041 namespace KGetMetalink 0042 { 0043 0044 class DateConstruct 0045 { 0046 public: 0047 DateConstruct() 0048 : negativeOffset(false) 0049 { 0050 } 0051 0052 void setData(const QDateTime &dateTime, const QTime &timeZoneOffset = QTime(), bool negativeOffset = false); 0053 void setData(const QString &dateConstruct); 0054 0055 void clear(); 0056 0057 bool isNull() const; 0058 bool isValid() const; 0059 0060 QString toString() const; 0061 0062 QDateTime dateTime; 0063 QTime timeZoneOffset; 0064 bool negativeOffset; 0065 }; 0066 0067 /** 0068 * This class contains a url and the name, it can be used to e.g. describe a publisher 0069 */ 0070 class UrlText 0071 { 0072 public: 0073 UrlText() 0074 { 0075 } 0076 0077 bool isEmpty() const 0078 { 0079 return name.isEmpty() && url.isEmpty(); 0080 } 0081 0082 void clear(); 0083 0084 QString name; 0085 QUrl url; 0086 }; 0087 0088 /** 0089 * Files, File and Metadata contain this 0090 * Metadata not as member and only for compatibility 0091 */ 0092 class CommonData 0093 { 0094 public: 0095 CommonData() 0096 { 0097 } 0098 0099 void load(const QDomElement &e); 0100 void save(QDomElement &e) const; 0101 0102 void clear(); 0103 0104 QString identity; 0105 QString version; 0106 QString description; 0107 QStringList oses; 0108 QUrl logo; 0109 QStringList languages; 0110 UrlText publisher; 0111 QString copyright; 0112 }; 0113 0114 class Metaurl 0115 { 0116 public: 0117 Metaurl() 0118 : priority(0) 0119 { 0120 } 0121 0122 /** 0123 * "smaller" urls are less important than larger, larger urls should be preferred 0124 */ 0125 bool operator<(const Metaurl &other) const; 0126 0127 void load(const QDomElement &e); 0128 void save(QDomElement &e) const; 0129 0130 bool isValid(); 0131 0132 void clear(); 0133 0134 QString type; 0135 0136 /** 0137 * the priority of the urls, 1 is highest priority, 999999 lowest 0138 * default is 0 as in not set and thus is ranked even behind 999999 0139 */ 0140 uint priority; 0141 0142 /** 0143 * Optional the name of a file that should be get of that metaurl 0144 */ 0145 QString name; 0146 0147 QUrl url; 0148 }; 0149 0150 class Url 0151 { 0152 public: 0153 Url() 0154 : priority(0) 0155 { 0156 } 0157 0158 /** 0159 * "smaller" urls are less important than larger, larger urls should be preferred 0160 */ 0161 bool operator<(const Url &other) const; 0162 0163 void load(const QDomElement &e); 0164 void save(QDomElement &e) const; 0165 0166 bool isValid(); 0167 0168 void clear(); 0169 0170 /** 0171 * the priority of the urls, 1 is highest priority, 999999 lowest 0172 * default is 0 as in not set and thus is ranked even behind 999999 0173 */ 0174 uint priority; 0175 0176 /** 0177 * the location of the server eg. "uk" 0178 */ 0179 QString location; 0180 0181 QUrl url; 0182 }; 0183 0184 class Resources 0185 { 0186 public: 0187 Resources() 0188 { 0189 } 0190 0191 bool isValid() const 0192 { 0193 return !urls.isEmpty() || !metaurls.isEmpty(); 0194 } 0195 0196 void load(const QDomElement &e); 0197 void save(QDomElement &e) const; 0198 0199 void clear(); 0200 0201 QList<Url> urls; 0202 QList<Metaurl> metaurls; 0203 }; 0204 0205 class Pieces 0206 { 0207 public: 0208 Pieces() 0209 : length(0) 0210 { 0211 } 0212 0213 void load(const QDomElement &e); 0214 void save(QDomElement &e) const; 0215 0216 void clear(); 0217 0218 QString type; 0219 KIO::filesize_t length; 0220 QStringList hashes; 0221 }; 0222 0223 class Verification 0224 { 0225 public: 0226 Verification() 0227 { 0228 } 0229 0230 void load(const QDomElement &e); 0231 void save(QDomElement &e) const; 0232 0233 void clear(); 0234 0235 QMultiHash<QString, QString> hashes; 0236 QList<Pieces> pieces; 0237 QMultiHash<QString, QString> signatures; 0238 }; 0239 0240 class File 0241 { 0242 public: 0243 File() 0244 : size(0) 0245 { 0246 } 0247 0248 void load(const QDomElement &e); 0249 void save(QDomElement &e) const; 0250 0251 void clear(); 0252 0253 bool isValid() const; 0254 0255 /** 0256 * Controls if the name attribute is valid, i.e. it is not empty and 0257 * does not contain any directory traversal directives or information, 0258 * as described in the Metalink 4.0 specification 4.1.2.1. 0259 */ 0260 bool isValidNameAttribute() const; 0261 0262 QString name; 0263 Verification verification; 0264 KIO::filesize_t size; 0265 CommonData data; 0266 Resources resources; 0267 }; 0268 0269 class Files 0270 { 0271 public: 0272 Files() 0273 { 0274 } 0275 0276 bool isValid() const; 0277 0278 void load(const QDomElement &e); 0279 void save(QDomElement &e) const; 0280 0281 void clear(); 0282 0283 QList<File> files; 0284 }; 0285 0286 class Metalink 0287 { 0288 public: 0289 Metalink() 0290 : dynamic(false) 0291 { 0292 } 0293 0294 /** 0295 * checks if the minimum requirements of a metalink are met 0296 * @return true if the minimum requirements are met 0297 */ 0298 bool isValid() const; 0299 0300 void load(const QDomElement &e); 0301 0302 /** 0303 * Save the metalink 0304 * @return the QDomDocument containing the metalink 0305 */ 0306 QDomDocument save() const; 0307 0308 void clear(); 0309 0310 bool dynamic; 0311 QString xmlns; // the xmlns value is ignored when saving, instead the data format described in the specification is always used 0312 DateConstruct published; // when the metalink was published 0313 QUrl origin; 0314 QString generator; 0315 DateConstruct updated; // when the metalink was updated 0316 Files files; 0317 0318 static const QString KGET_DESCRIPTION; 0319 static const uint MAX_URL_PRIORITY; // maximum priority a Metalink 4.0 Url or Metaurl can have, not to be mixed up with the highest priority 0320 }; 0321 0322 /** 0323 * @class Metalink_v3 0324 * Metalink version 3.0 2nd ed 0325 * Used only for loading and saving, uses itself Metalink internally 0326 */ 0327 class Metalink_v3 0328 { 0329 public: 0330 Metalink_v3(); 0331 0332 Metalink metalink(); 0333 void setMetalink(const Metalink &metalink); 0334 0335 void load(const QDomElement &e); 0336 0337 /** 0338 * Save the metalink 0339 * @return the QDomDocument containing the metalink 0340 */ 0341 QDomDocument save() const; 0342 0343 private: 0344 void parseFiles(const QDomElement &e); 0345 Resources parseResources(const QDomElement &e); 0346 DateConstruct parseDateConstruct(const QString &data); 0347 CommonData parseCommonData(const QDomElement &e); 0348 0349 /** 0350 * Inherits CommonData, the inheritor inherits every settings 0351 * from the ancestor it has not set itself 0352 */ 0353 void inheritCommonData(const CommonData &ancestor, CommonData *inheritor); 0354 0355 void saveFiles(QDomElement &e) const; 0356 void saveResources(const Resources &resources, QDomElement &e) const; 0357 void saveVerification(const Verification &verification, QDomElement &e) const; 0358 void saveCommonData(const CommonData &data, QDomElement &e) const; 0359 QString dateConstructToString(const DateConstruct &date) const; 0360 0361 private: 0362 Metalink m_metalink; 0363 static const uint MAX_PREFERENCE; 0364 }; 0365 0366 /** 0367 * This class can handle the loading and saving of metalinks on the filesystem 0368 */ 0369 class HandleMetalink 0370 { 0371 public: 0372 /** 0373 * Loads destination into metalink 0374 * @param destination the place of the metalink in the filesystem 0375 * @param metalink the instance of Metalink where the metalink will be stored 0376 * @return return true if it worked 0377 */ 0378 static bool load(const QUrl &destination, Metalink *metalink); 0379 0380 /** 0381 * Loads data into metalink 0382 * @param data the contents of a metalink 0383 * @param metalink the instance of Metalink where the metalink will be stored 0384 * @return return true if it worked 0385 */ 0386 static bool load(const QByteArray &data, Metalink *metalink); 0387 0388 /** 0389 * Saves metalink to destination 0390 * @param destination the place where the metlink will be saved, the ending defines 0391 * what version should be used: *.meta4 --> Metalink 4.0; *.metalink --> Metalink 3.0 0392 * @param metalink the instance of metalink that will be written to the filesystem 0393 * @return return true if it worked 0394 */ 0395 static bool save(const QUrl &destination, Metalink *metalink); 0396 }; 0397 0398 class MetalinkHttpParser : public QObject 0399 { 0400 Q_OBJECT 0401 public: 0402 MetalinkHttpParser(const QUrl &Url) 0403 : m_Url(Url) 0404 , m_MetalinkHSatus(false) 0405 , m_EtagValue(QString("")) 0406 { 0407 checkMetalinkHttp(); 0408 } 0409 0410 ~MetalinkHttpParser() override; 0411 0412 /** 0413 * @return true if m_Url is a metalink/http supported URL. 0414 */ 0415 0416 bool isMetalinkHttp(); 0417 0418 /** 0419 * @return the Url m_Url which is being tested for metalink 0420 */ 0421 0422 QUrl getUrl(); 0423 QMultiMap<QString, QString> *getHeaderInfo(); 0424 0425 /** 0426 * @return Returns the ETag if present in the HTTP headers 0427 */ 0428 0429 QString *getEtag(); 0430 0431 private Q_SLOTS: 0432 void slotHeaderResult(KJob *kjob); 0433 void checkMetalinkHttp(); 0434 void detectMime(KIO::Job *job, const QString &type); 0435 void slotRedirection(KIO::Job *, const QUrl &); 0436 0437 private: 0438 QUrl m_Url; 0439 QUrl m_redirectionUrl; 0440 bool m_MetalinkHSatus; 0441 QEventLoop m_loop; 0442 QMultiMap<QString, QString> m_headerInfo; 0443 QString m_EtagValue; 0444 0445 /** 0446 * Parsees the Metalink values from QString to the Map 0447 * @param Value of the QString ie raw HTTP headers 0448 */ 0449 void parseHeaders(const QString &); 0450 0451 /** 0452 * Sets the status of m_MetalinkHStatus to true if the URL is a Metalink 0453 */ 0454 void setMetalinkHSatus(); 0455 }; 0456 0457 class HttpLinkHeader : public Metaurl 0458 { 0459 public: 0460 HttpLinkHeader(const QString &headerLine); 0461 0462 QString reltype; 0463 bool pref; 0464 int depth; 0465 QString geo; 0466 0467 /** 0468 * Loads information from a header value into metalink header structure. 0469 * @param line Value of the "link" HTTP header response. 0470 */ 0471 void parseHeaderLine(const QString &); 0472 0473 bool operator<(const HttpLinkHeader &) const; 0474 }; 0475 0476 } 0477 0478 #endif // Metalinker_H