• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • 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 // $Id: kcookieserver.cpp 707375 2007-09-01 17:19:13Z adawit $
00027 
00028 #define SAVE_DELAY 3 // Save after 3 minutes
00029 
00030 #include <unistd.h>
00031 
00032 #include <qtimer.h>
00033 #include <qptrlist.h>
00034 #include <qfile.h>
00035 
00036 #include <dcopclient.h>
00037 
00038 #include <kconfig.h>
00039 #include <kdebug.h>
00040 #include <kapplication.h>
00041 #include <kcmdlineargs.h>
00042 #include <kstandarddirs.h>
00043 
00044 #include "kcookiejar.h"
00045 #include "kcookiewin.h"
00046 #include "kcookieserver.h"
00047 
00048 extern "C" {
00049     KDE_EXPORT KDEDModule *create_kcookiejar(const QCString &name)
00050     {
00051        return new KCookieServer(name);
00052     }
00053 }
00054 
00055 
00056 // Cookie field indexes
00057 enum CookieDetails { CF_DOMAIN=0, CF_PATH, CF_NAME, CF_HOST,
00058                      CF_VALUE, CF_EXPIRE, CF_PROVER, CF_SECURE };
00059 
00060 
00061 class CookieRequest {
00062 public:
00063    DCOPClient *client;
00064    DCOPClientTransaction *transaction;
00065    QString url;
00066    bool DOM;
00067    long windowId;
00068 };
00069 
00070 template class  QPtrList<CookieRequest>;
00071 
00072 class RequestList : public QPtrList<CookieRequest>
00073 {
00074 public:
00075    RequestList() : QPtrList<CookieRequest>() { }
00076 };
00077 
00078 KCookieServer::KCookieServer(const QCString &name)
00079               :KDEDModule(name)
00080 {
00081    mOldCookieServer = new DCOPClient(); // backwards compatibility.
00082    mOldCookieServer->registerAs("kcookiejar", false);
00083    mOldCookieServer->setDaemonMode( true );
00084    mCookieJar = new KCookieJar;
00085    mPendingCookies = new KHttpCookieList;
00086    mPendingCookies->setAutoDelete(true);
00087    mRequestList = new RequestList;
00088    mAdvicePending = false;
00089    mTimer = new QTimer();
00090    connect( mTimer, SIGNAL( timeout()), SLOT( slotSave()));
00091    mConfig = new KConfig("kcookiejarrc");
00092    mCookieJar->loadConfig( mConfig );
00093 
00094    QString filename = locateLocal("data", "kcookiejar/cookies");
00095 
00096    // Stay backwards compatible!
00097    QString filenameOld = locate("data", "kfm/cookies");
00098    if (!filenameOld.isEmpty())
00099    {
00100       mCookieJar->loadCookies( filenameOld );
00101       if (mCookieJar->saveCookies( filename))
00102       {
00103          unlink(QFile::encodeName(filenameOld)); // Remove old kfm cookie file
00104       }
00105    }
00106    else
00107    {
00108       mCookieJar->loadCookies( filename);
00109    }
00110    connect(this, SIGNAL(windowUnregistered(long)),
00111            this, SLOT(slotDeleteSessionCookies(long)));
00112 }
00113 
00114 KCookieServer::~KCookieServer()
00115 {
00116    if (mCookieJar->changed())
00117       slotSave();
00118    delete mOldCookieServer;
00119    delete mCookieJar;
00120    delete mTimer;
00121    delete mPendingCookies;
00122    delete mConfig;
00123 }
00124 
00125 bool KCookieServer::cookiesPending( const QString &url, KHttpCookieList *cookieList )
00126 {
00127   QString fqdn;
00128   QStringList domains;
00129   QString path;
00130   // Check whether 'url' has cookies on the pending list
00131   if (mPendingCookies->isEmpty())
00132      return false;
00133   if (!KCookieJar::parseURL(url, fqdn, path))
00134      return false;
00135 
00136   mCookieJar->extractDomains( fqdn, domains );
00137   for( KHttpCookie *cookie = mPendingCookies->first();
00138        cookie != 0L;
00139        cookie = mPendingCookies->next())
00140   {
00141        if (cookie->match( fqdn, domains, path))
00142        {
00143           if (!cookieList)
00144              return true;
00145           cookieList->append(cookie);
00146        }
00147   }
00148   if (!cookieList)
00149      return false;
00150   return cookieList->isEmpty();
00151 }
00152 
00153 void KCookieServer::addCookies( const QString &url, const QCString &cookieHeader,
00154                                long windowId, bool useDOMFormat )
00155 {
00156     KHttpCookieList cookieList;
00157     if (useDOMFormat)
00158        cookieList = mCookieJar->makeDOMCookies(url, cookieHeader, windowId);
00159     else
00160        cookieList = mCookieJar->makeCookies(url, cookieHeader, windowId);
00161 
00162     checkCookies(&cookieList);
00163     
00164     for(KHttpCookiePtr cookie = cookieList.first(); cookie; cookie = cookieList.first())
00165        mPendingCookies->append(cookieList.take());
00166 
00167     if (!mAdvicePending)
00168     {
00169        mAdvicePending = true;
00170        while (!mPendingCookies->isEmpty())
00171        {
00172           checkCookies(0);
00173        }
00174        mAdvicePending = false;
00175     }
00176 }
00177 
00178 void KCookieServer::checkCookies( KHttpCookieList *cookieList)
00179 {
00180     KHttpCookieList *list;
00181     
00182     if (cookieList)
00183        list = cookieList;
00184     else
00185        list = mPendingCookies;
00186 
00187     KHttpCookiePtr cookie = list->first();
00188     while (cookie)
00189     {
00190         kdDebug(7104) << "checkCookies: Asking cookie advice for " << cookie->host() << endl;
00191         KCookieAdvice advice = mCookieJar->cookieAdvice(cookie);
00192         switch(advice)
00193         {
00194         case KCookieAccept:
00195             list->take();
00196             mCookieJar->addCookie(cookie);
00197             cookie = list->current();
00198             break;
00199 
00200         case KCookieReject:
00201             list->take();
00202             delete cookie;
00203             cookie = list->current();
00204             break;
00205 
00206         default:
00207             cookie = list->next();
00208             break;
00209         }
00210     }
00211     
00212     if (cookieList || list->isEmpty())
00213        return;
00214        
00215     KHttpCookiePtr currentCookie = mPendingCookies->first();
00216     
00217     KHttpCookieList currentList;
00218     currentList.append(currentCookie);
00219     QString currentHost = currentCookie->host();
00220 
00221     cookie = mPendingCookies->next();
00222     while (cookie)
00223     {
00224         if (cookie->host() == currentHost)
00225         {
00226             currentList.append(cookie);
00227         }
00228         cookie = mPendingCookies->next();
00229     }
00230 
00231     KCookieWin *kw = new KCookieWin( 0L, currentList,
00232                                      mCookieJar->preferredDefaultPolicy(),
00233                                      mCookieJar->showCookieDetails() );
00234     KCookieAdvice userAdvice = kw->advice(mCookieJar, currentCookie);
00235     delete kw;
00236     // Save the cookie config if it has changed
00237     mCookieJar->saveConfig( mConfig );
00238     
00239     // Apply the user's choice to all cookies that are currently
00240     // queued for this host.
00241     cookie = mPendingCookies->first();
00242     while (cookie)
00243     {
00244         if (cookie->host() == currentHost)
00245         {
00246            switch(userAdvice)
00247            {
00248            case KCookieAccept:
00249                mPendingCookies->take();
00250                mCookieJar->addCookie(cookie);
00251                cookie = mPendingCookies->current();
00252                break;
00253 
00254            case KCookieReject:
00255                mPendingCookies->take();
00256                delete cookie;
00257                cookie = mPendingCookies->current();
00258                break;
00259 
00260            default:
00261                qWarning(__FILE__":%d Problem!", __LINE__);
00262                cookie = mPendingCookies->next();
00263                break;
00264            }
00265         }
00266         else
00267         {
00268             cookie = mPendingCookies->next();
00269         }
00270     }
00271 
00272 
00273     // Check if we can handle any request
00274     for ( CookieRequest *request = mRequestList->first(); request;)
00275     {
00276         if (!cookiesPending( request->url ))
00277         {
00278            QCString replyType;
00279            QByteArray replyData;
00280            QString res = mCookieJar->findCookies( request->url, request->DOM, request->windowId );
00281 
00282            QDataStream stream2(replyData, IO_WriteOnly);
00283            stream2 << res;
00284            replyType = "QString";
00285            request->client->endTransaction( request->transaction,
00286                                             replyType, replyData);
00287            CookieRequest *tmp = request;
00288            request = mRequestList->next();
00289            mRequestList->removeRef( tmp );
00290            delete tmp;
00291         }
00292         else
00293         {
00294           request = mRequestList->next();
00295         }
00296     }
00297     if (mCookieJar->changed())
00298         saveCookieJar();
00299 }
00300 
00301 void KCookieServer::slotSave()
00302 {
00303    QString filename = locateLocal("data", "kcookiejar/cookies");
00304    mCookieJar->saveCookies(filename);
00305 }
00306 
00307 void KCookieServer::saveCookieJar()
00308 {
00309     if( mTimer->isActive() )
00310         return;
00311 
00312     mTimer->start( 1000*60*SAVE_DELAY, true );
00313 }
00314 
00315 void KCookieServer::putCookie( QStringList& out, KHttpCookie *cookie,
00316                                const QValueList<int>& fields )
00317 {
00318     QValueList<int>::ConstIterator i = fields.begin();
00319     for ( ; i != fields.end(); ++i )
00320     {
00321         switch(*i)
00322         {
00323          case CF_DOMAIN :
00324             out << cookie->domain();
00325             break;
00326          case CF_NAME :
00327             out << cookie->name();
00328             break;
00329          case CF_PATH :
00330             out << cookie->path();
00331             break;
00332          case CF_HOST :
00333             out << cookie->host();
00334             break;
00335          case CF_VALUE :
00336             out << cookie->value();
00337             break;
00338          case CF_EXPIRE :
00339             out << QString::number(cookie->expireDate());
00340             break;
00341          case CF_PROVER :
00342             out << QString::number(cookie->protocolVersion());
00343             break;
00344          case CF_SECURE :
00345             out << QString::number( cookie->isSecure() ? 1 : 0 );
00346             break;
00347          default :
00348             out << QString::null;
00349         }
00350     }
00351 }
00352 
00353 bool KCookieServer::cookieMatches( KHttpCookiePtr c,
00354                                    QString domain, QString fqdn,
00355                                    QString path, QString name )
00356 {
00357     if( c )
00358     {
00359         bool hasDomain = !domain.isEmpty();
00360         return
00361        ((hasDomain && c->domain() == domain) ||
00362         fqdn == c->host()) &&
00363        (c->path()   == path) &&
00364        (c->name()   == name) &&
00365        (!c->isExpired(time(0)));
00366     }
00367     return false;
00368 }
00369 
00370 // DCOP function
00371 QString
00372 KCookieServer::findCookies(QString url)
00373 {
00374   return findCookies(url, 0);
00375 }
00376 
00377 // DCOP function
00378 QString
00379 KCookieServer::findCookies(QString url, long windowId)
00380 {
00381    if (cookiesPending(url))
00382    {
00383       CookieRequest *request = new CookieRequest;
00384       request->client = callingDcopClient();
00385       request->transaction = request->client->beginTransaction();
00386       request->url = url;
00387       request->DOM = false;
00388       request->windowId = windowId;
00389       mRequestList->append( request );
00390       return QString::null; // Talk to you later :-)
00391    }
00392 
00393    QString cookies = mCookieJar->findCookies(url, false, windowId);
00394 
00395    if (mCookieJar->changed())
00396       saveCookieJar();
00397 
00398    return cookies;
00399 }
00400 
00401 // DCOP function
00402 QStringList
00403 KCookieServer::findDomains()
00404 {
00405    QStringList result;
00406    const QStringList domains = mCookieJar->getDomainList();
00407    for ( QStringList::ConstIterator domIt = domains.begin();
00408          domIt != domains.end(); ++domIt )
00409    {
00410        // Ignore domains that have policy set for but contain
00411        // no cookies whatsoever...
00412        const KHttpCookieList* list =  mCookieJar->getCookieList(*domIt, "");
00413        if ( list && !list->isEmpty() )
00414           result << *domIt;
00415    }
00416    return result;
00417 }
00418 
00419 // DCOP function
00420 QStringList
00421 KCookieServer::findCookies(QValueList<int> fields,
00422                            QString domain,
00423                            QString fqdn,
00424                            QString path,
00425                            QString name)
00426 {
00427    QStringList result;
00428    bool allDomCookies = name.isEmpty();
00429 
00430    const KHttpCookieList* list =  mCookieJar->getCookieList(domain, fqdn);
00431    if ( list && !list->isEmpty() )
00432    {
00433       QPtrListIterator<KHttpCookie>it( *list );
00434       for ( ; it.current(); ++it )
00435       {
00436          if ( !allDomCookies )
00437          {
00438             if ( cookieMatches(it.current(), domain, fqdn, path, name) )
00439             {
00440                putCookie(result, it.current(), fields);
00441                break;
00442             }
00443          }
00444          else
00445             putCookie(result, it.current(), fields);
00446       }
00447    }
00448    return result;
00449 }
00450 
00451 // DCOP function
00452 QString
00453 KCookieServer::findDOMCookies(QString url)
00454 {
00455    return findDOMCookies(url, 0);
00456 }
00457 
00458 // DCOP function
00459 QString
00460 KCookieServer::findDOMCookies(QString url, long windowId)
00461 {
00462    // We don't wait for pending cookies because it locks up konqueror 
00463    // which can cause a deadlock if it happens to have a popup-menu up.
00464    // Instead we just return pending cookies as if they had been accepted already.
00465    KHttpCookieList pendingCookies;
00466    cookiesPending(url, &pendingCookies);
00467 
00468    return mCookieJar->findCookies(url, true, windowId, &pendingCookies);
00469 }
00470 
00471 // DCOP function
00472 void
00473 KCookieServer::addCookies(QString arg1, QCString arg2, long arg3)
00474 {
00475    addCookies(arg1, arg2, arg3, false);
00476 }
00477 
00478 // DCOP function
00479 void
00480 KCookieServer::deleteCookie(QString domain, QString fqdn,
00481                             QString path, QString name)
00482 {
00483    const KHttpCookieList* list = mCookieJar->getCookieList( domain, fqdn );
00484    if ( list && !list->isEmpty() )
00485    {
00486       QPtrListIterator<KHttpCookie>it (*list);
00487       for ( ; it.current(); ++it )
00488       {
00489          if( cookieMatches(it.current(), domain, fqdn, path, name) )
00490          {
00491             mCookieJar->eatCookie( it.current() );
00492             saveCookieJar();
00493             break;
00494          }
00495       }
00496    }
00497 }
00498 
00499 // DCOP function
00500 void
00501 KCookieServer::deleteCookiesFromDomain(QString domain)
00502 {
00503    mCookieJar->eatCookiesForDomain(domain);
00504    saveCookieJar();
00505 }
00506 
00507 
00508 // Qt function
00509 void
00510 KCookieServer::slotDeleteSessionCookies( long windowId )
00511 {
00512    deleteSessionCookies(windowId);
00513 }
00514 
00515 // DCOP function
00516 void
00517 KCookieServer::deleteSessionCookies( long windowId )
00518 {
00519   mCookieJar->eatSessionCookies( windowId );
00520   saveCookieJar();
00521 }
00522 
00523 void
00524 KCookieServer::deleteSessionCookiesFor(QString fqdn, long windowId)
00525 {
00526   mCookieJar->eatSessionCookies( fqdn, windowId );
00527   saveCookieJar();
00528 }
00529 
00530 // DCOP function
00531 void
00532 KCookieServer::deleteAllCookies()
00533 {
00534    mCookieJar->eatAllCookies();
00535    saveCookieJar();
00536 }
00537 
00538 // DCOP function
00539 void
00540 KCookieServer::addDOMCookies(QString arg1, QCString arg2, long arg3)
00541 {
00542    addCookies(arg1, arg2, arg3, true);
00543 }
00544 
00545 // DCOP function
00546 void
00547 KCookieServer::setDomainAdvice(QString url, QString advice)
00548 {
00549    QString fqdn;
00550    QString dummy;
00551    if (KCookieJar::parseURL(url, fqdn, dummy))
00552    {
00553       QStringList domains;
00554       mCookieJar->extractDomains(fqdn, domains);
00555       
00556       mCookieJar->setDomainAdvice(domains[domains.count() > 3 ? 3 : 0],
00557                                   KCookieJar::strToAdvice(advice));
00558       // Save the cookie config if it has changed
00559       mCookieJar->saveConfig( mConfig );
00560    }
00561 }
00562 
00563 // DCOP function
00564 QString
00565 KCookieServer::getDomainAdvice(QString url)
00566 {
00567    KCookieAdvice advice = KCookieDunno;
00568    QString fqdn;
00569    QString dummy;
00570    if (KCookieJar::parseURL(url, fqdn, dummy))
00571    {
00572       QStringList domains;
00573       mCookieJar->extractDomains(fqdn, domains);
00574 
00575       QStringList::ConstIterator it = domains.begin();
00576       while ( (advice == KCookieDunno) && (it != domains.end()) )
00577       {
00578          // Always check advice in both ".domain" and "domain". Note
00579          // that we only want to check "domain" if it matches the
00580          // fqdn of the requested URL.
00581          if ( (*it)[0] == '.' || (*it) == fqdn )
00582             advice = mCookieJar->getDomainAdvice(*it);
00583          ++it;
00584       }
00585       if (advice == KCookieDunno)
00586          advice = mCookieJar->getGlobalAdvice();
00587    }
00588    return KCookieJar::adviceToStr(advice);
00589 }
00590 
00591 // DCOP function
00592 void
00593 KCookieServer::reloadPolicy()
00594 {
00595    mCookieJar->loadConfig( mConfig, true );
00596 }
00597 
00598 // DCOP function
00599 void
00600 KCookieServer::shutdown()
00601 {
00602    deleteLater();
00603 }
00604 
00605 #include "kcookieserver.moc"
00606 

kioslave

Skip menu "kioslave"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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