File indexing completed on 2025-11-09 11:08:56
0001 /* 0002 This file is part of the KDE File Manager 0003 SPDX-FileCopyrightText: 1998 Waldo Bastian <bastian@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only 0006 */ 0007 0008 // KDE File Manager -- HTTP Cookies 0009 0010 #ifndef KCOOKIEJAR_H 0011 #define KCOOKIEJAR_H 0012 0013 #include <QHash> 0014 #include <QSet> 0015 #include <QString> 0016 #include <QStringList> 0017 #include <qwindowdefs.h> //WId 0018 0019 #include <QLoggingCategory> 0020 Q_DECLARE_LOGGING_CATEGORY(KIO_COOKIEJAR) 0021 0022 class KConfig; 0023 class KCookieJar; 0024 class KHttpCookie; 0025 class KHttpCookieList; 0026 0027 typedef KHttpCookie *KHttpCookiePtr; 0028 0029 enum KCookieAdvice { 0030 KCookieDunno = 0, 0031 KCookieAccept, 0032 KCookieAcceptForSession, 0033 KCookieReject, 0034 KCookieAsk, 0035 }; 0036 0037 class KHttpCookie 0038 { 0039 friend class KCookieJar; 0040 friend class KHttpCookieList; 0041 friend QDebug operator<<(QDebug, const KHttpCookie &); // for cookieStr() 0042 0043 protected: 0044 QString mHost; 0045 QString mDomain; 0046 QString mPath; 0047 QString mName; 0048 QString mValue; 0049 qint64 mExpireDate; 0050 int mProtocolVersion; 0051 bool mSecure; 0052 bool mCrossDomain; 0053 bool mHttpOnly; 0054 bool mExplicitPath; 0055 QList<WId> mWindowIds; 0056 QList<int> mPorts; 0057 KCookieAdvice mUserSelectedAdvice; 0058 0059 QString cookieStr(bool useDOMFormat) const; 0060 0061 public: 0062 explicit KHttpCookie(const QString &_host = QString(), 0063 const QString &_domain = QString(), 0064 const QString &_path = QString(), 0065 const QString &_name = QString(), 0066 const QString &_value = QString(), 0067 qint64 _expireDate = 0, 0068 int _protocolVersion = 0, 0069 bool _secure = false, 0070 bool _httpOnly = false, 0071 bool _explicitPath = false); 0072 0073 QString domain() const 0074 { 0075 return mDomain; 0076 } 0077 QString host() const 0078 { 0079 return mHost; 0080 } 0081 QString path() const 0082 { 0083 return mPath; 0084 } 0085 QString name() const 0086 { 0087 return mName; 0088 } 0089 QString value() const 0090 { 0091 return mValue; 0092 } 0093 QList<WId> &windowIds() 0094 { 0095 return mWindowIds; 0096 } 0097 const QList<WId> &windowIds() const 0098 { 0099 return mWindowIds; 0100 } 0101 const QList<int> &ports() const 0102 { 0103 return mPorts; 0104 } 0105 void fixDomain(const QString &domain) 0106 { 0107 mDomain = domain; 0108 } 0109 qint64 expireDate() const 0110 { 0111 return mExpireDate; 0112 } 0113 int protocolVersion() const 0114 { 0115 return mProtocolVersion; 0116 } 0117 bool isSecure() const 0118 { 0119 return mSecure; 0120 } 0121 /** 0122 * If currentDate is -1, the default, then the current timestamp in UTC 0123 * is used for comparison against this cookie's expiration date. 0124 */ 0125 bool isExpired(qint64 currentDate = -1) const; 0126 bool isCrossDomain() const 0127 { 0128 return mCrossDomain; 0129 } 0130 bool isHttpOnly() const 0131 { 0132 return mHttpOnly; 0133 } 0134 bool hasExplicitPath() const 0135 { 0136 return mExplicitPath; 0137 } 0138 bool match(const QString &fqdn, const QStringList &domainList, const QString &path, int port = -1) const; 0139 0140 KCookieAdvice getUserSelectedAdvice() const 0141 { 0142 return mUserSelectedAdvice; 0143 } 0144 void setUserSelectedAdvice(KCookieAdvice advice) 0145 { 0146 mUserSelectedAdvice = advice; 0147 } 0148 }; 0149 0150 QDebug operator<<(QDebug, const KHttpCookie &); 0151 0152 class KHttpCookieList : public QList<KHttpCookie> 0153 { 0154 public: 0155 KHttpCookieList() 0156 : QList<KHttpCookie>() 0157 , advice(KCookieDunno) 0158 { 0159 } 0160 virtual ~KHttpCookieList() 0161 { 0162 } 0163 0164 KCookieAdvice getAdvice() const 0165 { 0166 return advice; 0167 } 0168 void setAdvice(KCookieAdvice _advice) 0169 { 0170 advice = _advice; 0171 } 0172 0173 private: 0174 KCookieAdvice advice; 0175 }; 0176 0177 QDebug operator<<(QDebug, const KHttpCookieList &); 0178 0179 class KCookieJar 0180 { 0181 public: 0182 /** 0183 * Constructs a new cookie jar 0184 * 0185 * One jar should be enough for all cookies. 0186 */ 0187 KCookieJar(); 0188 0189 /** 0190 * Destructs the cookie jar 0191 * 0192 * Poor little cookies, they will all be eaten by the cookie monster! 0193 */ 0194 ~KCookieJar(); 0195 0196 KCookieJar(const KCookieJar &) = delete; 0197 KCookieJar &operator=(const KCookieJar &) = delete; 0198 0199 /** 0200 * Returns whether the cookiejar has been changed 0201 */ 0202 bool changed() const 0203 { 0204 return m_cookiesChanged || m_configChanged; 0205 } 0206 0207 /** 0208 * Store all the cookies in a safe(?) place 0209 */ 0210 bool saveCookies(const QString &_filename); 0211 0212 /** 0213 * Load all the cookies from file and add them to the cookie jar. 0214 */ 0215 bool loadCookies(const QString &_filename); 0216 0217 /** 0218 * Save the cookie configuration 0219 */ 0220 void saveConfig(KConfig *_config); 0221 0222 /** 0223 * Load the cookie configuration 0224 */ 0225 void loadConfig(KConfig *_config, bool reparse = false); 0226 0227 /** 0228 * Looks for cookies in the cookie jar which are appropriate for _url. 0229 * Returned is a string containing all appropriate cookies in a format 0230 * which can be added to a HTTP-header without any additional processing. 0231 * 0232 * If @p useDOMFormat is true, the string is formatted in a format 0233 * in compliance with the DOM standard. 0234 * @p pendingCookies contains a list of cookies that have not been 0235 * approved yet by the user but that will be included in the result 0236 * none the less. 0237 */ 0238 QString findCookies(const QString &_url, bool useDOMFormat, WId windowId, KHttpCookieList *pendingCookies = nullptr); 0239 0240 /** 0241 * This function parses cookie_headers and returns a linked list of 0242 * valid KHttpCookie objects for all cookies found in cookie_headers. 0243 * If no cookies could be found 0 is returned. 0244 * 0245 * cookie_headers should be a concatenation of all lines of a HTTP-header 0246 * which start with "Set-Cookie". The lines should be separated by '\n's. 0247 */ 0248 KHttpCookieList makeCookies(const QString &_url, const QByteArray &cookie_headers, WId windowId); 0249 0250 /** 0251 * This function parses cookie_headers and returns a linked list of 0252 * valid KHttpCookie objects for all cookies found in cookie_headers. 0253 * If no cookies could be found 0 is returned. 0254 * 0255 * cookie_domstr should be a concatenation of "name=value" pairs, separated 0256 * by a semicolon ';'. 0257 */ 0258 KHttpCookieList makeDOMCookies(const QString &_url, const QByteArray &cookie_domstr, WId windowId); 0259 0260 /** 0261 * This function hands a KHttpCookie object over to the cookie jar. 0262 */ 0263 void addCookie(KHttpCookie &cookie); 0264 0265 /** 0266 * This function tells whether a single KHttpCookie object should 0267 * be considered persistent. Persistent cookies do not get deleted 0268 * at the end of the session and are saved on disk. 0269 */ 0270 bool cookieIsPersistent(const KHttpCookie &cookie) const; 0271 0272 /** 0273 * This function advises whether a single KHttpCookie object should 0274 * be added to the cookie jar. 0275 * 0276 * Possible return values are: 0277 * - KCookieAccept, the cookie should be added 0278 * - KCookieAcceptForSession, the cookie should be added as session cookie 0279 * - KCookieReject, the cookie should not be added 0280 * - KCookieAsk, the user should decide what to do 0281 * 0282 * Before sending cookies back to a server this function is consulted, 0283 * so that cookies having advice KCookieReject are not sent back. 0284 */ 0285 KCookieAdvice cookieAdvice(const KHttpCookie &cookie) const; 0286 0287 /** 0288 * This function gets the advice for all cookies originating from 0289 * _domain. 0290 * 0291 * - KCookieDunno, no specific advice for _domain 0292 * - KCookieAccept, accept all cookies for _domain 0293 * - KCookieAcceptForSession, accept all cookies for _domain as session cookies 0294 * - KCookieReject, reject all cookies for _domain 0295 * - KCookieAsk, the user decides what to do with cookies for _domain 0296 */ 0297 KCookieAdvice getDomainAdvice(const QString &_domain) const; 0298 0299 /** 0300 * This function sets the advice for all cookies originating from 0301 * _domain. 0302 * 0303 * _advice can have the following values: 0304 * - KCookieDunno, no specific advice for _domain 0305 * - KCookieAccept, accept all cookies for _domain 0306 * - KCookieAcceptForSession, accept all cookies for _domain as session cookies 0307 * - KCookieReject, reject all cookies for _domain 0308 * - KCookieAsk, the user decides what to do with cookies for _domain 0309 */ 0310 void setDomainAdvice(const QString &domain, KCookieAdvice advice); 0311 0312 /** 0313 * This function sets the advice for all cookies originating from 0314 * the same domain as _cookie 0315 * 0316 * _advice can have the following values: 0317 * - KCookieDunno, no specific advice for _domain 0318 * - KCookieAccept, accept all cookies for _domain 0319 * - KCookieAcceptForSession, accept all cookies for _domain as session cookies 0320 * - KCookieReject, reject all cookies for _domain 0321 * - KCookieAsk, the user decides what to do with cookies for _domain 0322 */ 0323 void setDomainAdvice(const KHttpCookie &_cookie, KCookieAdvice _advice); 0324 0325 /** 0326 * Get the global advice for cookies 0327 * 0328 * The returned advice can have the following values: 0329 * - KCookieAccept, accept cookies 0330 * - KCookieAcceptForSession, accept cookies as session cookies 0331 * - KCookieReject, reject cookies 0332 * - KCookieAsk, the user decides what to do with cookies 0333 * 0334 * The global advice is used if the domain has no advice set. 0335 */ 0336 KCookieAdvice getGlobalAdvice() const 0337 { 0338 return m_globalAdvice; 0339 } 0340 0341 /** 0342 * This function sets the global advice for cookies 0343 * 0344 * _advice can have the following values: 0345 * - KCookieAccept, accept cookies 0346 * - KCookieAcceptForSession, accept cookies as session cookies 0347 * - KCookieReject, reject cookies 0348 * - KCookieAsk, the user decides what to do with cookies 0349 * 0350 * The global advice is used if the domain has no advice set. 0351 */ 0352 void setGlobalAdvice(KCookieAdvice _advice); 0353 0354 /** 0355 * Get a list of all domains known to the cookie jar. 0356 * A domain is known to the cookie jar if: 0357 * - It has a cookie originating from the domain 0358 * - It has a specific advice set for the domain 0359 */ 0360 const QStringList &getDomainList(); 0361 0362 /** 0363 * Get a list of all cookies in the cookie jar originating from _domain. 0364 */ 0365 KHttpCookieList *getCookieList(const QString &_domain, const QString &_fqdn); 0366 0367 /** 0368 * Remove & delete a cookie from the jar. 0369 * 0370 * cookieIterator should be one of the entries in a KHttpCookieList. 0371 * Update your KHttpCookieList by calling getCookieList after 0372 * calling this function. 0373 */ 0374 void eatCookie(const KHttpCookieList::iterator &cookieIterator); 0375 0376 /** 0377 * Remove & delete all cookies for @p domain. 0378 */ 0379 void eatCookiesForDomain(const QString &domain); 0380 0381 /** 0382 * Remove & delete all cookies 0383 */ 0384 void eatAllCookies(); 0385 0386 /** 0387 * Removes all end of session cookies set by the 0388 * session @p windId. 0389 */ 0390 void eatSessionCookies(long windowId); 0391 0392 /** 0393 * Removes all end of session cookies set by the 0394 * session @p windId. 0395 */ 0396 void eatSessionCookies(const QString &fqdn, WId windowId, bool isFQDN = true); 0397 0398 /** 0399 * Parses _url and returns the FQDN (_fqdn) and path (_path). 0400 */ 0401 static bool parseUrl(const QString &_url, QString &_fqdn, QString &_path, int *port = nullptr); 0402 0403 /** 0404 * Returns a list of domains in @p _domainList relevant for this host. 0405 * The list is sorted with the FQDN listed first and the top-most 0406 * domain listed last 0407 */ 0408 void extractDomains(const QString &_fqdn, QStringList &_domainList) const; 0409 0410 static QString adviceToStr(KCookieAdvice _advice); 0411 static KCookieAdvice strToAdvice(const QString &_str); 0412 0413 enum KCookieDefaultPolicy { 0414 ApplyToShownCookiesOnly = 0, 0415 ApplyToCookiesFromDomain = 1, 0416 ApplyToAllCookies = 2, 0417 }; 0418 /** Returns the user's choice in the cookie window */ 0419 KCookieDefaultPolicy preferredDefaultPolicy() const 0420 { 0421 return m_preferredPolicy; 0422 } 0423 0424 /** Returns the */ 0425 bool showCookieDetails() const 0426 { 0427 return m_showCookieDetails; 0428 } 0429 0430 /** 0431 * Sets the user's default preference cookie policy. 0432 */ 0433 void setPreferredDefaultPolicy(KCookieDefaultPolicy value) 0434 { 0435 m_preferredPolicy = value; 0436 } 0437 0438 /** 0439 * Sets the user's preference of level of detail displayed 0440 * by the cookie dialog. 0441 */ 0442 void setShowCookieDetails(bool value) 0443 { 0444 m_showCookieDetails = value; 0445 } 0446 0447 protected: 0448 void stripDomain(const QString &_fqdn, QString &_domain) const; 0449 QString stripDomain(const KHttpCookie &cookie) const; 0450 0451 protected: 0452 QStringList m_domainList; 0453 KCookieAdvice m_globalAdvice; 0454 QHash<QString, KHttpCookieList *> m_cookieDomains; 0455 QSet<QString> m_twoLevelTLD; 0456 QSet<QString> m_gTLDs; 0457 0458 bool m_configChanged; 0459 bool m_cookiesChanged; 0460 bool m_showCookieDetails; 0461 bool m_rejectCrossDomainCookies; 0462 bool m_autoAcceptSessionCookies; 0463 0464 KCookieDefaultPolicy m_preferredPolicy; 0465 }; 0466 #endif