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

tdeioslave/http

  • tdeioslave
  • http
  • kcookiejar
kcookiejar.cpp
1 /* This file is part of the KDE File Manager
2 
3  Copyright (C) 1998-2000 Waldo Bastian (bastian@kde.org)
4  Copyright (C) 2000,2001 Dawit Alemayehu (adawit@kde.org)
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, and/or sell copies of the
10  Software, and to permit persons to whom the Software is furnished to do so,
11  subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 //----------------------------------------------------------------------------
24 //
25 // KDE File Manager -- HTTP Cookies
26 // $Id$
27 
28 //
29 // The cookie protocol is a mess. RFC2109 is a joke since nobody seems to
30 // use it. Apart from that it is badly written.
31 // We try to implement Netscape Cookies and try to behave us according to
32 // RFC2109 as much as we can.
33 //
34 // We assume cookies do not contain any spaces (Netscape spec.)
35 // According to RFC2109 this is allowed though.
36 //
37 
38 #include <config.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #ifdef HAVE_SYS_PARAM_H
42 #include <sys/param.h>
43 #endif
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <stdio.h>
47 #include <string.h>
48 
49 #ifdef USE_SOLARIS
50 #include <strings.h>
51 #endif
52 
53 #include <stdlib.h>
54 
55 //#include <netinet/in.h>
56 //#include <arpa/inet.h>
57 
58 #include <tqstring.h>
59 #include <tqstrlist.h>
60 #include <tqptrlist.h>
61 #include <tqptrdict.h>
62 #include <tqfile.h>
63 #include <tqdir.h>
64 #include <tqregexp.h>
65 
66 #include <kurl.h>
67 #include <krfcdate.h>
68 #include <tdeconfig.h>
69 #include <ksavefile.h>
70 #include <kdebug.h>
71 
72 #include "kcookiejar.h"
73 
74 
75 // BR87227
76 // Waba: Should the number of cookies be limited?
77 // I am not convinced of the need of such limit
78 // Mozilla seems to limit to 20 cookies / domain
79 // but it is unclear which policy it uses to expire
80 // cookies when it exceeds that amount
81 #undef MAX_COOKIE_LIMIT
82 
83 #define MAX_COOKIES_PER_HOST 25
84 #define READ_BUFFER_SIZE 8192
85 #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]?)"
86 
87 // Note with respect to TQString::fromLatin1( )
88 // Cookies are stored as 8 bit data and passed to tdeio_http as
89 // latin1 regardless of their actual encoding.
90 
91 // L1 is used to indicate latin1 constants
92 #define L1(x) TQString::fromLatin1(x)
93 
94 template class TQPtrList<KHttpCookie>;
95 template class TQPtrDict<KHttpCookieList>;
96 
97 TQString KCookieJar::adviceToStr(KCookieAdvice _advice)
98 {
99  switch( _advice )
100  {
101  case KCookieAccept: return L1("Accept");
102  case KCookieReject: return L1("Reject");
103  case KCookieAsk: return L1("Ask");
104  default: return L1("Dunno");
105  }
106 }
107 
108 KCookieAdvice KCookieJar::strToAdvice(const TQString &_str)
109 {
110  if (_str.isEmpty())
111  return KCookieDunno;
112 
113  TQCString advice = _str.lower().latin1();
114 
115  if (advice == "accept")
116  return KCookieAccept;
117  else if (advice == "reject")
118  return KCookieReject;
119  else if (advice == "ask")
120  return KCookieAsk;
121 
122  return KCookieDunno;
123 }
124 
125 // KHttpCookie
127 
128 //
129 // Cookie constructor
130 //
131 KHttpCookie::KHttpCookie(const TQString &_host,
132  const TQString &_domain,
133  const TQString &_path,
134  const TQString &_name,
135  const TQString &_value,
136  time_t _expireDate,
137  int _protocolVersion,
138  bool _secure,
139  bool _httpOnly,
140  bool _explicitPath) :
141  mHost(_host),
142  mDomain(_domain),
143  mPath(_path.isEmpty() ? TQString::null : _path),
144  mName(_name),
145  mValue(_value),
146  mExpireDate(_expireDate),
147  mProtocolVersion(_protocolVersion),
148  mSecure(_secure),
149  mCrossDomain(false),
150  mHttpOnly(_httpOnly),
151  mExplicitPath(_explicitPath)
152 {
153 }
154 
155 //
156 // Checks if a cookie has been expired
157 //
158 bool KHttpCookie::isExpired(time_t currentDate)
159 {
160  return (mExpireDate != 0) && (mExpireDate < currentDate);
161 }
162 
163 //
164 // Returns a string for a HTTP-header
165 //
166 TQString KHttpCookie::cookieStr(bool useDOMFormat)
167 {
168  TQString result;
169 
170  if (useDOMFormat || (mProtocolVersion == 0))
171  {
172  if ( !mName.isEmpty() )
173  result = mName + '=';
174  result += mValue;
175  }
176  else
177  {
178  result = mName + '=' + mValue;
179  if (mExplicitPath)
180  result += L1("; $Path=\"") + mPath + L1("\"");
181  if (!mDomain.isEmpty())
182  result += L1("; $Domain=\"") + mDomain + L1("\"");
183  }
184  return result;
185 }
186 
187 //
188 // Returns whether this cookie should be send to this location.
189 bool KHttpCookie::match(const TQString &fqdn, const TQStringList &domains,
190  const TQString &path)
191 {
192  // Cookie domain match check
193  if (mDomain.isEmpty())
194  {
195  if (fqdn != mHost)
196  return false;
197  }
198  else if (!domains.contains(mDomain))
199  {
200  if (mDomain[0] == '.')
201  return false;
202 
203  // Maybe the domain needs an extra dot.
204  TQString domain = '.' + mDomain;
205  if ( !domains.contains( domain ) )
206  if ( fqdn != mDomain )
207  return false;
208  }
209 
210  // Cookie path match check
211  if (mPath.isEmpty())
212  return true;
213 
214  // According to the netscape spec both http://www.acme.com/foobar,
215  // http://www.acme.com/foo.bar and http://www.acme.com/foo/bar
216  // match http://www.acme.com/foo.
217  // We only match http://www.acme.com/foo/bar
218 
219  if( path.startsWith(mPath) &&
220  (
221  (path.length() == mPath.length() ) || // Paths are exact match
222  (path[mPath.length()-1] == '/') || // mPath ended with a slash
223  (path[mPath.length()] == '/') // A slash follows.
224  ))
225  return true; // Path of URL starts with cookie-path
226 
227  return false;
228 }
229 
230 // KHttpCookieList
232 
233 int KHttpCookieList::compareItems( void * item1, void * item2)
234 {
235  int pathLen1 = ((KHttpCookie *)item1)->path().length();
236  int pathLen2 = ((KHttpCookie *)item2)->path().length();
237  if (pathLen1 > pathLen2)
238  return -1;
239  if (pathLen1 < pathLen2)
240  return 1;
241  return 0;
242 }
243 
244 
245 // KCookieJar
247 
248 //
249 // Constructs a new cookie jar
250 //
251 // One jar should be enough for all cookies.
252 //
253 KCookieJar::KCookieJar()
254 {
255  m_cookieDomains.setAutoDelete( true );
256  m_globalAdvice = KCookieDunno;
257  m_configChanged = false;
258  m_cookiesChanged = false;
259 
260  TDEConfig cfg("tdehtml/domain_info", true, false, "data");
261  TQStringList countries = cfg.readListEntry("twoLevelTLD");
262  for(TQStringList::ConstIterator it = countries.begin();
263  it != countries.end(); ++it)
264  {
265  m_twoLevelTLD.replace(*it, (int *) 1);
266  }
267 }
268 
269 //
270 // Destructs the cookie jar
271 //
272 // Poor little cookies, they will all be eaten by the cookie monster!
273 //
274 KCookieJar::~KCookieJar()
275 {
276  // Not much to do here
277 }
278 
279 static void removeDuplicateFromList(KHttpCookieList *list, KHttpCookie *cookiePtr, bool nameMatchOnly=false, bool updateWindowId=false)
280 {
281  TQString domain1 = cookiePtr->domain();
282  if (domain1.isEmpty())
283  domain1 = cookiePtr->host();
284 
285  for ( KHttpCookiePtr cookie=list->first(); cookie != 0; )
286  {
287  TQString domain2 = cookie->domain();
288  if (domain2.isEmpty())
289  domain2 = cookie->host();
290 
291  if (
292  (cookiePtr->name() == cookie->name()) &&
293  (
294  nameMatchOnly ||
295  ( (domain1 == domain2) && (cookiePtr->path() == cookie->path()) )
296  )
297  )
298  {
299  if (updateWindowId)
300  {
301  for(TQValueList<long>::ConstIterator it = cookie->windowIds().begin();
302  it != cookie->windowIds().end(); ++it)
303  {
304  long windowId = *it;
305  if (windowId && (cookiePtr->windowIds().find(windowId) == cookiePtr->windowIds().end()))
306  {
307  cookiePtr->windowIds().append(windowId);
308  }
309  }
310  }
311  KHttpCookiePtr old_cookie = cookie;
312  cookie = list->next();
313  list->removeRef( old_cookie );
314  break;
315  }
316  else
317  {
318  cookie = list->next();
319  }
320  }
321 }
322 
323 
324 //
325 // Looks for cookies in the cookie jar which are appropriate for _url.
326 // Returned is a string containing all appropriate cookies in a format
327 // which can be added to a HTTP-header without any additional processing.
328 //
329 TQString KCookieJar::findCookies(const TQString &_url, bool useDOMFormat, long windowId, KHttpCookieList *pendingCookies)
330 {
331  TQString cookieStr;
332  TQStringList domains;
333  TQString fqdn;
334  TQString path;
335  KHttpCookiePtr cookie;
336  KCookieAdvice advice = m_globalAdvice;
337 
338  if (!parseURL(_url, fqdn, path))
339  return cookieStr;
340 
341  bool secureRequest = (_url.find( L1("https://"), 0, false) == 0 ||
342  _url.find( L1("webdavs://"), 0, false) == 0);
343 
344  // kdDebug(7104) << "findCookies: URL= " << _url << ", secure = " << secureRequest << endl;
345 
346  extractDomains(fqdn, domains);
347 
348  KHttpCookieList allCookies;
349 
350  for(TQStringList::ConstIterator it = domains.begin();
351  true;
352  ++it)
353  {
354  KHttpCookieList *cookieList;
355  if (it == domains.end())
356  {
357  cookieList = pendingCookies; // Add pending cookies
358  pendingCookies = 0;
359  if (!cookieList)
360  break;
361  }
362  else
363  {
364  TQString key = (*it).isNull() ? L1("") : (*it);
365  cookieList = m_cookieDomains[key];
366  if (!cookieList)
367  continue; // No cookies for this domain
368  }
369 
370  if (cookieList->getAdvice() != KCookieDunno)
371  advice = cookieList->getAdvice();
372 
373  for ( cookie=cookieList->first(); cookie != 0; cookie=cookieList->next() )
374  {
375  // If the we are setup to automatically accept all session cookies and to
376  // treat all cookies as session cookies or the current cookie is a session
377  // cookie, then send the cookie back regardless of either policy.
378  if (advice == KCookieReject &&
379  !(m_autoAcceptSessionCookies &&
380  (m_ignoreCookieExpirationDate || cookie->expireDate() == 0)))
381  continue;
382 
383  if (!cookie->match(fqdn, domains, path))
384  continue;
385 
386  if( cookie->isSecure() && !secureRequest )
387  continue;
388 
389  if( cookie->isHttpOnly() && useDOMFormat )
390  continue;
391 
392  // Do not send expired cookies.
393  if ( cookie->isExpired (time(0)) )
394  {
395  // Note there is no need to actually delete the cookie here
396  // since the cookieserver will invoke ::saveCookieJar because
397  // of the state change below. This will then do the job of
398  // deleting the cookie for us.
399  m_cookiesChanged = true;
400  continue;
401  }
402 
403  if (windowId && (cookie->windowIds().find(windowId) == cookie->windowIds().end()))
404  {
405  cookie->windowIds().append(windowId);
406  }
407 
408  if (it == domains.end()) // Only needed when processing pending cookies
409  removeDuplicateFromList(&allCookies, cookie);
410 
411  allCookies.append(cookie);
412  }
413  if (it == domains.end())
414  break; // Finished.
415  }
416 
417  int cookieCount = 0;
418 
419  int protVersion=0;
420  for ( cookie=allCookies.first(); cookie != 0; cookie=allCookies.next() )
421  {
422  if (cookie->protocolVersion() > protVersion)
423  protVersion = cookie->protocolVersion();
424  }
425 
426  for ( cookie=allCookies.first(); cookie != 0; cookie=allCookies.next() )
427  {
428  if (useDOMFormat)
429  {
430  if (cookieCount > 0)
431  cookieStr += L1("; ");
432  cookieStr += cookie->cookieStr(true);
433  }
434  else
435  {
436  if (cookieCount == 0)
437  {
438  cookieStr += L1("Cookie: ");
439  if (protVersion > 0)
440  {
441  TQString version;
442  version.sprintf("$Version=%d; ", protVersion); // Without quotes
443  cookieStr += version;
444  }
445  }
446  else
447  {
448  cookieStr += L1("; ");
449  }
450  cookieStr += cookie->cookieStr(false);
451  }
452  cookieCount++;
453  }
454 
455  return cookieStr;
456 }
457 
458 //
459 // This function parses a string like 'my_name="my_value";' and returns
460 // 'my_name' in Name and 'my_value' in Value.
461 //
462 // A pointer to the end of the parsed part is returned.
463 // This pointer points either to:
464 // '\0' - The end of the string has reached.
465 // ';' - Another my_name="my_value" pair follows
466 // ',' - Another cookie follows
467 // '\n' - Another header follows
468 static const char * parseNameValue(const char *header,
469  TQString &Name,
470  TQString &Value,
471  bool keepQuotes=false,
472  bool rfcQuotes=false)
473 {
474  const char *s = header;
475  // Parse 'my_name' part
476  for(; (*s != '='); s++)
477  {
478  if ((*s=='\0') || (*s==';') || (*s=='\n'))
479  {
480  // No '=' sign -> use string as the value, name is empty
481  // (behavior found in Mozilla and IE)
482  Name = "";
483  Value = TQString::fromLatin1(header);
484  Value.truncate( s - header );
485  Value = Value.stripWhiteSpace();
486  return (s);
487  }
488  }
489 
490  Name = header;
491  Name.truncate( s - header );
492  Name = Name.stripWhiteSpace();
493 
494  // *s == '='
495  s++;
496 
497  // Skip any whitespace
498  for(; (*s == ' ') || (*s == '\t'); s++)
499  {
500  if ((*s=='\0') || (*s==';') || (*s=='\n'))
501  {
502  // End of Name
503  Value = "";
504  return (s);
505  }
506  }
507 
508  if ((rfcQuotes || !keepQuotes) && (*s == '\"'))
509  {
510  // Parse '"my_value"' part (quoted value)
511  if (keepQuotes)
512  header = s++;
513  else
514  header = ++s; // skip "
515  for(;(*s != '\"');s++)
516  {
517  if ((*s=='\0') || (*s=='\n'))
518  {
519  // End of Name
520  Value = TQString::fromLatin1(header);
521  Value.truncate(s - header);
522  return (s);
523  }
524  }
525  Value = TQString::fromLatin1(header);
526  // *s == '\"';
527  if (keepQuotes)
528  Value.truncate( ++s - header );
529  else
530  Value.truncate( s++ - header );
531 
532  // Skip any remaining garbage
533  for(;; s++)
534  {
535  if ((*s=='\0') || (*s==';') || (*s=='\n'))
536  break;
537  }
538  }
539  else
540  {
541  // Parse 'my_value' part (unquoted value)
542  header = s;
543  while ((*s != '\0') && (*s != ';') && (*s != '\n'))
544  s++;
545  // End of Name
546  Value = TQString::fromLatin1(header);
547  Value.truncate( s - header );
548  Value = Value.stripWhiteSpace();
549  }
550  return (s);
551 
552 }
553 
554 void KCookieJar::stripDomain(const TQString &_fqdn, TQString &_domain)
555 {
556  TQStringList domains;
557  extractDomains(_fqdn, domains);
558  if (domains.count() > 3)
559  _domain = domains[3];
560  else
561  _domain = domains[0];
562 }
563 
564 TQString KCookieJar::stripDomain( KHttpCookiePtr cookiePtr)
565 {
566  TQString domain; // We file the cookie under this domain.
567  if (cookiePtr->domain().isEmpty())
568  stripDomain( cookiePtr->host(), domain);
569  else
570  stripDomain (cookiePtr->domain(), domain);
571  return domain;
572 }
573 
574 bool KCookieJar::parseURL(const TQString &_url,
575  TQString &_fqdn,
576  TQString &_path)
577 {
578  KURL kurl(_url);
579  if (!kurl.isValid())
580  return false;
581 
582  _fqdn = kurl.host().lower();
583  if (kurl.port())
584  {
585  if (((kurl.protocol() == L1("http")) && (kurl.port() != 80)) ||
586  ((kurl.protocol() == L1("https")) && (kurl.port() != 443)))
587  {
588  _fqdn = L1("%1:%2").arg(kurl.port()).arg(_fqdn);
589  }
590  }
591 
592  // Cookie spoofing protection. Since there is no way a path separator
593  // or escape encoded character is allowed in the hostname according
594  // to RFC 2396, reject attempts to include such things there!
595  if(_fqdn.find('/') > -1 || _fqdn.find('%') > -1)
596  {
597  return false; // deny everything!!
598  }
599 
600  _path = kurl.path();
601  if (_path.isEmpty())
602  _path = L1("/");
603 
604  TQRegExp exp(L1("[\\\\/]\\.\\.[\\\\/]"));
605  // Weird path, cookie stealing attempt?
606  if (exp.search(_path) != -1)
607  return false; // Deny everything!!
608 
609  return true;
610 }
611 
612 void KCookieJar::extractDomains(const TQString &_fqdn,
613  TQStringList &_domains)
614 {
615  // Return numeric IPv6 addresses as is...
616  if (_fqdn[0] == '[')
617  {
618  _domains.append( _fqdn );
619  return;
620  }
621  // Return numeric IPv4 addresses as is...
622  if ((_fqdn.at(0) >= TQChar('0')) && (_fqdn.at(0) <= TQChar('9')))
623  {
624  if (_fqdn.find(TQRegExp(IP_ADDRESS_EXPRESSION)) > -1)
625  {
626  _domains.append( _fqdn );
627  return;
628  }
629  }
630 
631  TQStringList partList = TQStringList::split('.', _fqdn, false);
632 
633  if (partList.count())
634  partList.remove(partList.begin()); // Remove hostname
635 
636  while(partList.count())
637  {
638 
639  if (partList.count() == 1)
640  break; // We only have a TLD left.
641 
642  if ((partList.count() == 2) && (m_twoLevelTLD[partList[1].lower()]))
643  {
644  // This domain uses two-level TLDs in the form xxxx.yy
645  break;
646  }
647 
648  if ((partList.count() == 2) && (partList[1].length() == 2))
649  {
650  // If this is a TLD, we should stop. (e.g. co.uk)
651  // We assume this is a TLD if it ends with .xx.yy or .x.yy
652  if (partList[0].length() <= 2)
653  break; // This is a TLD.
654 
655  // Catch some TLDs that we miss with the previous check
656  // e.g. com.au, org.uk, mil.co
657  TQCString t = partList[0].lower().utf8();
658  if ((t == "com") || (t == "net") || (t == "org") || (t == "gov") || (t == "edu") || (t == "mil") || (t == "int"))
659  break;
660  }
661 
662  TQString domain = partList.join(L1("."));
663  _domains.append(domain);
664  _domains.append('.' + domain);
665  partList.remove(partList.begin()); // Remove part
666  }
667 
668  // Always add the FQDN at the start of the list for
669  // hostname == cookie-domainname checks!
670  _domains.prepend( '.' + _fqdn );
671  _domains.prepend( _fqdn );
672 }
673 
674 
675 /*
676  Changes dates in from the following format
677 
678  Wed Sep 12 07:00:00 2007 GMT
679  to
680  Wed Sep 12 2007 07:00:00 GMT
681 
682  to allow KRFCDate::parseDate to properly parse expiration date formats
683  used in cookies by some servers such as amazon.com. See BR# 145244.
684 */
685 static TQString fixupDateTime(const TQString& dt)
686 {
687  const int index = dt.find(TQRegExp("[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}"));
688 
689  if (index > -1)
690  {
691  TQStringList dateStrList = TQStringList::split(' ', dt.mid(index));
692  if (dateStrList.count() > 1)
693  {
694  TQString date = dateStrList[0];
695  dateStrList[0] = dateStrList[1];
696  dateStrList[1] = date;
697  date = dt;
698  return date.replace(index, date.length(), dateStrList.join(" "));
699  }
700  }
701 
702  return dt;
703 }
704 
705 //
706 // This function parses cookie_headers and returns a linked list of
707 // KHttpCookie objects for all cookies found in cookie_headers.
708 // If no cookies could be found 0 is returned.
709 //
710 // cookie_headers should be a concatenation of all lines of a HTTP-header
711 // which start with "Set-Cookie". The lines should be separated by '\n's.
712 //
713 KHttpCookieList KCookieJar::makeCookies(const TQString &_url,
714  const TQCString &cookie_headers,
715  long windowId)
716 {
717  KHttpCookieList cookieList;
718  KHttpCookieList cookieList2;
719  KHttpCookiePtr lastCookie = 0;
720  const char *cookieStr = cookie_headers.data();
721  TQString Name;
722  TQString Value;
723  TQString fqdn;
724  TQString path;
725  bool crossDomain = false;
726 
727  if (!parseURL(_url, fqdn, path))
728  {
729  // Error parsing _url
730  return KHttpCookieList();
731  }
732  TQString defaultPath;
733  int i = path.findRev('/');
734  if (i > 0)
735  defaultPath = path.left(i);
736 
737  // The hard stuff :)
738  for(;;)
739  {
740  // check for "Set-Cookie"
741  if (strncmp(cookieStr, "Cross-Domain\n", 13) == 0)
742  {
743  cookieStr += 13;
744  crossDomain = true;
745  }
746  else if (strncasecmp(cookieStr, "Set-Cookie:", 11) == 0)
747  {
748  cookieStr = parseNameValue(cookieStr+11, Name, Value, true);
749 
750  // Host = FQDN
751  // Default domain = ""
752  // Default path according to rfc2109
753 
754  KHttpCookie *cookie = new KHttpCookie(fqdn, L1(""), defaultPath, Name, Value);
755  if (windowId)
756  cookie->mWindowIds.append(windowId);
757  cookie->mCrossDomain = crossDomain;
758 
759  // Insert cookie in chain
760  cookieList.append(cookie);
761  lastCookie = cookie;
762  }
763  else if (strncasecmp(cookieStr, "Set-Cookie2:", 12) == 0)
764  {
765  // Attempt to follow rfc2965
766  cookieStr = parseNameValue(cookieStr+12, Name, Value, true, true);
767 
768  // Host = FQDN
769  // Default domain = ""
770  // Default path according to rfc2965
771 
772  KHttpCookie *cookie = new KHttpCookie(fqdn, L1(""), defaultPath, Name, Value);
773  if (windowId)
774  cookie->mWindowIds.append(windowId);
775  cookie->mCrossDomain = crossDomain;
776 
777  // Insert cookie in chain
778  cookieList2.append(cookie);
779  lastCookie = cookie;
780  }
781  else
782  {
783  // This is not the start of a cookie header, skip till next line.
784  while (*cookieStr && *cookieStr != '\n')
785  cookieStr++;
786 
787  if (*cookieStr == '\n')
788  cookieStr++;
789 
790  if (!*cookieStr)
791  break; // End of cookie_headers
792  else
793  continue; // end of this header, continue with next.
794  }
795 
796  while ((*cookieStr == ';') || (*cookieStr == ' '))
797  {
798  cookieStr++;
799 
800  // Name-Value pair follows
801  cookieStr = parseNameValue(cookieStr, Name, Value);
802 
803  TQCString cName = Name.lower().latin1();
804  if (cName == "domain")
805  {
806  TQString dom = Value.lower();
807  // RFC2965 3.2.2: If an explicitly specified value does not
808  // start with a dot, the user agent supplies a leading dot
809  if(dom.length() && dom[0] != '.')
810  dom.prepend(".");
811  // remove a trailing dot
812  if(dom.length() > 2 && dom[dom.length()-1] == '.')
813  dom = dom.left(dom.length()-1);
814 
815  if(dom.contains('.') > 1 || dom == ".local")
816  lastCookie->mDomain = dom;
817  }
818  else if (cName == "max-age")
819  {
820  int max_age = Value.toInt();
821  if (max_age == 0)
822  lastCookie->mExpireDate = 1;
823  else
824  lastCookie->mExpireDate = time(0)+max_age;
825  }
826  else if (cName == "expires")
827  {
828  // Parse brain-dead netscape cookie-format
829  lastCookie->mExpireDate = KRFCDate::parseDate(Value);
830 
831  // Workaround for servers that send the expiration date in
832  // 'Wed Sep 12 07:00:00 2007 GMT' format. See BR# 145244.
833  if (lastCookie->mExpireDate == 0)
834  lastCookie->mExpireDate = KRFCDate::parseDate(fixupDateTime(Value));
835  }
836  else if (cName == "path")
837  {
838  if (Value.isEmpty())
839  lastCookie->mPath = TQString::null; // Catch "" <> TQString::null
840  else
841  lastCookie->mPath = KURL::decode_string(Value);
842  lastCookie->mExplicitPath = true;
843  }
844  else if (cName == "version")
845  {
846  lastCookie->mProtocolVersion = Value.toInt();
847  }
848  else if ((cName == "secure") ||
849  (cName.isEmpty() && Value.lower() == L1("secure")))
850  {
851  lastCookie->mSecure = true;
852  }
853  else if ((cName == "httponly") ||
854  (cName.isEmpty() && Value.lower() == L1("httponly")))
855  {
856  lastCookie->mHttpOnly = true;
857  }
858  }
859 
860  if (*cookieStr == '\0')
861  break; // End of header
862 
863  // Skip ';' or '\n'
864  cookieStr++;
865  }
866 
867  // RFC2965 cookies come last so that they override netscape cookies.
868  while( !cookieList2.isEmpty() && (lastCookie = cookieList2.take(0)) )
869  {
870  removeDuplicateFromList(&cookieList, lastCookie, true);
871  cookieList.append(lastCookie);
872  }
873 
874  return cookieList;
875 }
876 
883 KHttpCookieList KCookieJar::makeDOMCookies(const TQString &_url,
884  const TQCString &cookie_domstring,
885  long windowId)
886 {
887  // A lot copied from above
888  KHttpCookieList cookieList;
889  KHttpCookiePtr lastCookie = 0;
890 
891  const char *cookieStr = cookie_domstring.data();
892  TQString Name;
893  TQString Value;
894  TQString fqdn;
895  TQString path;
896 
897  if (!parseURL(_url, fqdn, path))
898  {
899  // Error parsing _url
900  return KHttpCookieList();
901  }
902 
903  // This time it's easy
904  while(*cookieStr)
905  {
906  cookieStr = parseNameValue(cookieStr, Name, Value);
907 
908  // Host = FQDN
909  // Default domain = ""
910  // Default path = ""
911  KHttpCookie *cookie = new KHttpCookie(fqdn, TQString::null, TQString::null,
912  Name, Value );
913  if (windowId)
914  cookie->mWindowIds.append(windowId);
915 
916  cookieList.append(cookie);
917  lastCookie = cookie;
918 
919  if (*cookieStr != '\0')
920  cookieStr++; // Skip ';' or '\n'
921  }
922 
923  return cookieList;
924 }
925 
926 #ifdef MAX_COOKIE_LIMIT
927 static void makeRoom(KHttpCookieList *cookieList, KHttpCookiePtr &cookiePtr)
928 {
929  // Too much cookies: throw one away, try to be somewhat clever
930  KHttpCookiePtr lastCookie = 0;
931  for(KHttpCookiePtr cookie = cookieList->first(); cookie; cookie = cookieList->next())
932  {
933  if (cookieList->compareItems(cookie, cookiePtr) < 0)
934  break;
935  lastCookie = cookie;
936  }
937  if (!lastCookie)
938  lastCookie = cookieList->first();
939  cookieList->removeRef(lastCookie);
940 }
941 #endif
942 
943 //
944 // This function hands a KHttpCookie object over to the cookie jar.
945 //
946 // On return cookiePtr is set to 0.
947 //
948 void KCookieJar::addCookie(KHttpCookiePtr &cookiePtr)
949 {
950  TQStringList domains;
951  KHttpCookieList *cookieList = 0L;
952 
953  // We always need to do this to make sure that the
954  // that cookies of type hostname == cookie-domainname
955  // are properly removed and/or updated as necessary!
956  extractDomains( cookiePtr->host(), domains );
957  for ( TQStringList::ConstIterator it = domains.begin();
958  (it != domains.end() && !cookieList);
959  ++it )
960  {
961  TQString key = (*it).isNull() ? L1("") : (*it);
962  KHttpCookieList *list= m_cookieDomains[key];
963  if ( !list ) continue;
964 
965  removeDuplicateFromList(list, cookiePtr, false, true);
966  }
967 
968  TQString domain = stripDomain( cookiePtr );
969  TQString key = domain.isNull() ? L1("") : domain;
970  cookieList = m_cookieDomains[ key ];
971  if (!cookieList)
972  {
973  // Make a new cookie list
974  cookieList = new KHttpCookieList();
975  cookieList->setAutoDelete(true);
976 
977  // All cookies whose domain is not already
978  // known to us should be added with KCookieDunno.
979  // KCookieDunno means that we use the global policy.
980  cookieList->setAdvice( KCookieDunno );
981 
982  m_cookieDomains.insert( domain, cookieList);
983 
984  // Update the list of domains
985  m_domainList.append(domain);
986  }
987 
988  // Add the cookie to the cookie list
989  // The cookie list is sorted 'longest path first'
990  if (!cookiePtr->isExpired(time(0)))
991  {
992 #ifdef MAX_COOKIE_LIMIT
993  if (cookieList->count() >= MAX_COOKIES_PER_HOST)
994  makeRoom(cookieList, cookiePtr); // Delete a cookie
995 #endif
996  cookieList->inSort( cookiePtr );
997  m_cookiesChanged = true;
998  }
999  else
1000  {
1001  delete cookiePtr;
1002  }
1003  cookiePtr = 0;
1004 }
1005 
1006 //
1007 // This function advices whether a single KHttpCookie object should
1008 // be added to the cookie jar.
1009 //
1010 KCookieAdvice KCookieJar::cookieAdvice(KHttpCookiePtr cookiePtr)
1011 {
1012  if (m_rejectCrossDomainCookies && cookiePtr->isCrossDomain())
1013  return KCookieReject;
1014 
1015  TQStringList domains;
1016 
1017  extractDomains(cookiePtr->host(), domains);
1018 
1019  // If the cookie specifies a domain, check whether it is valid. Otherwise,
1020  // accept the cookie anyways but remove the domain="" value to prevent
1021  // cross-site cookie injection.
1022  if (!cookiePtr->domain().isEmpty())
1023  {
1024  if (!domains.contains(cookiePtr->domain()) &&
1025  !cookiePtr->domain().endsWith("."+cookiePtr->host()))
1026  cookiePtr->fixDomain(TQString::null);
1027  }
1028 
1029  if (m_autoAcceptSessionCookies && (cookiePtr->expireDate() == 0 ||
1030  m_ignoreCookieExpirationDate))
1031  return KCookieAccept;
1032 
1033  KCookieAdvice advice = KCookieDunno;
1034  bool isFQDN = true; // First is FQDN
1035  TQStringList::Iterator it = domains.begin(); // Start with FQDN which first in the list.
1036  while( (advice == KCookieDunno) && (it != domains.end()))
1037  {
1038  TQString domain = *it;
1039  // Check if a policy for the FQDN/domain is set.
1040  if ( domain[0] == '.' || isFQDN )
1041  {
1042  isFQDN = false;
1043  KHttpCookieList *cookieList = m_cookieDomains[domain];
1044  if (cookieList)
1045  advice = cookieList->getAdvice();
1046  }
1047  domains.remove(it);
1048  it = domains.begin(); // Continue from begin of remaining list
1049  }
1050 
1051  if (advice == KCookieDunno)
1052  advice = m_globalAdvice;
1053 
1054  return advice;
1055 }
1056 
1057 //
1058 // This function gets the advice for all cookies originating from
1059 // _domain.
1060 //
1061 KCookieAdvice KCookieJar::getDomainAdvice(const TQString &_domain)
1062 {
1063  KHttpCookieList *cookieList = m_cookieDomains[_domain];
1064  KCookieAdvice advice;
1065 
1066  if (cookieList)
1067  {
1068  advice = cookieList->getAdvice();
1069  }
1070  else
1071  {
1072  advice = KCookieDunno;
1073  }
1074 
1075  return advice;
1076 }
1077 
1078 //
1079 // This function sets the advice for all cookies originating from
1080 // _domain.
1081 //
1082 void KCookieJar::setDomainAdvice(const TQString &_domain, KCookieAdvice _advice)
1083 {
1084  TQString domain(_domain);
1085  KHttpCookieList *cookieList = m_cookieDomains[domain];
1086 
1087  if (cookieList)
1088  {
1089  if (cookieList->getAdvice() != _advice)
1090  {
1091  m_configChanged = true;
1092  // domain is already known
1093  cookieList->setAdvice( _advice);
1094  }
1095 
1096  if ((cookieList->isEmpty()) &&
1097  (_advice == KCookieDunno))
1098  {
1099  // This deletes cookieList!
1100  m_cookieDomains.remove(domain);
1101  m_domainList.remove(domain);
1102  }
1103  }
1104  else
1105  {
1106  // domain is not yet known
1107  if (_advice != KCookieDunno)
1108  {
1109  // We should create a domain entry
1110  m_configChanged = true;
1111  // Make a new cookie list
1112  cookieList = new KHttpCookieList();
1113  cookieList->setAutoDelete(true);
1114  cookieList->setAdvice( _advice);
1115  m_cookieDomains.insert( domain, cookieList);
1116  // Update the list of domains
1117  m_domainList.append( domain);
1118  }
1119  }
1120 }
1121 
1122 //
1123 // This function sets the advice for all cookies originating from
1124 // the same domain as _cookie
1125 //
1126 void KCookieJar::setDomainAdvice(KHttpCookiePtr cookiePtr, KCookieAdvice _advice)
1127 {
1128  TQString domain;
1129  stripDomain(cookiePtr->host(), domain); // We file the cookie under this domain.
1130 
1131  setDomainAdvice(domain, _advice);
1132 }
1133 
1134 //
1135 // This function sets the global advice for cookies
1136 //
1137 void KCookieJar::setGlobalAdvice(KCookieAdvice _advice)
1138 {
1139  if (m_globalAdvice != _advice)
1140  m_configChanged = true;
1141  m_globalAdvice = _advice;
1142 }
1143 
1144 //
1145 // Get a list of all domains known to the cookie jar.
1146 //
1147 const TQStringList& KCookieJar::getDomainList()
1148 {
1149  return m_domainList;
1150 }
1151 
1152 //
1153 // Get a list of all cookies in the cookie jar originating from _domain.
1154 //
1155 const KHttpCookieList *KCookieJar::getCookieList(const TQString & _domain,
1156  const TQString & _fqdn )
1157 {
1158  TQString domain;
1159 
1160  if (_domain.isEmpty())
1161  stripDomain( _fqdn, domain );
1162  else
1163  domain = _domain;
1164 
1165  return m_cookieDomains[domain];
1166 }
1167 
1168 //
1169 // Eat a cookie out of the jar.
1170 // cookiePtr should be one of the cookies returned by getCookieList()
1171 //
1172 void KCookieJar::eatCookie(KHttpCookiePtr cookiePtr)
1173 {
1174  TQString domain = stripDomain(cookiePtr); // We file the cookie under this domain.
1175  KHttpCookieList *cookieList = m_cookieDomains[domain];
1176 
1177  if (cookieList)
1178  {
1179  // This deletes cookiePtr!
1180  if (cookieList->removeRef( cookiePtr ))
1181  m_cookiesChanged = true;
1182 
1183  if ((cookieList->isEmpty()) &&
1184  (cookieList->getAdvice() == KCookieDunno))
1185  {
1186  // This deletes cookieList!
1187  m_cookieDomains.remove(domain);
1188 
1189  m_domainList.remove(domain);
1190  }
1191  }
1192 }
1193 
1194 void KCookieJar::eatCookiesForDomain(const TQString &domain)
1195 {
1196  KHttpCookieList *cookieList = m_cookieDomains[domain];
1197  if (!cookieList || cookieList->isEmpty()) return;
1198 
1199  cookieList->clear();
1200  if (cookieList->getAdvice() == KCookieDunno)
1201  {
1202  // This deletes cookieList!
1203  m_cookieDomains.remove(domain);
1204  m_domainList.remove(domain);
1205  }
1206  m_cookiesChanged = true;
1207 }
1208 
1209 void KCookieJar::eatSessionCookies( long windowId )
1210 {
1211  if (!windowId)
1212  return;
1213 
1214  TQStringList::Iterator it=m_domainList.begin();
1215  for ( ; it != m_domainList.end(); ++it )
1216  eatSessionCookies( *it, windowId, false );
1217 }
1218 
1219 void KCookieJar::eatAllCookies()
1220 {
1221  for ( TQStringList::Iterator it=m_domainList.begin();
1222  it != m_domainList.end();)
1223  {
1224  TQString domain = *it++;
1225  // This might remove domain from domainList!
1226  eatCookiesForDomain(domain);
1227  }
1228 }
1229 
1230 void KCookieJar::eatSessionCookies( const TQString& fqdn, long windowId,
1231  bool isFQDN )
1232 {
1233  KHttpCookieList* cookieList;
1234  if ( !isFQDN )
1235  cookieList = m_cookieDomains[fqdn];
1236  else
1237  {
1238  TQString domain;
1239  stripDomain( fqdn, domain );
1240  cookieList = m_cookieDomains[domain];
1241  }
1242 
1243  if ( cookieList )
1244  {
1245  KHttpCookiePtr cookie=cookieList->first();
1246  for (; cookie != 0;)
1247  {
1248  if ((cookie->expireDate() != 0) && !m_ignoreCookieExpirationDate)
1249  {
1250  cookie = cookieList->next();
1251  continue;
1252  }
1253 
1254  TQValueList<long> &ids = cookie->windowIds();
1255  if (!ids.remove(windowId) || !ids.isEmpty())
1256  {
1257  cookie = cookieList->next();
1258  continue;
1259  }
1260  KHttpCookiePtr old_cookie = cookie;
1261  cookie = cookieList->next();
1262  cookieList->removeRef( old_cookie );
1263  }
1264  }
1265 }
1266 
1267 //
1268 // Saves all cookies to the file '_filename'.
1269 // On succes 'true' is returned.
1270 // On failure 'false' is returned.
1271 bool KCookieJar::saveCookies(const TQString &_filename)
1272 {
1273  KSaveFile saveFile(_filename, 0600);
1274 
1275  if (saveFile.status() != 0)
1276  return false;
1277 
1278  FILE *fStream = saveFile.fstream();
1279 
1280  time_t curTime = time(0);
1281 
1282  fprintf(fStream, "# KDE Cookie File v2\n#\n");
1283 
1284  fprintf(fStream, "%-20s %-20s %-12s %-10s %-4s %-20s %-4s %s\n",
1285  "# Host", "Domain", "Path", "Exp.date", "Prot",
1286  "Name", "Sec", "Value");
1287 
1288  for ( TQStringList::Iterator it=m_domainList.begin(); it != m_domainList.end();
1289  it++ )
1290  {
1291  const TQString &domain = *it;
1292  bool domainPrinted = false;
1293 
1294  KHttpCookieList *cookieList = m_cookieDomains[domain];
1295  KHttpCookiePtr cookie=cookieList->last();
1296 
1297  for (; cookie != 0;)
1298  {
1299  if (cookie->isExpired(curTime))
1300  {
1301  // Delete expired cookies
1302  KHttpCookiePtr old_cookie = cookie;
1303  cookie = cookieList->prev();
1304  cookieList->removeRef( old_cookie );
1305  }
1306  else if (cookie->expireDate() != 0 && !m_ignoreCookieExpirationDate)
1307  {
1308  if (!domainPrinted)
1309  {
1310  domainPrinted = true;
1311  fprintf(fStream, "[%s]\n", domain.local8Bit().data());
1312  }
1313  // Store persistent cookies
1314  TQString path = L1("\"");
1315  path += cookie->path();
1316  path += '"';
1317  TQString domain = L1("\"");
1318  domain += cookie->domain();
1319  domain += '"';
1320  fprintf(fStream, "%-20s %-20s %-12s %10lu %3d %-20s %-4i %s\n",
1321  cookie->host().latin1(), domain.latin1(),
1322  path.latin1(), (unsigned long) cookie->expireDate(),
1323  cookie->protocolVersion(),
1324  cookie->name().isEmpty() ? cookie->value().latin1() : cookie->name().latin1(),
1325  (cookie->isSecure() ? 1 : 0) + (cookie->isHttpOnly() ? 2 : 0) +
1326  (cookie->hasExplicitPath() ? 4 : 0) + (cookie->name().isEmpty() ? 8 : 0),
1327  cookie->value().latin1());
1328  cookie = cookieList->prev();
1329  }
1330  else
1331  {
1332  // Skip session-only cookies
1333  cookie = cookieList->prev();
1334  }
1335  }
1336  }
1337 
1338  return saveFile.close();
1339 }
1340 
1341 typedef char *charPtr;
1342 
1343 static const char *parseField(charPtr &buffer, bool keepQuotes=false)
1344 {
1345  char *result;
1346  if (!keepQuotes && (*buffer == '\"'))
1347  {
1348  // Find terminating "
1349  buffer++;
1350  result = buffer;
1351  while((*buffer != '\"') && (*buffer))
1352  buffer++;
1353  }
1354  else
1355  {
1356  // Find first white space
1357  result = buffer;
1358  while((*buffer != ' ') && (*buffer != '\t') && (*buffer != '\n') && (*buffer))
1359  buffer++;
1360  }
1361 
1362  if (!*buffer)
1363  return result; //
1364  *buffer++ = '\0';
1365 
1366  // Skip white-space
1367  while((*buffer == ' ') || (*buffer == '\t') || (*buffer == '\n'))
1368  buffer++;
1369 
1370  return result;
1371 }
1372 
1373 
1374 //
1375 // Reloads all cookies from the file '_filename'.
1376 // On succes 'true' is returned.
1377 // On failure 'false' is returned.
1378 bool KCookieJar::loadCookies(const TQString &_filename)
1379 {
1380  FILE *fStream = fopen( TQFile::encodeName(_filename), "r");
1381  if (fStream == 0)
1382  {
1383  return false;
1384  }
1385 
1386  time_t curTime = time(0);
1387 
1388  char *buffer = new char[READ_BUFFER_SIZE];
1389 
1390  bool err = false;
1391  err = (fgets(buffer, READ_BUFFER_SIZE, fStream) == 0);
1392 
1393  int version = 1;
1394  if (!err)
1395  {
1396  if (strcmp(buffer, "# KDE Cookie File\n") == 0)
1397  {
1398  // version 1
1399  }
1400  else if (sscanf(buffer, "# KDE Cookie File v%d\n", &version) != 1)
1401  {
1402  err = true;
1403  }
1404  }
1405 
1406  if (!err)
1407  {
1408  while(fgets(buffer, READ_BUFFER_SIZE, fStream) != 0)
1409  {
1410  char *line = buffer;
1411  // Skip lines which begin with '#' or '['
1412  if ((line[0] == '#') || (line[0] == '['))
1413  continue;
1414 
1415  const char *host( parseField(line) );
1416  const char *domain( parseField(line) );
1417  const char *path( parseField(line) );
1418  const char *expStr( parseField(line) );
1419  if (!expStr) continue;
1420  int expDate = (time_t) strtoul(expStr, 0, 10);
1421  const char *verStr( parseField(line) );
1422  if (!verStr) continue;
1423  int protVer = (time_t) strtoul(verStr, 0, 10);
1424  const char *name( parseField(line) );
1425  bool keepQuotes = false;
1426  bool secure = false;
1427  bool httpOnly = false;
1428  bool explicitPath = false;
1429  const char *value = 0;
1430  if ((version == 2) || (protVer >= 200))
1431  {
1432  if (protVer >= 200)
1433  protVer -= 200;
1434  int i = atoi( parseField(line) );
1435  secure = i & 1;
1436  httpOnly = i & 2;
1437  explicitPath = i & 4;
1438  if (i & 8)
1439  name = "";
1440  line[strlen(line)-1] = '\0'; // Strip LF.
1441  value = line;
1442  }
1443  else
1444  {
1445  if (protVer >= 100)
1446  {
1447  protVer -= 100;
1448  keepQuotes = true;
1449  }
1450  value = parseField(line, keepQuotes);
1451  secure = atoi( parseField(line) );
1452  }
1453 
1454  // Parse error
1455  if (!value) continue;
1456 
1457  // Expired or parse error
1458  if ((expDate == 0) || (expDate < curTime))
1459  continue;
1460 
1461  KHttpCookie *cookie = new KHttpCookie(TQString::fromLatin1(host),
1462  TQString::fromLatin1(domain),
1463  TQString::fromLatin1(path),
1464  TQString::fromLatin1(name),
1465  TQString::fromLatin1(value),
1466  expDate, protVer,
1467  secure, httpOnly, explicitPath);
1468  addCookie(cookie);
1469  }
1470  }
1471  delete [] buffer;
1472  m_cookiesChanged = false;
1473 
1474  fclose( fStream);
1475  return err;
1476 }
1477 
1478 //
1479 // Save the cookie configuration
1480 //
1481 
1482 void KCookieJar::saveConfig(TDEConfig *_config)
1483 {
1484  if (!m_configChanged)
1485  return;
1486 
1487  _config->setGroup("Cookie Dialog");
1488  _config->writeEntry("PreferredPolicy", m_preferredPolicy);
1489  _config->writeEntry("ShowCookieDetails", m_showCookieDetails );
1490  _config->setGroup("Cookie Policy");
1491  _config->writeEntry("CookieGlobalAdvice", adviceToStr( m_globalAdvice));
1492 
1493  TQStringList domainSettings;
1494  for ( TQStringList::Iterator it=m_domainList.begin();
1495  it != m_domainList.end();
1496  it++ )
1497  {
1498  const TQString &domain = *it;
1499  KCookieAdvice advice = getDomainAdvice( domain);
1500  if (advice != KCookieDunno)
1501  {
1502  TQString value(domain);
1503  value += ':';
1504  value += adviceToStr(advice);
1505  domainSettings.append(value);
1506  }
1507  }
1508  _config->writeEntry("CookieDomainAdvice", domainSettings);
1509  _config->sync();
1510  m_configChanged = false;
1511 }
1512 
1513 
1514 //
1515 // Load the cookie configuration
1516 //
1517 
1518 void KCookieJar::loadConfig(TDEConfig *_config, bool reparse )
1519 {
1520  if ( reparse )
1521  _config->reparseConfiguration();
1522 
1523  _config->setGroup("Cookie Dialog");
1524  m_showCookieDetails = _config->readBoolEntry( "ShowCookieDetails" );
1525  m_preferredPolicy = _config->readNumEntry( "PreferredPolicy", 0 );
1526 
1527  _config->setGroup("Cookie Policy");
1528  TQStringList domainSettings = _config->readListEntry("CookieDomainAdvice");
1529  m_rejectCrossDomainCookies = _config->readBoolEntry( "RejectCrossDomainCookies", true );
1530  m_autoAcceptSessionCookies = _config->readBoolEntry( "AcceptSessionCookies", true );
1531  m_ignoreCookieExpirationDate = _config->readBoolEntry( "IgnoreExpirationDate", false );
1532  TQString value = _config->readEntry("CookieGlobalAdvice", L1("Ask"));
1533  m_globalAdvice = strToAdvice(value);
1534 
1535  // Reset current domain settings first.
1536  for ( TQStringList::Iterator it=m_domainList.begin(); it != m_domainList.end(); )
1537  {
1538  // Make sure to update iterator before calling setDomainAdvice()
1539  // setDomainAdvice() might delete the domain from domainList.
1540  TQString domain = *it++;
1541  setDomainAdvice(domain, KCookieDunno);
1542  }
1543 
1544  // Now apply the domain settings read from config file...
1545  for ( TQStringList::Iterator it=domainSettings.begin();
1546  it != domainSettings.end(); )
1547  {
1548  const TQString &value = *it++;
1549 
1550  int sepPos = value.findRev(':');
1551 
1552  if (sepPos <= 0)
1553  continue;
1554 
1555  TQString domain(value.left(sepPos));
1556  KCookieAdvice advice = strToAdvice( value.mid(sepPos + 1) );
1557  setDomainAdvice(domain, advice);
1558  }
1559 }

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeioslave/http by doxygen 1.8.8
This website is maintained by Timothy Pearson.