• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeioslave/http
 

tdeioslave/http

kcookiejar.cpp

00001 /* This file is part of the KDE File Manager
00002 
00003    Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)
00004    Copyright (C) 2000,2001 Dawit Alemayehu (adawit@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 copies of the
00010    Software, and to permit persons to whom the Software is furnished to do so,
00011    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 AN
00020    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00021    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 */
00023 //----------------------------------------------------------------------------
00024 //
00025 // KDE File Manager -- HTTP Cookies
00026 // $Id$
00027 
00028 //
00029 // The cookie protocol is a mess. RFC2109 is a joke since nobody seems to
00030 // use it. Apart from that it is badly written.
00031 // We try to implement Netscape Cookies and try to behave us according to
00032 // RFC2109 as much as we can.
00033 //
00034 // We assume cookies do not contain any spaces (Netscape spec.)
00035 // According to RFC2109 this is allowed though.
00036 //
00037 
00038 #include <config.h>
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #ifdef HAVE_SYS_PARAM_H
00042 #include <sys/param.h>
00043 #endif
00044 #include <fcntl.h>
00045 #include <unistd.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 
00049 #ifdef USE_SOLARIS
00050 #include <strings.h>
00051 #endif
00052 
00053 #include <stdlib.h>
00054 
00055 //#include <netinet/in.h>
00056 //#include <arpa/inet.h>
00057 
00058 #include <tqstring.h>
00059 #include <tqstrlist.h>
00060 #include <tqptrlist.h>
00061 #include <tqptrdict.h>
00062 #include <tqfile.h>
00063 #include <tqdir.h>
00064 #include <tqregexp.h>
00065 
00066 #include <kurl.h>
00067 #include <krfcdate.h>
00068 #include <tdeconfig.h>
00069 #include <ksavefile.h>
00070 #include <kdebug.h>
00071 
00072 #include "kcookiejar.h"
00073 
00074 
00075 // BR87227
00076 // Waba: Should the number of cookies be limited?
00077 // I am not convinced of the need of such limit
00078 // Mozilla seems to limit to 20 cookies / domain
00079 // but it is unclear which policy it uses to expire
00080 // cookies when it exceeds that amount
00081 #undef MAX_COOKIE_LIMIT
00082 
00083 #define MAX_COOKIES_PER_HOST 25
00084 #define READ_BUFFER_SIZE 8192
00085 #define IP_ADDRESS_EXPRESSION "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
00086 
00087 // Note with respect to TQString::fromLatin1( )
00088 // Cookies are stored as 8 bit data and passed to tdeio_http as
00089 // latin1 regardless of their actual encoding.
00090 
00091 // L1 is used to indicate latin1 constants
00092 #define L1(x) TQString::fromLatin1(x)
00093 
00094 template class TQPtrList<KHttpCookie>;
00095 template class TQPtrDict<KHttpCookieList>;
00096 
00097 TQString KCookieJar::adviceToStr(KCookieAdvice _advice)
00098 {
00099     switch( _advice )
00100     {
00101     case KCookieAccept: return L1("Accept");
00102     case KCookieReject: return L1("Reject");
00103     case KCookieAsk: return L1("Ask");
00104     default: return L1("Dunno");
00105     }
00106 }
00107 
00108 KCookieAdvice KCookieJar::strToAdvice(const TQString &_str)
00109 {
00110     if (_str.isEmpty())
00111         return KCookieDunno;
00112 
00113     TQCString advice = _str.lower().latin1();
00114 
00115     if (advice == "accept")
00116         return KCookieAccept;
00117     else if (advice == "reject")
00118         return KCookieReject;
00119     else if (advice == "ask")
00120         return KCookieAsk;
00121 
00122     return KCookieDunno;
00123 }
00124 
00125 // KHttpCookie
00127 
00128 //
00129 // Cookie constructor
00130 //
00131 KHttpCookie::KHttpCookie(const TQString &_host,
00132                  const TQString &_domain,
00133                  const TQString &_path,
00134                  const TQString &_name,
00135                  const TQString &_value,
00136                  time_t _expireDate,
00137                  int _protocolVersion,
00138                  bool _secure,
00139                  bool _httpOnly,
00140                  bool _explicitPath) :
00141        mHost(_host),
00142        mDomain(_domain),
00143        mPath(_path.isEmpty() ? TQString::null : _path),
00144        mName(_name),
00145        mValue(_value),
00146        mExpireDate(_expireDate),
00147        mProtocolVersion(_protocolVersion),
00148        mSecure(_secure),
00149        mCrossDomain(false),
00150        mHttpOnly(_httpOnly),
00151        mExplicitPath(_explicitPath)
00152 {
00153 }
00154 
00155 //
00156 // Checks if a cookie has been expired
00157 //
00158 bool    KHttpCookie::isExpired(time_t currentDate)
00159 {
00160     return (mExpireDate != 0) && (mExpireDate < currentDate);
00161 }
00162 
00163 //
00164 // Returns a string for a HTTP-header
00165 //
00166 TQString KHttpCookie::cookieStr(bool useDOMFormat)
00167 {
00168     TQString result;
00169 
00170     if (useDOMFormat || (mProtocolVersion == 0))
00171     {
00172         if ( !mName.isEmpty() )
00173            result = mName + '=';
00174         result += mValue;
00175     }
00176     else
00177     {
00178         result = mName + '=' + mValue;
00179         if (mExplicitPath)
00180             result += L1("; $Path=\"") + mPath + L1("\"");
00181         if (!mDomain.isEmpty())
00182             result += L1("; $Domain=\"") + mDomain + L1("\"");
00183     }
00184     return result;
00185 }
00186 
00187 //
00188 // Returns whether this cookie should be send to this location.
00189 bool KHttpCookie::match(const TQString &fqdn, const TQStringList &domains,
00190                         const TQString &path)
00191 {
00192     // Cookie domain match check
00193     if (mDomain.isEmpty())
00194     {
00195        if (fqdn != mHost)
00196           return false;
00197     }
00198     else if (!domains.contains(mDomain))
00199     {
00200         if (mDomain[0] == '.')
00201             return false;
00202 
00203         // Maybe the domain needs an extra dot.
00204         TQString domain = '.' + mDomain;
00205         if ( !domains.contains( domain ) )
00206           if ( fqdn != mDomain )
00207             return false;
00208     }
00209 
00210     // Cookie path match check
00211     if (mPath.isEmpty())
00212         return true;
00213 
00214     // According to the netscape spec both http://www.acme.com/foobar,
00215     // http://www.acme.com/foo.bar and http://www.acme.com/foo/bar
00216     // match http://www.acme.com/foo.
00217     // We only match http://www.acme.com/foo/bar
00218 
00219     if( path.startsWith(mPath) &&
00220         (
00221          (path.length() == mPath.length() ) ||  // Paths are exact match
00222          (path[mPath.length()-1] == '/') ||     // mPath ended with a slash
00223          (path[mPath.length()] == '/')      // A slash follows.
00224          ))
00225         return true; // Path of URL starts with cookie-path
00226 
00227     return false;
00228 }
00229 
00230 // KHttpCookieList
00232 
00233 int KHttpCookieList::compareItems( void * item1, void * item2)
00234 {
00235     int pathLen1 = ((KHttpCookie *)item1)->path().length();
00236     int pathLen2 = ((KHttpCookie *)item2)->path().length();
00237     if (pathLen1 > pathLen2)
00238         return -1;
00239     if (pathLen1 < pathLen2)
00240         return 1;
00241     return 0;
00242 }
00243 
00244 
00245 // KCookieJar
00247 
00248 //
00249 // Constructs a new cookie jar
00250 //
00251 // One jar should be enough for all cookies.
00252 //
00253 KCookieJar::KCookieJar()
00254 {
00255     m_cookieDomains.setAutoDelete( true );
00256     m_globalAdvice = KCookieDunno;
00257     m_configChanged = false;
00258     m_cookiesChanged = false;
00259     
00260     TDEConfig cfg("tdehtml/domain_info", true, false, "data");
00261     TQStringList countries = cfg.readListEntry("twoLevelTLD");
00262     for(TQStringList::ConstIterator it = countries.begin();
00263         it != countries.end(); ++it)
00264     {
00265        m_twoLevelTLD.replace(*it, (int *) 1);
00266     }
00267 }
00268 
00269 //
00270 // Destructs the cookie jar
00271 //
00272 // Poor little cookies, they will all be eaten by the cookie monster!
00273 //
00274 KCookieJar::~KCookieJar()
00275 {
00276     // Not much to do here
00277 }
00278 
00279 static void removeDuplicateFromList(KHttpCookieList *list, KHttpCookie *cookiePtr, bool nameMatchOnly=false, bool updateWindowId=false)
00280 {
00281     TQString domain1 = cookiePtr->domain();
00282     if (domain1.isEmpty())
00283        domain1 = cookiePtr->host();
00284 
00285     for ( KHttpCookiePtr cookie=list->first(); cookie != 0; )
00286     {
00287        TQString domain2 = cookie->domain();
00288        if (domain2.isEmpty())
00289           domain2 = cookie->host();
00290 
00291        if ( 
00292             (cookiePtr->name() == cookie->name()) &&
00293             (
00294               nameMatchOnly ||
00295               ( (domain1 == domain2) && (cookiePtr->path() == cookie->path()) )
00296             )
00297           )
00298        {
00299           if (updateWindowId)
00300           {
00301             for(TQValueList<long>::ConstIterator it = cookie->windowIds().begin();
00302                 it != cookie->windowIds().end(); ++it)
00303             {
00304                long windowId = *it;
00305                if (windowId && (cookiePtr->windowIds().find(windowId) == cookiePtr->windowIds().end()))
00306                {
00307                   cookiePtr->windowIds().append(windowId);
00308                }
00309             }
00310           }
00311           KHttpCookiePtr old_cookie = cookie;
00312           cookie = list->next();
00313           list->removeRef( old_cookie );
00314           break;
00315        }
00316        else
00317        {
00318           cookie = list->next();
00319        }
00320     }
00321 }
00322 
00323 
00324 //
00325 // Looks for cookies in the cookie jar which are appropriate for _url.
00326 // Returned is a string containing all appropriate cookies in a format
00327 // which can be added to a HTTP-header without any additional processing.
00328 //
00329 TQString KCookieJar::findCookies(const TQString &_url, bool useDOMFormat, long windowId, KHttpCookieList *pendingCookies)
00330 {
00331     TQString cookieStr;
00332     TQStringList domains;
00333     TQString fqdn;
00334     TQString path;
00335     KHttpCookiePtr cookie;
00336     KCookieAdvice advice = m_globalAdvice;
00337 
00338     if (!parseURL(_url, fqdn, path))
00339         return cookieStr;
00340 
00341     bool secureRequest = (_url.find( L1("https://"), 0, false) == 0 ||
00342                           _url.find( L1("webdavs://"), 0, false) == 0);
00343 
00344     // kdDebug(7104) << "findCookies: URL= " << _url << ", secure = " << secureRequest << endl;
00345 
00346     extractDomains(fqdn, domains);
00347 
00348     KHttpCookieList allCookies;
00349 
00350     for(TQStringList::ConstIterator it = domains.begin();
00351         true;
00352         ++it)
00353     {
00354        KHttpCookieList *cookieList;
00355        if (it == domains.end())
00356        {
00357           cookieList = pendingCookies; // Add pending cookies
00358           pendingCookies = 0;
00359           if (!cookieList)
00360              break;
00361        }
00362        else
00363        {
00364           TQString key = (*it).isNull() ? L1("") : (*it);
00365           cookieList = m_cookieDomains[key];
00366           if (!cookieList)
00367              continue; // No cookies for this domain
00368        }
00369 
00370        if (cookieList->getAdvice() != KCookieDunno)
00371           advice = cookieList->getAdvice();
00372 
00373        for ( cookie=cookieList->first(); cookie != 0; cookie=cookieList->next() )
00374        {
00375           // If the we are setup to automatically accept all session cookies and to
00376           // treat all cookies as session cookies or the current cookie is a session
00377           // cookie, then send the cookie back regardless of either policy.
00378           if (advice == KCookieReject &&
00379               !(m_autoAcceptSessionCookies && 
00380                 (m_ignoreCookieExpirationDate || cookie->expireDate() == 0)))
00381               continue;
00382 
00383           if (!cookie->match(fqdn, domains, path))
00384              continue;
00385 
00386           if( cookie->isSecure() && !secureRequest )
00387              continue;
00388 
00389           if( cookie->isHttpOnly() && useDOMFormat )
00390              continue;
00391 
00392           // Do not send expired cookies.
00393           if ( cookie->isExpired (time(0)) )
00394           {
00395              // Note there is no need to actually delete the cookie here
00396              // since the cookieserver will invoke ::saveCookieJar because
00397              // of the state change below. This will then do the job of
00398              // deleting the cookie for us.
00399              m_cookiesChanged = true;
00400              continue;
00401           }
00402 
00403           if (windowId && (cookie->windowIds().find(windowId) == cookie->windowIds().end()))
00404           {
00405              cookie->windowIds().append(windowId);
00406           }
00407 
00408           if (it == domains.end()) // Only needed when processing pending cookies
00409              removeDuplicateFromList(&allCookies, cookie);
00410 
00411           allCookies.append(cookie);
00412        }
00413        if (it == domains.end())
00414           break; // Finished.
00415     }
00416 
00417     int cookieCount = 0;
00418 
00419     int protVersion=0; 
00420     for ( cookie=allCookies.first(); cookie != 0; cookie=allCookies.next() )
00421     {
00422        if (cookie->protocolVersion() > protVersion)
00423           protVersion = cookie->protocolVersion();
00424     }
00425 
00426     for ( cookie=allCookies.first(); cookie != 0; cookie=allCookies.next() )
00427     {
00428        if (useDOMFormat)
00429        {
00430           if (cookieCount > 0)
00431              cookieStr += L1("; ");
00432           cookieStr += cookie->cookieStr(true);
00433        }
00434        else
00435        {
00436           if (cookieCount == 0)
00437           {
00438              cookieStr += L1("Cookie: ");
00439              if (protVersion > 0)
00440              {
00441                 TQString version;
00442                 version.sprintf("$Version=%d; ", protVersion); // Without quotes
00443                 cookieStr += version;
00444              }
00445           }
00446           else
00447           {
00448              cookieStr += L1("; ");
00449           }
00450           cookieStr += cookie->cookieStr(false);
00451        }
00452        cookieCount++;
00453     }
00454 
00455     return cookieStr;
00456 }
00457 
00458 //
00459 // This function parses a string like 'my_name="my_value";' and returns
00460 // 'my_name' in Name and 'my_value' in Value.
00461 //
00462 // A pointer to the end of the parsed part is returned.
00463 // This pointer points either to:
00464 // '\0' - The end of the string has reached.
00465 // ';'  - Another my_name="my_value" pair follows
00466 // ','  - Another cookie follows
00467 // '\n' - Another header follows
00468 static const char * parseNameValue(const char *header,
00469                                   TQString &Name,
00470                                   TQString &Value,
00471                                   bool keepQuotes=false,
00472                                   bool rfcQuotes=false)
00473 {
00474     const char *s = header;
00475     // Parse 'my_name' part
00476     for(; (*s != '='); s++)
00477     {
00478         if ((*s=='\0') || (*s==';') || (*s=='\n'))
00479         {
00480             // No '=' sign -> use string as the value, name is empty
00481             // (behavior found in Mozilla and IE)
00482             Name = "";
00483             Value = TQString::fromLatin1(header);
00484             Value.truncate( s - header );
00485             Value = Value.stripWhiteSpace();
00486             return (s);
00487         }
00488     }
00489 
00490     Name = header;
00491     Name.truncate( s - header );
00492     Name = Name.stripWhiteSpace();
00493 
00494     // *s == '='
00495     s++;
00496 
00497     // Skip any whitespace
00498     for(; (*s == ' ') || (*s == '\t'); s++)
00499     {
00500         if ((*s=='\0') || (*s==';') || (*s=='\n'))
00501         {
00502             // End of Name
00503             Value = "";
00504             return (s);
00505         }
00506     }
00507 
00508     if ((rfcQuotes || !keepQuotes) && (*s == '\"'))
00509     {
00510         // Parse '"my_value"' part (quoted value)
00511         if (keepQuotes)
00512            header = s++;
00513         else
00514            header = ++s; // skip "
00515         for(;(*s != '\"');s++)
00516         {
00517             if ((*s=='\0') || (*s=='\n'))
00518             {
00519                 // End of Name
00520                 Value = TQString::fromLatin1(header);
00521                 Value.truncate(s - header);
00522                 return (s);
00523             }
00524         }
00525         Value = TQString::fromLatin1(header);
00526         // *s == '\"';
00527         if (keepQuotes)
00528            Value.truncate( ++s - header );
00529         else
00530            Value.truncate( s++ - header );
00531 
00532         // Skip any remaining garbage
00533         for(;; s++)
00534         {
00535             if ((*s=='\0') || (*s==';') || (*s=='\n'))
00536                 break;
00537         }
00538     }
00539     else
00540     {
00541         // Parse 'my_value' part (unquoted value)
00542         header = s;
00543         while ((*s != '\0') && (*s != ';') && (*s != '\n'))
00544             s++;
00545         // End of Name
00546         Value = TQString::fromLatin1(header);
00547         Value.truncate( s - header );
00548         Value = Value.stripWhiteSpace();
00549     }
00550     return (s);
00551 
00552 }
00553 
00554 void KCookieJar::stripDomain(const TQString &_fqdn, TQString &_domain)
00555 {
00556    TQStringList domains;
00557    extractDomains(_fqdn, domains);
00558    if (domains.count() > 3)
00559       _domain = domains[3];
00560    else
00561       _domain = domains[0];
00562 }
00563 
00564 TQString KCookieJar::stripDomain( KHttpCookiePtr cookiePtr)
00565 {
00566     TQString domain; // We file the cookie under this domain.
00567     if (cookiePtr->domain().isEmpty())
00568        stripDomain( cookiePtr->host(), domain);
00569     else
00570        stripDomain (cookiePtr->domain(), domain);
00571     return domain;
00572 }
00573 
00574 bool KCookieJar::parseURL(const TQString &_url,
00575                           TQString &_fqdn,
00576                           TQString &_path)
00577 {
00578     KURL kurl(_url);
00579     if (!kurl.isValid())
00580        return false;
00581 
00582     _fqdn = kurl.host().lower();
00583     if (kurl.port())
00584     {
00585        if (((kurl.protocol() == L1("http")) && (kurl.port() != 80)) ||
00586            ((kurl.protocol() == L1("https")) && (kurl.port() != 443)))
00587        {
00588           _fqdn = L1("%1:%2").arg(kurl.port()).arg(_fqdn);
00589        }
00590     }
00591 
00592     // Cookie spoofing protection.  Since there is no way a path separator
00593     // or escape encoded character is allowed in the hostname according
00594     // to RFC 2396, reject attempts to include such things there!
00595     if(_fqdn.find('/') > -1 || _fqdn.find('%') > -1)
00596     {
00597         return false;  // deny everything!!
00598     }
00599 
00600     _path = kurl.path();
00601     if (_path.isEmpty())
00602        _path = L1("/");
00603 
00604     TQRegExp exp(L1("[\\\\/]\\.\\.[\\\\/]"));
00605     // Weird path, cookie stealing attempt?
00606     if (exp.search(_path) != -1)
00607        return false; // Deny everything!!
00608 
00609     return true;
00610 }
00611 
00612 void KCookieJar::extractDomains(const TQString &_fqdn,
00613                                 TQStringList &_domains)
00614 {
00615     // Return numeric IPv6 addresses as is...
00616     if (_fqdn[0] == '[')
00617     {
00618        _domains.append( _fqdn );
00619        return;
00620     }
00621     // Return numeric IPv4 addresses as is...
00622     if ((_fqdn.at(0) >= TQChar('0')) && (_fqdn.at(0) <= TQChar('9')))
00623     {
00624        if (_fqdn.find(TQRegExp(IP_ADDRESS_EXPRESSION)) > -1)
00625        {
00626           _domains.append( _fqdn );
00627           return;
00628        }
00629     }
00630 
00631     TQStringList partList = TQStringList::split('.', _fqdn, false);
00632 
00633     if (partList.count())
00634         partList.remove(partList.begin()); // Remove hostname
00635 
00636     while(partList.count())
00637     {
00638 
00639        if (partList.count() == 1)
00640          break; // We only have a TLD left.
00641 
00642        if ((partList.count() == 2) && (m_twoLevelTLD[partList[1].lower()]))
00643        {
00644           // This domain uses two-level TLDs in the form xxxx.yy
00645           break;
00646        }
00647 
00648        if ((partList.count() == 2) && (partList[1].length() == 2))
00649        {
00650           // If this is a TLD, we should stop. (e.g. co.uk)
00651           // We assume this is a TLD if it ends with .xx.yy or .x.yy
00652           if (partList[0].length() <= 2)
00653              break; // This is a TLD.
00654 
00655           // Catch some TLDs that we miss with the previous check
00656           // e.g. com.au, org.uk, mil.co
00657           TQCString t = partList[0].lower().utf8();
00658           if ((t == "com") || (t == "net") || (t == "org") || (t == "gov") || (t == "edu") || (t == "mil") || (t == "int"))
00659               break;
00660        }
00661 
00662        TQString domain = partList.join(L1("."));
00663        _domains.append(domain);
00664        _domains.append('.' + domain);
00665        partList.remove(partList.begin()); // Remove part
00666     }
00667 
00668     // Always add the FQDN at the start of the list for
00669     // hostname == cookie-domainname checks!
00670     _domains.prepend( '.' + _fqdn );
00671     _domains.prepend( _fqdn );
00672 }
00673 
00674 
00675 /*
00676    Changes dates in from the following format
00677 
00678       Wed Sep 12 07:00:00 2007 GMT
00679    to
00680       Wed Sep 12 2007 07:00:00 GMT
00681 
00682    to allow KRFCDate::parseDate to properly parse expiration date formats 
00683    used in cookies by some servers such as amazon.com. See BR# 145244.
00684 */
00685 static TQString fixupDateTime(const TQString& dt)
00686 {
00687   const int index = dt.find(TQRegExp("[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}"));
00688 
00689   if (index > -1)
00690   {
00691     TQStringList dateStrList = TQStringList::split(' ', dt.mid(index));
00692     if (dateStrList.count() > 1)
00693     {
00694       TQString date = dateStrList[0];
00695       dateStrList[0] = dateStrList[1];
00696       dateStrList[1] = date;
00697       date = dt;
00698       return date.replace(index, date.length(), dateStrList.join(" "));
00699     }
00700   }
00701 
00702   return dt;
00703 }
00704 
00705 //
00706 // This function parses cookie_headers and returns a linked list of
00707 // KHttpCookie objects for all cookies found in cookie_headers.
00708 // If no cookies could be found 0 is returned.
00709 //
00710 // cookie_headers should be a concatenation of all lines of a HTTP-header
00711 // which start with "Set-Cookie". The lines should be separated by '\n's.
00712 //
00713 KHttpCookieList KCookieJar::makeCookies(const TQString &_url,
00714                                        const TQCString &cookie_headers,
00715                                        long windowId)
00716 {
00717     KHttpCookieList cookieList;
00718     KHttpCookieList cookieList2;
00719     KHttpCookiePtr lastCookie = 0;
00720     const char *cookieStr = cookie_headers.data();
00721     TQString Name;
00722     TQString Value;
00723     TQString fqdn;
00724     TQString path;
00725     bool crossDomain = false;
00726 
00727     if (!parseURL(_url, fqdn, path))
00728     {
00729         // Error parsing _url
00730         return KHttpCookieList();
00731     }
00732     TQString defaultPath;
00733     int i = path.findRev('/');
00734     if (i > 0)
00735        defaultPath = path.left(i);
00736 
00737     //  The hard stuff :)
00738     for(;;)
00739     {
00740         // check for "Set-Cookie"
00741         if (strncmp(cookieStr, "Cross-Domain\n", 13) == 0)
00742         {
00743             cookieStr += 13;
00744             crossDomain = true;
00745         }
00746         else if (strncasecmp(cookieStr, "Set-Cookie:", 11) == 0) 
00747         {
00748             cookieStr = parseNameValue(cookieStr+11, Name, Value, true);
00749 
00750             // Host = FQDN
00751             // Default domain = ""
00752             // Default path according to rfc2109
00753 
00754             KHttpCookie *cookie = new KHttpCookie(fqdn, L1(""), defaultPath, Name, Value);
00755             if (windowId)
00756                cookie->mWindowIds.append(windowId);
00757             cookie->mCrossDomain = crossDomain;
00758 
00759             // Insert cookie in chain
00760             cookieList.append(cookie);
00761             lastCookie = cookie;
00762         }
00763         else if (strncasecmp(cookieStr, "Set-Cookie2:", 12) == 0)
00764         {
00765             // Attempt to follow rfc2965
00766             cookieStr = parseNameValue(cookieStr+12, Name, Value, true, true);
00767 
00768             // Host = FQDN
00769             // Default domain = ""
00770             // Default path according to rfc2965
00771 
00772             KHttpCookie *cookie = new KHttpCookie(fqdn, L1(""), defaultPath, Name, Value);
00773             if (windowId)
00774                cookie->mWindowIds.append(windowId);
00775             cookie->mCrossDomain = crossDomain;
00776 
00777             // Insert cookie in chain
00778             cookieList2.append(cookie);
00779             lastCookie = cookie;
00780         }
00781         else
00782         {
00783             // This is not the start of a cookie header, skip till next line.
00784             while (*cookieStr && *cookieStr != '\n')
00785                 cookieStr++;
00786 
00787             if (*cookieStr == '\n')
00788                 cookieStr++;
00789 
00790             if (!*cookieStr)
00791                 break; // End of cookie_headers
00792             else
00793                 continue; // end of this header, continue with next.
00794         }
00795 
00796         while ((*cookieStr == ';') || (*cookieStr == ' '))
00797         {
00798             cookieStr++;
00799 
00800             // Name-Value pair follows
00801             cookieStr = parseNameValue(cookieStr, Name, Value);
00802 
00803             TQCString cName = Name.lower().latin1();
00804             if (cName == "domain")
00805             {
00806                 TQString dom = Value.lower();
00807                 // RFC2965 3.2.2: If an explicitly specified value does not
00808                 // start with a dot, the user agent supplies a leading dot
00809                 if(dom.length() && dom[0] != '.')
00810                     dom.prepend(".");
00811                 // remove a trailing dot
00812                 if(dom.length() > 2 && dom[dom.length()-1] == '.')
00813                     dom = dom.left(dom.length()-1);
00814 
00815                 if(dom.contains('.') > 1 || dom == ".local")
00816                     lastCookie->mDomain = dom;
00817             }
00818             else if (cName == "max-age")
00819             {
00820                 int max_age = Value.toInt();
00821                 if (max_age == 0)
00822                     lastCookie->mExpireDate = 1;
00823                 else
00824                     lastCookie->mExpireDate = time(0)+max_age;
00825             }
00826             else if (cName == "expires")
00827             {
00828                 // Parse brain-dead netscape cookie-format
00829                 lastCookie->mExpireDate = KRFCDate::parseDate(Value);
00830 
00831                 // Workaround for servers that send the expiration date in
00832                 // 'Wed Sep 12 07:00:00 2007 GMT' format. See BR# 145244.
00833                 if (lastCookie->mExpireDate == 0)
00834                   lastCookie->mExpireDate = KRFCDate::parseDate(fixupDateTime(Value));
00835             }
00836             else if (cName == "path")
00837             {
00838                 if (Value.isEmpty())
00839                    lastCookie->mPath = TQString::null; // Catch "" <> TQString::null
00840                 else
00841                    lastCookie->mPath = KURL::decode_string(Value);
00842                 lastCookie->mExplicitPath = true;
00843             }
00844             else if (cName == "version")
00845             {
00846                 lastCookie->mProtocolVersion = Value.toInt();
00847             }
00848             else if ((cName == "secure") ||
00849                      (cName.isEmpty() && Value.lower() == L1("secure")))
00850             {
00851                 lastCookie->mSecure = true;
00852             }
00853             else if ((cName == "httponly") ||
00854                      (cName.isEmpty() && Value.lower() == L1("httponly")))
00855             {
00856                 lastCookie->mHttpOnly = true;
00857             }
00858         }
00859 
00860         if (*cookieStr == '\0')
00861             break; // End of header
00862 
00863         // Skip ';' or '\n'
00864         cookieStr++;
00865     }
00866 
00867     // RFC2965 cookies come last so that they override netscape cookies.
00868     while( !cookieList2.isEmpty() && (lastCookie = cookieList2.take(0)) )
00869     {
00870        removeDuplicateFromList(&cookieList, lastCookie, true);
00871        cookieList.append(lastCookie);
00872     }
00873 
00874     return cookieList;
00875 }
00876 
00883 KHttpCookieList KCookieJar::makeDOMCookies(const TQString &_url,
00884                                           const TQCString &cookie_domstring,
00885                                           long windowId)
00886 {
00887     // A lot copied from above
00888     KHttpCookieList cookieList;
00889     KHttpCookiePtr lastCookie = 0;
00890 
00891     const char *cookieStr = cookie_domstring.data();
00892     TQString Name;
00893     TQString Value;
00894     TQString fqdn;
00895     TQString path;
00896 
00897     if (!parseURL(_url, fqdn, path))
00898     {
00899         // Error parsing _url
00900         return KHttpCookieList();
00901     }
00902 
00903     //  This time it's easy
00904     while(*cookieStr)
00905     {
00906         cookieStr = parseNameValue(cookieStr, Name, Value);
00907 
00908         // Host = FQDN
00909         // Default domain = ""
00910         // Default path = ""
00911         KHttpCookie *cookie = new KHttpCookie(fqdn, TQString::null, TQString::null,
00912                                 Name, Value );
00913         if (windowId)
00914             cookie->mWindowIds.append(windowId);
00915 
00916         cookieList.append(cookie);
00917         lastCookie = cookie;
00918 
00919         if (*cookieStr != '\0')
00920             cookieStr++;         // Skip ';' or '\n'
00921      }
00922 
00923      return cookieList;
00924 }
00925 
00926 #ifdef MAX_COOKIE_LIMIT
00927 static void makeRoom(KHttpCookieList *cookieList, KHttpCookiePtr &cookiePtr)
00928 {
00929      // Too much cookies: throw one away, try to be somewhat clever
00930      KHttpCookiePtr lastCookie = 0;
00931      for(KHttpCookiePtr cookie = cookieList->first(); cookie; cookie = cookieList->next())
00932      {
00933          if (cookieList->compareItems(cookie, cookiePtr) < 0)
00934             break;
00935          lastCookie = cookie;
00936      }
00937      if (!lastCookie)
00938          lastCookie = cookieList->first();
00939      cookieList->removeRef(lastCookie);
00940 }
00941 #endif
00942 
00943 //
00944 // This function hands a KHttpCookie object over to the cookie jar.
00945 //
00946 // On return cookiePtr is set to 0.
00947 //
00948 void KCookieJar::addCookie(KHttpCookiePtr &cookiePtr)
00949 {
00950     TQStringList domains;
00951     KHttpCookieList *cookieList = 0L;
00952 
00953     // We always need to do this to make sure that the
00954     // that cookies of type hostname == cookie-domainname
00955     // are properly removed and/or updated as necessary!
00956     extractDomains( cookiePtr->host(), domains );
00957     for ( TQStringList::ConstIterator it = domains.begin();
00958           (it != domains.end() && !cookieList);
00959           ++it )
00960     {
00961         TQString key = (*it).isNull() ? L1("") : (*it);
00962         KHttpCookieList *list= m_cookieDomains[key];
00963         if ( !list ) continue;
00964 
00965         removeDuplicateFromList(list, cookiePtr, false, true);
00966     }
00967 
00968     TQString domain = stripDomain( cookiePtr );
00969     TQString key = domain.isNull() ? L1("") : domain;
00970     cookieList = m_cookieDomains[ key ];
00971     if (!cookieList)
00972     {
00973         // Make a new cookie list
00974         cookieList = new KHttpCookieList();
00975         cookieList->setAutoDelete(true);
00976 
00977         // All cookies whose domain is not already
00978         // known to us should be added with KCookieDunno.
00979         // KCookieDunno means that we use the global policy.
00980         cookieList->setAdvice( KCookieDunno );
00981 
00982         m_cookieDomains.insert( domain, cookieList);
00983 
00984         // Update the list of domains
00985         m_domainList.append(domain);
00986     }
00987 
00988     // Add the cookie to the cookie list
00989     // The cookie list is sorted 'longest path first'
00990     if (!cookiePtr->isExpired(time(0)))
00991     {
00992 #ifdef MAX_COOKIE_LIMIT
00993         if (cookieList->count() >= MAX_COOKIES_PER_HOST)
00994            makeRoom(cookieList, cookiePtr); // Delete a cookie
00995 #endif
00996         cookieList->inSort( cookiePtr );
00997         m_cookiesChanged = true;
00998     }
00999     else
01000     {
01001         delete cookiePtr;
01002     }
01003     cookiePtr = 0;
01004 }
01005 
01006 //
01007 // This function advices whether a single KHttpCookie object should
01008 // be added to the cookie jar.
01009 //
01010 KCookieAdvice KCookieJar::cookieAdvice(KHttpCookiePtr cookiePtr)
01011 {
01012     if (m_rejectCrossDomainCookies && cookiePtr->isCrossDomain())
01013        return KCookieReject;
01014 
01015     TQStringList domains;
01016 
01017     extractDomains(cookiePtr->host(), domains);
01018 
01019     // If the cookie specifies a domain, check whether it is valid. Otherwise,
01020     // accept the cookie anyways but remove the domain="" value to prevent
01021     // cross-site cookie injection.
01022     if (!cookiePtr->domain().isEmpty())
01023     {
01024       if (!domains.contains(cookiePtr->domain()) && 
01025           !cookiePtr->domain().endsWith("."+cookiePtr->host()))
01026           cookiePtr->fixDomain(TQString::null);
01027     }
01028 
01029     if (m_autoAcceptSessionCookies && (cookiePtr->expireDate() == 0 ||
01030         m_ignoreCookieExpirationDate))
01031        return KCookieAccept;
01032 
01033     KCookieAdvice advice = KCookieDunno;
01034     bool isFQDN = true; // First is FQDN
01035     TQStringList::Iterator it = domains.begin(); // Start with FQDN which first in the list.
01036     while( (advice == KCookieDunno) && (it != domains.end()))
01037     {
01038        TQString domain = *it;
01039        // Check if a policy for the FQDN/domain is set.
01040        if ( domain[0] == '.' || isFQDN )
01041        {
01042           isFQDN = false;
01043           KHttpCookieList *cookieList = m_cookieDomains[domain];
01044           if (cookieList)
01045              advice = cookieList->getAdvice();
01046        }
01047        domains.remove(it);
01048        it = domains.begin(); // Continue from begin of remaining list
01049     }
01050 
01051     if (advice == KCookieDunno)
01052         advice = m_globalAdvice;
01053 
01054     return advice;
01055 }
01056 
01057 //
01058 // This function gets the advice for all cookies originating from
01059 // _domain.
01060 //
01061 KCookieAdvice KCookieJar::getDomainAdvice(const TQString &_domain)
01062 {
01063     KHttpCookieList *cookieList = m_cookieDomains[_domain];
01064     KCookieAdvice advice;
01065 
01066     if (cookieList)
01067     {
01068         advice = cookieList->getAdvice();
01069     }
01070     else
01071     {
01072         advice = KCookieDunno;
01073     }
01074 
01075     return advice;
01076 }
01077 
01078 //
01079 // This function sets the advice for all cookies originating from
01080 // _domain.
01081 //
01082 void KCookieJar::setDomainAdvice(const TQString &_domain, KCookieAdvice _advice)
01083 {
01084     TQString domain(_domain);
01085     KHttpCookieList *cookieList = m_cookieDomains[domain];
01086 
01087     if (cookieList)
01088     {
01089         if (cookieList->getAdvice() != _advice)
01090         {
01091            m_configChanged = true;
01092            // domain is already known
01093            cookieList->setAdvice( _advice);
01094         }
01095 
01096         if ((cookieList->isEmpty()) &&
01097             (_advice == KCookieDunno))
01098         {
01099             // This deletes cookieList!
01100             m_cookieDomains.remove(domain);
01101             m_domainList.remove(domain);
01102         }
01103     }
01104     else
01105     {
01106         // domain is not yet known
01107         if (_advice != KCookieDunno)
01108         {
01109             // We should create a domain entry
01110             m_configChanged = true;
01111             // Make a new cookie list
01112             cookieList = new KHttpCookieList();
01113             cookieList->setAutoDelete(true);
01114             cookieList->setAdvice( _advice);
01115             m_cookieDomains.insert( domain, cookieList);
01116             // Update the list of domains
01117             m_domainList.append( domain);
01118         }
01119     }
01120 }
01121 
01122 //
01123 // This function sets the advice for all cookies originating from
01124 // the same domain as _cookie
01125 //
01126 void KCookieJar::setDomainAdvice(KHttpCookiePtr cookiePtr, KCookieAdvice _advice)
01127 {
01128     TQString domain;
01129     stripDomain(cookiePtr->host(), domain); // We file the cookie under this domain.
01130 
01131     setDomainAdvice(domain, _advice);
01132 }
01133 
01134 //
01135 // This function sets the global advice for cookies
01136 //
01137 void KCookieJar::setGlobalAdvice(KCookieAdvice _advice)
01138 {
01139     if (m_globalAdvice != _advice)
01140        m_configChanged = true;
01141     m_globalAdvice = _advice;
01142 }
01143 
01144 //
01145 // Get a list of all domains known to the cookie jar.
01146 //
01147 const TQStringList& KCookieJar::getDomainList()
01148 {
01149     return m_domainList;
01150 }
01151 
01152 //
01153 // Get a list of all cookies in the cookie jar originating from _domain.
01154 //
01155 const KHttpCookieList *KCookieJar::getCookieList(const TQString & _domain,
01156                                                  const TQString & _fqdn )
01157 {
01158     TQString domain;
01159 
01160     if (_domain.isEmpty())
01161         stripDomain( _fqdn, domain );
01162     else
01163         domain = _domain;
01164 
01165     return m_cookieDomains[domain];
01166 }
01167 
01168 //
01169 // Eat a cookie out of the jar.
01170 // cookiePtr should be one of the cookies returned by getCookieList()
01171 //
01172 void KCookieJar::eatCookie(KHttpCookiePtr cookiePtr)
01173 {
01174     TQString domain = stripDomain(cookiePtr); // We file the cookie under this domain.
01175     KHttpCookieList *cookieList = m_cookieDomains[domain];
01176 
01177     if (cookieList)
01178     {
01179         // This deletes cookiePtr!
01180         if (cookieList->removeRef( cookiePtr ))
01181            m_cookiesChanged = true;
01182 
01183         if ((cookieList->isEmpty()) &&
01184             (cookieList->getAdvice() == KCookieDunno))
01185         {
01186             // This deletes cookieList!
01187             m_cookieDomains.remove(domain);
01188 
01189             m_domainList.remove(domain);
01190         }
01191     }
01192 }
01193 
01194 void KCookieJar::eatCookiesForDomain(const TQString &domain)
01195 {
01196    KHttpCookieList *cookieList = m_cookieDomains[domain];
01197    if (!cookieList || cookieList->isEmpty()) return;
01198 
01199    cookieList->clear();
01200    if (cookieList->getAdvice() == KCookieDunno)
01201    {
01202        // This deletes cookieList!
01203        m_cookieDomains.remove(domain);
01204        m_domainList.remove(domain);
01205    }
01206    m_cookiesChanged = true;
01207 }
01208 
01209 void KCookieJar::eatSessionCookies( long windowId )
01210 {
01211     if (!windowId)
01212         return;
01213 
01214     TQStringList::Iterator it=m_domainList.begin();
01215     for ( ; it != m_domainList.end(); ++it )
01216         eatSessionCookies( *it, windowId, false );
01217 }
01218 
01219 void KCookieJar::eatAllCookies()
01220 {
01221     for ( TQStringList::Iterator it=m_domainList.begin();
01222           it != m_domainList.end();)
01223     {
01224         TQString domain = *it++;
01225         // This might remove domain from domainList!
01226         eatCookiesForDomain(domain);
01227     }
01228 }
01229 
01230 void KCookieJar::eatSessionCookies( const TQString& fqdn, long windowId,
01231                                     bool isFQDN )
01232 {
01233     KHttpCookieList* cookieList;
01234     if ( !isFQDN )
01235         cookieList = m_cookieDomains[fqdn];
01236     else
01237     {
01238         TQString domain;
01239         stripDomain( fqdn, domain );
01240         cookieList = m_cookieDomains[domain];
01241     }
01242 
01243     if ( cookieList )
01244     {
01245         KHttpCookiePtr cookie=cookieList->first();
01246         for (; cookie != 0;)
01247         {
01248             if ((cookie->expireDate() != 0) && !m_ignoreCookieExpirationDate)
01249             {
01250                cookie = cookieList->next();
01251                continue;
01252             }
01253 
01254             TQValueList<long> &ids = cookie->windowIds();
01255             if (!ids.remove(windowId) || !ids.isEmpty())
01256             {
01257                cookie = cookieList->next();
01258                continue;
01259             }
01260             KHttpCookiePtr old_cookie = cookie;
01261             cookie = cookieList->next();
01262             cookieList->removeRef( old_cookie );
01263         }
01264     }
01265 }
01266 
01267 //
01268 // Saves all cookies to the file '_filename'.
01269 // On succes 'true' is returned.
01270 // On failure 'false' is returned.
01271 bool KCookieJar::saveCookies(const TQString &_filename)
01272 {
01273     KSaveFile saveFile(_filename, 0600);
01274 
01275     if (saveFile.status() != 0)
01276        return false;
01277 
01278     FILE *fStream = saveFile.fstream();
01279 
01280     time_t curTime = time(0);
01281 
01282     fprintf(fStream, "# KDE Cookie File v2\n#\n");
01283 
01284     fprintf(fStream, "%-20s %-20s %-12s %-10s %-4s %-20s %-4s %s\n",
01285                      "# Host", "Domain", "Path", "Exp.date", "Prot",
01286                      "Name", "Sec", "Value");
01287 
01288     for ( TQStringList::Iterator it=m_domainList.begin(); it != m_domainList.end();
01289           it++ )
01290     {
01291         const TQString &domain = *it;
01292         bool domainPrinted = false;
01293 
01294         KHttpCookieList *cookieList = m_cookieDomains[domain];
01295         KHttpCookiePtr cookie=cookieList->last();
01296 
01297         for (; cookie != 0;)
01298         {
01299             if (cookie->isExpired(curTime))
01300             {
01301                 // Delete expired cookies
01302                 KHttpCookiePtr old_cookie = cookie;
01303                 cookie = cookieList->prev();
01304                 cookieList->removeRef( old_cookie );
01305             }
01306             else if (cookie->expireDate() != 0 && !m_ignoreCookieExpirationDate)
01307             {
01308                 if (!domainPrinted)
01309                 {
01310                     domainPrinted = true;
01311                     fprintf(fStream, "[%s]\n", domain.local8Bit().data());
01312                 }
01313                 // Store persistent cookies
01314                 TQString path = L1("\"");
01315                 path += cookie->path();
01316                 path += '"';
01317                 TQString domain = L1("\"");
01318                 domain += cookie->domain();
01319                 domain += '"';
01320                 fprintf(fStream, "%-20s %-20s %-12s %10lu  %3d %-20s %-4i %s\n",
01321                         cookie->host().latin1(), domain.latin1(),
01322                         path.latin1(), (unsigned long) cookie->expireDate(),
01323                         cookie->protocolVersion(),
01324                         cookie->name().isEmpty() ? cookie->value().latin1() : cookie->name().latin1(),
01325                         (cookie->isSecure() ? 1 : 0) + (cookie->isHttpOnly() ? 2 : 0) + 
01326                         (cookie->hasExplicitPath() ? 4 : 0) + (cookie->name().isEmpty() ? 8 : 0),
01327                         cookie->value().latin1());
01328                 cookie = cookieList->prev();
01329             }
01330             else
01331             {
01332                 // Skip session-only cookies
01333                 cookie = cookieList->prev();
01334             }
01335         }
01336     }
01337 
01338     return saveFile.close();
01339 }
01340 
01341 typedef char *charPtr;
01342 
01343 static const char *parseField(charPtr &buffer, bool keepQuotes=false)
01344 {
01345     char *result;
01346     if (!keepQuotes && (*buffer == '\"'))
01347     {
01348         // Find terminating "
01349         buffer++;
01350         result = buffer;
01351         while((*buffer != '\"') && (*buffer))
01352             buffer++;
01353     }
01354     else
01355     {
01356         // Find first white space
01357         result = buffer;
01358         while((*buffer != ' ') && (*buffer != '\t') && (*buffer != '\n') && (*buffer))
01359             buffer++;
01360     }
01361 
01362     if (!*buffer)
01363         return result; //
01364     *buffer++ = '\0';
01365 
01366     // Skip white-space
01367     while((*buffer == ' ') || (*buffer == '\t') || (*buffer == '\n'))
01368         buffer++;
01369 
01370     return result;
01371 }
01372 
01373 
01374 //
01375 // Reloads all cookies from the file '_filename'.
01376 // On succes 'true' is returned.
01377 // On failure 'false' is returned.
01378 bool KCookieJar::loadCookies(const TQString &_filename)
01379 {
01380     FILE *fStream = fopen( TQFile::encodeName(_filename), "r");
01381     if (fStream == 0)
01382     {
01383         return false;
01384     }
01385 
01386     time_t curTime = time(0);
01387 
01388     char *buffer = new char[READ_BUFFER_SIZE];
01389 
01390     bool err = false;
01391     err = (fgets(buffer, READ_BUFFER_SIZE, fStream) == 0);
01392 
01393     int version = 1;
01394     if (!err)
01395     {
01396         if (strcmp(buffer, "# KDE Cookie File\n") == 0)
01397         {
01398           // version 1
01399         }
01400         else if (sscanf(buffer, "# KDE Cookie File v%d\n", &version) != 1)
01401         {
01402           err = true;
01403         }
01404     }
01405 
01406     if (!err)
01407     {
01408         while(fgets(buffer, READ_BUFFER_SIZE, fStream) != 0)
01409         {
01410             char *line = buffer;
01411             // Skip lines which begin with '#' or '['
01412             if ((line[0] == '#') || (line[0] == '['))
01413                 continue;
01414 
01415             const char *host( parseField(line) );
01416             const char *domain( parseField(line) );
01417             const char *path( parseField(line) );
01418             const char *expStr( parseField(line) );
01419             if (!expStr) continue;
01420             int expDate  = (time_t) strtoul(expStr, 0, 10);
01421             const char *verStr( parseField(line) );
01422             if (!verStr) continue;
01423             int protVer  = (time_t) strtoul(verStr, 0, 10);
01424             const char *name( parseField(line) );
01425             bool keepQuotes = false;
01426             bool secure = false;
01427             bool httpOnly = false;
01428             bool explicitPath = false;
01429             const char *value = 0;
01430             if ((version == 2) || (protVer >= 200))
01431             {
01432                 if (protVer >= 200)
01433                     protVer -= 200;
01434                 int i = atoi( parseField(line) );
01435                 secure = i & 1;
01436                 httpOnly = i & 2;
01437                 explicitPath = i & 4;
01438                 if (i & 8)
01439                    name = "";
01440                 line[strlen(line)-1] = '\0'; // Strip LF.
01441                 value = line;
01442             }
01443             else
01444             {
01445                 if (protVer >= 100)
01446                 {
01447                     protVer -= 100;
01448                     keepQuotes = true;
01449                 }
01450                 value = parseField(line, keepQuotes);
01451                 secure = atoi( parseField(line) );
01452             }
01453 
01454             // Parse error
01455             if (!value) continue;
01456 
01457             // Expired or parse error
01458             if ((expDate == 0) || (expDate < curTime))
01459                 continue;
01460 
01461             KHttpCookie *cookie = new KHttpCookie(TQString::fromLatin1(host),
01462                                                   TQString::fromLatin1(domain), 
01463                                                   TQString::fromLatin1(path), 
01464                                                   TQString::fromLatin1(name),
01465                                                   TQString::fromLatin1(value), 
01466                                                   expDate, protVer,
01467                                                   secure, httpOnly, explicitPath);
01468             addCookie(cookie);
01469         }
01470     }
01471     delete [] buffer;
01472     m_cookiesChanged = false;
01473 
01474     fclose( fStream);
01475     return err;
01476 }
01477 
01478 //
01479 // Save the cookie configuration
01480 //
01481 
01482 void KCookieJar::saveConfig(TDEConfig *_config)
01483 {
01484     if (!m_configChanged)
01485         return;
01486 
01487     _config->setGroup("Cookie Dialog");
01488     _config->writeEntry("PreferredPolicy", m_preferredPolicy);
01489     _config->writeEntry("ShowCookieDetails", m_showCookieDetails );
01490     _config->setGroup("Cookie Policy");
01491     _config->writeEntry("CookieGlobalAdvice", adviceToStr( m_globalAdvice));
01492 
01493     TQStringList domainSettings;
01494     for ( TQStringList::Iterator it=m_domainList.begin();
01495           it != m_domainList.end();
01496           it++ )
01497     {
01498          const TQString &domain = *it;
01499          KCookieAdvice advice = getDomainAdvice( domain);
01500          if (advice != KCookieDunno)
01501          {
01502              TQString value(domain);
01503              value += ':';
01504              value += adviceToStr(advice);
01505              domainSettings.append(value);
01506          }
01507     }
01508     _config->writeEntry("CookieDomainAdvice", domainSettings);
01509     _config->sync();
01510     m_configChanged = false;
01511 }
01512 
01513 
01514 //
01515 // Load the cookie configuration
01516 //
01517 
01518 void KCookieJar::loadConfig(TDEConfig *_config, bool reparse )
01519 {
01520     if ( reparse )
01521         _config->reparseConfiguration();
01522 
01523     _config->setGroup("Cookie Dialog");
01524     m_showCookieDetails = _config->readBoolEntry( "ShowCookieDetails" );
01525     m_preferredPolicy = _config->readNumEntry( "PreferredPolicy", 0 );
01526 
01527     _config->setGroup("Cookie Policy");
01528     TQStringList domainSettings = _config->readListEntry("CookieDomainAdvice");
01529     m_rejectCrossDomainCookies = _config->readBoolEntry( "RejectCrossDomainCookies", true );
01530     m_autoAcceptSessionCookies = _config->readBoolEntry( "AcceptSessionCookies", true );
01531     m_ignoreCookieExpirationDate = _config->readBoolEntry( "IgnoreExpirationDate", false );
01532     TQString value = _config->readEntry("CookieGlobalAdvice", L1("Ask"));
01533     m_globalAdvice = strToAdvice(value);
01534 
01535     // Reset current domain settings first.
01536     for ( TQStringList::Iterator it=m_domainList.begin(); it != m_domainList.end(); )
01537     {
01538          // Make sure to update iterator before calling setDomainAdvice()
01539          // setDomainAdvice() might delete the domain from domainList.
01540          TQString domain = *it++;
01541          setDomainAdvice(domain, KCookieDunno);
01542     }
01543 
01544     // Now apply the domain settings read from config file...
01545     for ( TQStringList::Iterator it=domainSettings.begin();
01546           it != domainSettings.end(); )
01547     {
01548         const TQString &value = *it++;
01549 
01550         int sepPos = value.findRev(':');
01551 
01552         if (sepPos <= 0)
01553           continue;
01554 
01555         TQString domain(value.left(sepPos));
01556         KCookieAdvice advice = strToAdvice( value.mid(sepPos + 1) );
01557         setDomainAdvice(domain, advice);
01558     }
01559 }

tdeioslave/http

Skip menu "tdeioslave/http"
  • Main Page
  • Alphabetical List
  • Class List
  • File List

tdeioslave/http

Skip menu "tdeioslave/http"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeioslave/http by doxygen 1.7.1
This website is maintained by Timothy Pearson.