• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIOSlave

kcookieserver.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of KDE
00003 
00004   Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022  */
00023 //----------------------------------------------------------------------------
00024 //
00025 // KDE Cookie Server
00026 
00027 #include "kcookieserver.h"
00028 
00029 #define SAVE_DELAY 3 // Save after 3 minutes
00030 
00031 #include <unistd.h>
00032 
00033 #include <QtCore/QTimer>
00034 #include <QtCore/QFile>
00035 
00036 #include <QtDBus/QtDBus>
00037 
00038 #include <kconfig.h>
00039 #include <kdebug.h>
00040 #include <kcmdlineargs.h>
00041 #include <kstandarddirs.h>
00042 
00043 #include "kcookiejar.h"
00044 #include "kcookiewin.h"
00045 #include "kcookieserveradaptor.h"
00046 #include <kpluginfactory.h>
00047 #include <kpluginloader.h>
00048 
00049 K_PLUGIN_FACTORY(KdedCookieServerFactory,
00050                  registerPlugin<KCookieServer>();
00051     )
00052 K_EXPORT_PLUGIN(KdedCookieServerFactory("kcookiejar"))
00053 
00054 // Cookie field indexes
00055 enum CookieDetails { CF_DOMAIN=0, CF_PATH, CF_NAME, CF_HOST,
00056                      CF_VALUE, CF_EXPIRE, CF_PROVER, CF_SECURE };
00057 
00058 
00059 class CookieRequest {
00060 public:
00061    QDBusMessage reply;
00062    QString url;
00063    bool DOM;
00064    qlonglong windowId;
00065 };
00066 
00067 template class  QList<CookieRequest*>;
00068 
00069 class RequestList : public QList<CookieRequest*>
00070 {
00071 public:
00072    RequestList() : QList<CookieRequest*>() { }
00073 };
00074 
00075 KCookieServer::KCookieServer(QObject* parent, const QList<QVariant>&)
00076     : KDEDModule(parent)
00077 {
00078    (void)new KCookieServerAdaptor(this);
00079    mCookieJar = new KCookieJar;
00080    mPendingCookies = new KHttpCookieList;
00081    mRequestList = new RequestList;
00082    mAdvicePending = false;
00083    mTimer = new QTimer();
00084    mTimer->setSingleShot(true);
00085    connect(mTimer, SIGNAL( timeout()), SLOT( slotSave()));
00086    mConfig = new KConfig("kcookiejarrc");
00087    mCookieJar->loadConfig( mConfig );
00088 
00089    QString filename = KStandardDirs::locateLocal("data", "kcookiejar/cookies");
00090 
00091    // Stay backwards compatible!
00092    QString filenameOld = KStandardDirs::locate("data", "kfm/cookies");
00093    if (!filenameOld.isEmpty())
00094    {
00095       mCookieJar->loadCookies( filenameOld );
00096       if (mCookieJar->saveCookies( filename))
00097       {
00098          unlink(QFile::encodeName(filenameOld)); // Remove old kfm cookie file
00099       }
00100    }
00101    else
00102    {
00103       mCookieJar->loadCookies( filename);
00104    }
00105    connect(this, SIGNAL(windowUnregistered(qlonglong)),
00106            this, SLOT(slotDeleteSessionCookies(qlonglong)));
00107 }
00108 
00109 KCookieServer::~KCookieServer()
00110 {
00111    slotSave();
00112    delete mCookieJar;
00113    delete mTimer;
00114    delete mPendingCookies;
00115    delete mConfig;
00116 }
00117 
00118 bool KCookieServer::cookiesPending( const QString &url, KHttpCookieList *cookieList )
00119 {
00120     QString fqdn;
00121     QString path;
00122     // Check whether 'url' has cookies on the pending list
00123     if (mPendingCookies->isEmpty())
00124         return false;
00125     if (!KCookieJar::parseUrl(url, fqdn, path))
00126         return false;
00127 
00128     QStringList domains;
00129     mCookieJar->extractDomains(fqdn, domains);
00130     Q_FOREACH(const KHttpCookie& cookie, *mPendingCookies) {
00131         if (cookie.match( fqdn, domains, path)) {
00132             if (!cookieList)
00133                 return true;
00134             cookieList->append(cookie);
00135         }
00136     }
00137     if (!cookieList)
00138         return false;
00139     return cookieList->isEmpty();
00140 }
00141 
00142 void KCookieServer::addCookies( const QString &url, const QByteArray &cookieHeader,
00143                                qlonglong windowId, bool useDOMFormat )
00144 {
00145     KHttpCookieList cookieList;
00146     if (useDOMFormat)
00147        cookieList = mCookieJar->makeDOMCookies(url, cookieHeader, windowId);
00148     else
00149        cookieList = mCookieJar->makeCookies(url, cookieHeader, windowId);
00150 
00151     checkCookies(&cookieList);
00152 
00153     *mPendingCookies += cookieList;
00154 
00155     if (!mAdvicePending)
00156     {
00157        mAdvicePending = true;
00158        while (!mPendingCookies->isEmpty())
00159        {
00160           checkCookies(0);
00161        }
00162        mAdvicePending = false;
00163     }
00164 }
00165 
00166 void KCookieServer::checkCookies( KHttpCookieList *cookieList)
00167 {
00168     KHttpCookieList *list;
00169 
00170     if (cookieList)
00171        list = cookieList;
00172     else
00173        list = mPendingCookies;
00174 
00175     QMutableListIterator<KHttpCookie> cookieIterator(*list);
00176     while (cookieIterator.hasNext()) {
00177         KHttpCookie& cookie = cookieIterator.next();
00178         const KCookieAdvice advice = mCookieJar->cookieAdvice(cookie);
00179         switch(advice) {
00180         case KCookieAccept:
00181             mCookieJar->addCookie(cookie);
00182             cookieIterator.remove();
00183             break;
00184 
00185         case KCookieReject:
00186             cookieIterator.remove();
00187             break;
00188 
00189         default:
00190             break;
00191         }
00192     }
00193 
00194     if (cookieList || list->isEmpty())
00195        return;
00196 
00197     const KHttpCookie& currentCookie = mPendingCookies->first();
00198 
00199     KHttpCookieList currentList;
00200     currentList.append(currentCookie);
00201     QString currentHost = currentCookie.host();
00202 
00203     Q_FOREACH(const KHttpCookie& cookie, *mPendingCookies) {
00204         if (cookie.host() == currentHost) {
00205             currentList.append(cookie);
00206         }
00207     }
00208 
00209     KCookieWin *kw = new KCookieWin( 0L, currentList,
00210                                      mCookieJar->preferredDefaultPolicy(),
00211                                      mCookieJar->showCookieDetails() );
00212     KCookieAdvice userAdvice = kw->advice(mCookieJar, currentCookie);
00213     delete kw;
00214     // Save the cookie config if it has changed
00215     mCookieJar->saveConfig( mConfig );
00216 
00217     // Apply the user's choice to all cookies that are currently
00218     // queued for this host.
00219     QMutableListIterator<KHttpCookie> cookieIterator2(*mPendingCookies);
00220     while (cookieIterator2.hasNext()) {
00221         KHttpCookie& cookie = cookieIterator2.next();
00222         if (cookie.host() != currentHost)
00223             continue;
00224         switch(userAdvice) {
00225            case KCookieAccept:
00226                mCookieJar->addCookie(cookie);
00227                cookieIterator2.remove();
00228                break;
00229 
00230            case KCookieReject:
00231                cookieIterator2.remove();
00232                break;
00233 
00234            default:
00235                kWarning() << "userAdvice not accept or reject, this should never happen!";
00236                break;
00237         }
00238     }
00239 
00240     // Check if we can handle any request
00241     QMutableListIterator<CookieRequest *> requestIterator(*mRequestList);
00242     while (requestIterator.hasNext()) {
00243         CookieRequest *request = requestIterator.next();
00244         if (!cookiesPending(request->url)) {
00245            const QString res = mCookieJar->findCookies(request->url, request->DOM, request->windowId);
00246 
00247            QDBusConnection::sessionBus().send(request->reply.createReply(res));
00248            delete request;
00249            requestIterator.remove();
00250         }
00251     }
00252 
00253     saveCookieJar();
00254 }
00255 
00256 void KCookieServer::slotSave()
00257 {
00258    if (mCookieJar->changed())
00259    {
00260       QString filename = KStandardDirs::locateLocal("data", "kcookiejar/cookies");
00261       mCookieJar->saveCookies(filename);
00262    }
00263 }
00264 
00265 void KCookieServer::saveCookieJar()
00266 {
00267     if( mTimer->isActive() )
00268         return;
00269 
00270     mTimer->start( 1000*60*SAVE_DELAY );
00271 }
00272 
00273 void KCookieServer::putCookie( QStringList& out, const KHttpCookie& cookie,
00274                                const QList<int>& fields )
00275 {
00276     foreach ( int i, fields ) {
00277        switch(i)
00278         {
00279          case CF_DOMAIN :
00280             out << cookie.domain();
00281             break;
00282          case CF_NAME :
00283             out << cookie.name();
00284             break;
00285          case CF_PATH :
00286             out << cookie.path();
00287             break;
00288          case CF_HOST :
00289             out << cookie.host();
00290             break;
00291          case CF_VALUE :
00292             out << cookie.value();
00293             break;
00294          case CF_EXPIRE :
00295             out << QString::number(cookie.expireDate());
00296             break;
00297          case CF_PROVER :
00298             out << QString::number(cookie.protocolVersion());
00299             break;
00300          case CF_SECURE :
00301             out << QString::number(cookie.isSecure() ? 1 : 0);
00302             break;
00303          default :
00304             out << QString();
00305         }
00306     }
00307 }
00308 
00309 bool KCookieServer::cookieMatches(const KHttpCookie& c,
00310                                   const QString &domain, const QString &fqdn,
00311                                   const QString &path, const QString &name)
00312 {
00313     const bool hasDomain = !domain.isEmpty();
00314     return
00315         ((hasDomain && c.domain() == domain) ||
00316          fqdn == c.host()) &&
00317         (c.path()   == path) &&
00318         (c.name()   == name) &&
00319         (!c.isExpired(time(0)));
00320 }
00321 
00322 
00323 // DBUS function
00324 QString KCookieServer::listCookies(const QString &url)
00325 {
00326     return findCookies(url, 0);
00327 }
00328 
00329 // DBUS function
00330 QString KCookieServer::findCookies(const QString &url, qlonglong windowId)
00331 {
00332    if (cookiesPending(url))
00333    {
00334       CookieRequest *request = new CookieRequest;
00335       message().setDelayedReply(true);
00336       request->reply = message();
00337       request->url = url;
00338       request->DOM = false;
00339       request->windowId = windowId;
00340       mRequestList->append( request );
00341       return QString(); // Talk to you later :-)
00342    }
00343 
00344    QString cookies = mCookieJar->findCookies(url, false, windowId);
00345    saveCookieJar();
00346    return cookies;
00347 }
00348 
00349 // DBUS function
00350 QStringList
00351 KCookieServer::findDomains()
00352 {
00353    QStringList result;
00354    const QStringList domains = mCookieJar->getDomainList();
00355    for ( QStringList::ConstIterator domIt = domains.begin();
00356          domIt != domains.end(); ++domIt )
00357    {
00358        // Ignore domains that have policy set for but contain
00359        // no cookies whatsoever...
00360        const KHttpCookieList* list =  mCookieJar->getCookieList(*domIt, "");
00361        if ( list && !list->isEmpty() )
00362           result << *domIt;
00363    }
00364    return result;
00365 }
00366 
00367 // DBUS function
00368 QStringList
00369 KCookieServer::findCookies(const QList<int> &fields,
00370                            const QString &domain,
00371                            const QString &fqdn,
00372                            const QString &path,
00373                            const QString &name)
00374 {
00375     QStringList result;
00376     const bool allDomCookies = name.isEmpty();
00377 
00378     const KHttpCookieList* list =  mCookieJar->getCookieList(domain, fqdn);
00379     if (list && !list->isEmpty()) {
00380         Q_FOREACH(const KHttpCookie& cookie, *list) {
00381             if (!allDomCookies) {
00382                 if (cookieMatches(cookie, domain, fqdn, path, name)) {
00383                     putCookie(result, cookie, fields);
00384                     break;
00385                 }
00386             } else {
00387                 putCookie(result, cookie, fields);
00388             }
00389         }
00390     }
00391     return result;
00392 }
00393 
00394 // DBUS function
00395 QString
00396 KCookieServer::findDOMCookies(const QString &url)
00397 {
00398    return findDOMCookies(url, 0);
00399 }
00400 
00401 // DBUS function
00402 QString
00403 KCookieServer::findDOMCookies(const QString &url, qlonglong windowId)
00404 {
00405    // We don't wait for pending cookies because it locks up konqueror
00406    // which can cause a deadlock if it happens to have a popup-menu up.
00407    // Instead we just return pending cookies as if they had been accepted already.
00408    KHttpCookieList pendingCookies;
00409    cookiesPending(url, &pendingCookies);
00410 
00411    return mCookieJar->findCookies(url, true, windowId, &pendingCookies);
00412 }
00413 
00414 // DBUS function
00415 void
00416 KCookieServer::addCookies(const QString &arg1, const QByteArray &arg2, qlonglong arg3)
00417 {
00418    addCookies(arg1, arg2, arg3, false);
00419 }
00420 
00421 // DBUS function
00422 void
00423 KCookieServer::deleteCookie(const QString &domain, const QString &fqdn,
00424                             const QString &path, const QString &name)
00425 {
00426     KHttpCookieList* cookieList = mCookieJar->getCookieList( domain, fqdn );
00427     if (cookieList && !cookieList->isEmpty()) {
00428         for (KHttpCookieList::iterator cookieIterator = cookieList->begin();
00429              cookieIterator != cookieList->end();
00430              ++cookieIterator ) {
00431             KHttpCookie& cookie = *cookieIterator;
00432             if (cookieMatches(cookie, domain, fqdn, path, name)) {
00433                 mCookieJar->eatCookie(cookieIterator);
00434                 saveCookieJar();
00435                 break;
00436             }
00437         }
00438     }
00439 }
00440 
00441 // DBUS function
00442 void
00443 KCookieServer::deleteCookiesFromDomain(const QString &domain)
00444 {
00445    mCookieJar->eatCookiesForDomain(domain);
00446    saveCookieJar();
00447 }
00448 
00449 
00450 // Qt function
00451 void
00452 KCookieServer::slotDeleteSessionCookies( qlonglong windowId )
00453 {
00454    deleteSessionCookies(windowId);
00455 }
00456 
00457 // DBUS function
00458 void
00459 KCookieServer::deleteSessionCookies( qlonglong windowId )
00460 {
00461   mCookieJar->eatSessionCookies( windowId );
00462   saveCookieJar();
00463 }
00464 
00465 void
00466 KCookieServer::deleteSessionCookiesFor(const QString &fqdn, qlonglong windowId)
00467 {
00468   mCookieJar->eatSessionCookies( fqdn, windowId );
00469   saveCookieJar();
00470 }
00471 
00472 // DBUS function
00473 void
00474 KCookieServer::deleteAllCookies()
00475 {
00476    mCookieJar->eatAllCookies();
00477    saveCookieJar();
00478 }
00479 
00480 // DBUS function
00481 void
00482 KCookieServer::addDOMCookies(const QString &url, const QByteArray &cookieHeader, qlonglong windowId)
00483 {
00484    addCookies(url, cookieHeader, windowId, true);
00485 }
00486 
00487 // DBUS function
00488 void
00489 KCookieServer::setDomainAdvice(const QString &url, const QString &advice)
00490 {
00491    QString fqdn;
00492    QString dummy;
00493    if (KCookieJar::parseUrl(url, fqdn, dummy))
00494    {
00495       QStringList domains;
00496       mCookieJar->extractDomains(fqdn, domains);
00497 
00498       mCookieJar->setDomainAdvice(domains[domains.count() > 3 ? 3 : 0],
00499                                   KCookieJar::strToAdvice(advice));
00500       // Save the cookie config if it has changed
00501       mCookieJar->saveConfig( mConfig );
00502    }
00503 }
00504 
00505 // DBUS function
00506 QString
00507 KCookieServer::getDomainAdvice(const QString &url)
00508 {
00509    KCookieAdvice advice = KCookieDunno;
00510    QString fqdn;
00511    QString dummy;
00512    if (KCookieJar::parseUrl(url, fqdn, dummy))
00513    {
00514       QStringList domains;
00515       mCookieJar->extractDomains(fqdn, domains);
00516 
00517       QStringList::ConstIterator it = domains.constBegin();
00518       while ( (advice == KCookieDunno) && (it != domains.constEnd()) )
00519       {
00520          // Always check advice in both ".domain" and "domain". Note
00521          // that we only want to check "domain" if it matches the
00522          // fqdn of the requested URL.
00523          if ( (*it)[0] == '.' || (*it) == fqdn )
00524             advice = mCookieJar->getDomainAdvice(*it);
00525          ++it;
00526       }
00527       if (advice == KCookieDunno)
00528          advice = mCookieJar->getGlobalAdvice();
00529    }
00530    return KCookieJar::adviceToStr(advice);
00531 }
00532 
00533 // DBUS function
00534 void
00535 KCookieServer::reloadPolicy()
00536 {
00537    mCookieJar->loadConfig( mConfig, true );
00538 }
00539 
00540 // DBUS function
00541 void
00542 KCookieServer::shutdown()
00543 {
00544    deleteLater();
00545 }
00546 
00547 #include "kcookieserver.moc"
00548 

KIOSlave

Skip menu "KIOSlave"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal