Qt 4.8
qnetworkcookie.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qnetworkcookie.h"
43 #include "qnetworkcookie_p.h"
44 
45 #include "qnetworkrequest.h"
46 #include "qnetworkreply.h"
47 #include "QtCore/qbytearray.h"
48 #include "QtCore/qdebug.h"
49 #include "QtCore/qlist.h"
50 #include "QtCore/qlocale.h"
51 #include "QtCore/qstring.h"
52 #include "QtCore/qstringlist.h"
53 #include "QtCore/qurl.h"
54 #include "private/qobject_p.h"
55 
57 
110  : d(new QNetworkCookiePrivate)
111 {
112  qRegisterMetaType<QNetworkCookie>();
113  qRegisterMetaType<QList<QNetworkCookie> >();
114 
115  d->name = name;
116  d->value = value;
117 }
118 
124  : d(other.d)
125 {
126 }
127 
132 {
133  // QSharedDataPointer auto deletes
134  d = 0;
135 }
136 
142 {
143  d = other.d;
144  return *this;
145 }
146 
168 {
169  if (d == other.d)
170  return true;
171  return d->name == other.d->name &&
172  d->value == other.d->value &&
173  d->expirationDate.toUTC() == other.d->expirationDate.toUTC() &&
174  d->domain == other.d->domain &&
175  d->path == other.d->path &&
176  d->secure == other.d->secure &&
177  d->comment == other.d->comment;
178 }
179 
190 {
191  return d->secure;
192 }
193 
202 void QNetworkCookie::setSecure(bool enable)
203 {
204  d->secure = enable;
205 }
206 
222 {
223  return d->httpOnly;
224 }
225 
235 {
236  d->httpOnly = enable;
237 }
238 
248 {
249  return !d->expirationDate.isValid();
250 }
251 
264 {
265  return d->expirationDate;
266 }
267 
276 {
277  d->expirationDate = date;
278 }
279 
291 {
292  return d->domain;
293 }
294 
301 {
302  d->domain = domain;
303 }
304 
312 {
313  return d->path;
314 }
315 
322 {
323  d->path = path;
324 }
325 
333 {
334  return d->name;
335 }
336 
344 void QNetworkCookie::setName(const QByteArray &cookieName)
345 {
346  d->name = cookieName;
347 }
348 
359 {
360  return d->value;
361 }
362 
369 {
370  d->value = value;
371 }
372 
373 // ### move this to qnetworkcookie_p.h and share with qnetworkaccesshttpbackend
374 static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position, bool isNameValue)
375 {
376  // format is one of:
377  // (1) token
378  // (2) token = token
379  // (3) token = quoted-string
380  int i;
381  const int length = text.length();
382  position = nextNonWhitespace(text, position);
383 
384  // parse the first part, before the equal sign
385  for (i = position; i < length; ++i) {
386  register char c = text.at(i);
387  if (c == ';' || c == '=')
388  break;
389  }
390 
391  QByteArray first = text.mid(position, i - position).trimmed();
392  position = i;
393 
394  if (first.isEmpty())
395  return qMakePair(QByteArray(), QByteArray());
396  if (i == length || text.at(i) != '=')
397  // no equal sign, we found format (1)
398  return qMakePair(first, QByteArray());
399 
400  QByteArray second;
401  second.reserve(32); // arbitrary but works for most cases
402 
403  i = nextNonWhitespace(text, position + 1);
404  if (i < length && text.at(i) == '"') {
405  // a quote, we found format (3), where:
406  // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
407  // qdtext = <any TEXT except <">>
408  // quoted-pair = "\" CHAR
409 
410  // If it is NAME=VALUE, retain the value as is
411  // refer to http://bugreports.qt-project.org/browse/QTBUG-17746
412  if (isNameValue)
413  second += '"';
414  ++i;
415  while (i < length) {
416  register char c = text.at(i);
417  if (c == '"') {
418  // end of quoted text
419  if (isNameValue)
420  second += '"';
421  break;
422  } else if (c == '\\') {
423  if (isNameValue)
424  second += '\\';
425  ++i;
426  if (i >= length)
427  // broken line
428  return qMakePair(QByteArray(), QByteArray());
429  c = text.at(i);
430  }
431 
432  second += c;
433  ++i;
434  }
435 
436  for ( ; i < length; ++i) {
437  register char c = text.at(i);
438  if (c == ';')
439  break;
440  }
441  position = i;
442  } else {
443  // no quote, we found format (2)
444  position = i;
445  for ( ; i < length; ++i) {
446  register char c = text.at(i);
447  // for name value pairs, we want to parse until reaching the next ';'
448  // and not break when reaching a space char
449  if (c == ';' || ((isNameValue && (c == '\n' || c == '\r')) || (!isNameValue && isLWS(c))))
450  break;
451  }
452 
453  second = text.mid(position, i - position).trimmed();
454  position = i;
455  }
456 
457  if (second.isNull())
458  second.resize(0); // turns into empty-but-not-null
459  return qMakePair(first, second);
460 }
461 
497 {
498  QByteArray result;
499  if (d->name.isEmpty())
500  return result; // not a valid cookie
501 
502  result = d->name;
503  result += '=';
504  if ((d->value.contains(';') ||
505  d->value.contains('"')) &&
506  (!d->value.startsWith('"') &&
507  !d->value.endsWith('"'))) {
508  result += '"';
509 
510  QByteArray value = d->value;
511  value.replace('"', "\\\"");
512  result += value;
513 
514  result += '"';
515  } else {
516  result += d->value;
517  }
518 
519  if (form == Full) {
520  // same as above, but encoding everything back
521  if (isSecure())
522  result += "; secure";
523  if (isHttpOnly())
524  result += "; HttpOnly";
525  if (!isSessionCookie()) {
526  result += "; expires=";
527  result += QLocale::c().toString(d->expirationDate.toUTC(),
528  QLatin1String("ddd, dd-MMM-yyyy hh:mm:ss 'GMT")).toLatin1();
529  }
530  if (!d->domain.isEmpty()) {
531  result += "; domain=";
532  QString domainNoDot = d->domain;
533  if (domainNoDot.startsWith(QLatin1Char('.'))) {
534  result += '.';
535  domainNoDot = domainNoDot.mid(1);
536  }
537  result += QUrl::toAce(domainNoDot);
538  }
539  if (!d->path.isEmpty()) {
540  result += "; path=";
541  result += QUrl::toPercentEncoding(d->path, "/");
542  }
543  }
544  return result;
545 }
546 
547 static const char zones[] =
548  "pst\0" // -8
549  "pdt\0"
550  "mst\0" // -7
551  "mdt\0"
552  "cst\0" // -6
553  "cdt\0"
554  "est\0" // -5
555  "edt\0"
556  "ast\0" // -4
557  "nst\0" // -3
558  "gmt\0" // 0
559  "utc\0"
560  "bst\0"
561  "met\0" // 1
562  "eet\0" // 2
563  "jst\0" // 9
564  "\0";
565 static int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 };
566 
567 static const char months[] =
568  "jan\0"
569  "feb\0"
570  "mar\0"
571  "apr\0"
572  "may\0"
573  "jun\0"
574  "jul\0"
575  "aug\0"
576  "sep\0"
577  "oct\0"
578  "nov\0"
579  "dec\0"
580  "\0";
581 
582 static inline bool isNumber(char s)
583 { return s >= '0' && s <= '9'; }
584 
585 static inline bool isTerminator(char c)
586 { return c == '\n' || c == '\r'; }
587 
588 static inline bool isValueSeparator(char c)
589 { return isTerminator(c) || c == ';'; }
590 
591 static inline bool isWhitespace(char c)
592 { return c == ' ' || c == '\t'; }
593 
594 static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, int size)
595 {
596  if (dateString[at] < 'a' || dateString[at] > 'z')
597  return false;
598  if (val == -1 && dateString.length() >= at + 3) {
599  int j = 0;
600  int i = 0;
601  while (i <= size) {
602  const char *str = array + i;
603  if (str[0] == dateString[at]
604  && str[1] == dateString[at + 1]
605  && str[2] == dateString[at + 2]) {
606  val = j;
607  return true;
608  }
609  i += strlen(str) + 1;
610  ++j;
611  }
612  }
613  return false;
614 }
615 
616 //#define PARSEDATESTRINGDEBUG
617 
618 #define ADAY 1
619 #define AMONTH 2
620 #define AYEAR 4
621 
622 /*
623  Parse all the date formats that Firefox can.
624 
625  The official format is:
626  expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT
627 
628  But browsers have been supporting a very wide range of date
629  strings. To work on many sites we need to support more then
630  just the official date format.
631 
632  For reference see Firefox's PR_ParseTimeStringToExplodedTime in
633  prtime.c. The Firefox date parser is coded in a very complex way
634  and is slightly over ~700 lines long. While this implementation
635  will be slightly slower for the non standard dates it is smaller,
636  more readable, and maintainable.
637 
638  Or in their own words:
639  "} // else what the hell is this."
640 */
641 static QDateTime parseDateString(const QByteArray &dateString)
642 {
643  QTime time;
644  // placeholders for values when we are not sure it is a year, month or day
645  int unknown[3] = {-1, -1, -1};
646  int month = -1;
647  int day = -1;
648  int year = -1;
649  int zoneOffset = -1;
650 
651  // hour:minute:second.ms pm
652  QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)"));
653 
654  int at = 0;
655  while (at < dateString.length()) {
656 #ifdef PARSEDATESTRINGDEBUG
657  qDebug() << dateString.mid(at);
658 #endif
659  bool isNum = isNumber(dateString[at]);
660 
661  // Month
662  if (!isNum
663  && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) {
664  ++month;
665 #ifdef PARSEDATESTRINGDEBUG
666  qDebug() << "Month:" << month;
667 #endif
668  at += 3;
669  continue;
670  }
671  // Zone
672  if (!isNum
673  && zoneOffset == -1
674  && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) {
675  int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1;
676  zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60;
677 #ifdef PARSEDATESTRINGDEBUG
678  qDebug() << "Zone:" << month;
679 #endif
680  at += 3;
681  continue;
682  }
683  // Zone offset
684  if (!isNum
685  && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt
686  && (dateString[at] == '+' || dateString[at] == '-')
687  && (at == 0
688  || isWhitespace(dateString[at - 1])
689  || dateString[at - 1] == ','
690  || (at >= 3
691  && (dateString[at - 3] == 'g')
692  && (dateString[at - 2] == 'm')
693  && (dateString[at - 1] == 't')))) {
694 
695  int end = 1;
696  while (end < 5 && dateString.length() > at+end
697  && dateString[at + end] >= '0' && dateString[at + end] <= '9')
698  ++end;
699  int minutes = 0;
700  int hours = 0;
701  switch (end - 1) {
702  case 4:
703  minutes = atoi(dateString.mid(at + 3, 2).constData());
704  // fall through
705  case 2:
706  hours = atoi(dateString.mid(at + 1, 2).constData());
707  break;
708  case 1:
709  hours = atoi(dateString.mid(at + 1, 1).constData());
710  break;
711  default:
712  at += end;
713  continue;
714  }
715  if (end != 1) {
716  int sign = dateString[at] == '-' ? -1 : 1;
717  zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60));
718 #ifdef PARSEDATESTRINGDEBUG
719  qDebug() << "Zone offset:" << zoneOffset << hours << minutes;
720 #endif
721  at += end;
722  continue;
723  }
724  }
725 
726  // Time
727  if (isNum && time.isNull()
728  && dateString.length() >= at + 3
729  && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) {
730  // While the date can be found all over the string the format
731  // for the time is set and a nice regexp can be used.
732  int pos = timeRx.indexIn(QLatin1String(dateString), at);
733  if (pos != -1) {
734  QStringList list = timeRx.capturedTexts();
735  int h = atoi(list.at(1).toLatin1().constData());
736  int m = atoi(list.at(2).toLatin1().constData());
737  int s = atoi(list.at(4).toLatin1().constData());
738  int ms = atoi(list.at(6).toLatin1().constData());
739  if (h < 12 && !list.at(9).isEmpty())
740  if (list.at(9) == QLatin1String("pm"))
741  h += 12;
742  time = QTime(h, m, s, ms);
743 #ifdef PARSEDATESTRINGDEBUG
744  qDebug() << "Time:" << list << timeRx.matchedLength();
745 #endif
746  at += timeRx.matchedLength();
747  continue;
748  }
749  }
750 
751  // 4 digit Year
752  if (isNum
753  && year == -1
754  && dateString.length() > at + 3) {
755  if (isNumber(dateString[at + 1])
756  && isNumber(dateString[at + 2])
757  && isNumber(dateString[at + 3])) {
758  year = atoi(dateString.mid(at, 4).constData());
759  at += 4;
760 #ifdef PARSEDATESTRINGDEBUG
761  qDebug() << "Year:" << year;
762 #endif
763  continue;
764  }
765  }
766 
767  // a one or two digit number
768  // Could be month, day or year
769  if (isNum) {
770  int length = 1;
771  if (dateString.length() > at + 1
772  && isNumber(dateString[at + 1]))
773  ++length;
774  int x = atoi(dateString.mid(at, length).constData());
775  if (year == -1 && (x > 31 || x == 0)) {
776  year = x;
777  } else {
778  if (unknown[0] == -1) unknown[0] = x;
779  else if (unknown[1] == -1) unknown[1] = x;
780  else if (unknown[2] == -1) unknown[2] = x;
781  }
782  at += length;
783 #ifdef PARSEDATESTRINGDEBUG
784  qDebug() << "Saving" << x;
785 #endif
786  continue;
787  }
788 
789  // Unknown character, typically a weekday such as 'Mon'
790  ++at;
791  }
792 
793  // Once we are done parsing the string take the digits in unknown
794  // and determine which is the unknown year/month/day
795 
796  int couldBe[3] = { 0, 0, 0 };
797  int unknownCount = 3;
798  for (int i = 0; i < unknownCount; ++i) {
799  if (unknown[i] == -1) {
800  couldBe[i] = ADAY | AYEAR | AMONTH;
801  unknownCount = i;
802  continue;
803  }
804 
805  if (unknown[i] >= 1)
806  couldBe[i] = ADAY;
807 
808  if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12)
809  couldBe[i] |= AMONTH;
810 
811  if (year == -1)
812  couldBe[i] |= AYEAR;
813  }
814 
815  // For any possible day make sure one of the values that could be a month
816  // can contain that day.
817  // For any possible month make sure one of the values that can be a
818  // day that month can have.
819  // Example: 31 11 06
820  // 31 can't be a day because 11 and 6 don't have 31 days
821  for (int i = 0; i < unknownCount; ++i) {
822  int currentValue = unknown[i];
823  bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29;
824  bool findMatchingDay = couldBe[i] & AMONTH;
825  if (!findMatchingMonth || !findMatchingDay)
826  continue;
827  for (int j = 0; j < 3; ++j) {
828  if (j == i)
829  continue;
830  for (int k = 0; k < 2; ++k) {
831  if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH)))
832  continue;
833  else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY)))
834  continue;
835  int m = currentValue;
836  int d = unknown[j];
837  if (k == 0)
838  qSwap(m, d);
839  if (m == -1) m = month;
840  bool found = true;
841  switch(m) {
842  case 2:
843  // When we get 29 and the year ends up having only 28
844  // See date.isValid below
845  // Example: 29 23 Feb
846  if (d <= 29)
847  found = false;
848  break;
849  case 4: case 6: case 9: case 11:
850  if (d <= 30)
851  found = false;
852  break;
853  default:
854  if (d > 0 && d <= 31)
855  found = false;
856  }
857  if (k == 0) findMatchingMonth = found;
858  else if (k == 1) findMatchingDay = found;
859  }
860  }
861  if (findMatchingMonth)
862  couldBe[i] &= ~ADAY;
863  if (findMatchingDay)
864  couldBe[i] &= ~AMONTH;
865  }
866 
867  // First set the year/month/day that have been deduced
868  // and reduce the set as we go along to deduce more
869  for (int i = 0; i < unknownCount; ++i) {
870  int unset = 0;
871  for (int j = 0; j < 3; ++j) {
872  if (couldBe[j] == ADAY && day == -1) {
873  day = unknown[j];
874  unset |= ADAY;
875  } else if (couldBe[j] == AMONTH && month == -1) {
876  month = unknown[j];
877  unset |= AMONTH;
878  } else if (couldBe[j] == AYEAR && year == -1) {
879  year = unknown[j];
880  unset |= AYEAR;
881  } else {
882  // common case
883  break;
884  }
885  couldBe[j] &= ~unset;
886  }
887  }
888 
889  // Now fallback to a standardized order to fill in the rest with
890  for (int i = 0; i < unknownCount; ++i) {
891  if (couldBe[i] & AMONTH && month == -1) month = unknown[i];
892  else if (couldBe[i] & ADAY && day == -1) day = unknown[i];
893  else if (couldBe[i] & AYEAR && year == -1) year = unknown[i];
894  }
895 #ifdef PARSEDATESTRINGDEBUG
896  qDebug() << "Final set" << year << month << day;
897 #endif
898 
899  if (year == -1 || month == -1 || day == -1) {
900 #ifdef PARSEDATESTRINGDEBUG
901  qDebug() << "Parser failure" << year << month << day;
902 #endif
903  return QDateTime();
904  }
905 
906  // Y2k behavior
907  int y2k = 0;
908  if (year < 70)
909  y2k = 2000;
910  else if (year < 100)
911  y2k = 1900;
912 
913  QDate date(year + y2k, month, day);
914 
915  // When we were given a bad cookie that when parsed
916  // set the day to 29 and the year to one that doesn't
917  // have the 29th of Feb rather then adding the extra
918  // complicated checking earlier just swap here.
919  // Example: 29 23 Feb
920  if (!date.isValid())
921  date = QDate(day + y2k, month, year);
922 
923  QDateTime dateTime(date, time, Qt::UTC);
924 
925  if (zoneOffset != -1) {
926  dateTime = dateTime.addSecs(zoneOffset);
927  }
928  if (!dateTime.isValid())
929  return QDateTime();
930  return dateTime;
931 }
932 
945 {
946  // cookieString can be a number of set-cookie header strings joined together
947  // by \n, parse each line separately.
948  QList<QNetworkCookie> cookies;
949  QList<QByteArray> list = cookieString.split('\n');
950  for (int a = 0; a < list.size(); a++)
952  return cookies;
953 }
954 
956 {
957  // According to http://wp.netscape.com/newsref/std/cookie_spec.html,<
958  // the Set-Cookie response header is of the format:
959  //
960  // Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
961  //
962  // where only the NAME=VALUE part is mandatory
963  //
964  // We do not support RFC 2965 Set-Cookie2-style cookies
965 
966  QList<QNetworkCookie> result;
968 
969  int position = 0;
970  const int length = cookieString.length();
971  while (position < length) {
972  QNetworkCookie cookie;
973 
974  // The first part is always the "NAME=VALUE" part
975  QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true);
976  if (field.first.isEmpty() || field.second.isNull())
977  // parsing error
978  break;
979  cookie.setName(field.first);
980  cookie.setValue(field.second);
981 
982  position = nextNonWhitespace(cookieString, position);
983  while (position < length) {
984  switch (cookieString.at(position++)) {
985  case ';':
986  // new field in the cookie
987  field = nextField(cookieString, position, false);
988  field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive
989 
990  if (field.first == "expires") {
991  position -= field.second.length();
992  int end;
993  for (end = position; end < length; ++end)
994  if (isValueSeparator(cookieString.at(end)))
995  break;
996 
997  QByteArray dateString = cookieString.mid(position, end - position).trimmed();
998  position = end;
999  QDateTime dt = parseDateString(dateString.toLower());
1000  if (!dt.isValid()) {
1001  return result;
1002  }
1003  cookie.setExpirationDate(dt);
1004  } else if (field.first == "domain") {
1005  QByteArray rawDomain = field.second;
1006  QString maybeLeadingDot;
1007  if (rawDomain.startsWith('.')) {
1008  maybeLeadingDot = QLatin1Char('.');
1009  rawDomain = rawDomain.mid(1);
1010  }
1011 
1012  QString normalizedDomain = QUrl::fromAce(QUrl::toAce(QString::fromUtf8(rawDomain)));
1013  if (normalizedDomain.isEmpty() && !rawDomain.isEmpty())
1014  return result;
1015  cookie.setDomain(maybeLeadingDot + normalizedDomain);
1016  } else if (field.first == "max-age") {
1017  bool ok = false;
1018  int secs = field.second.toInt(&ok);
1019  if (!ok)
1020  return result;
1021  cookie.setExpirationDate(now.addSecs(secs));
1022  } else if (field.first == "path") {
1024  cookie.setPath(path);
1025  } else if (field.first == "secure") {
1026  cookie.setSecure(true);
1027  } else if (field.first == "httponly") {
1028  cookie.setHttpOnly(true);
1029  } else if (field.first == "comment") {
1030  //cookie.setComment(QString::fromUtf8(field.second));
1031  } else if (field.first == "version") {
1032  if (field.second != "1") {
1033  // oops, we don't know how to handle this cookie
1034  return result;
1035  }
1036  } else {
1037  // got an unknown field in the cookie
1038  // what do we do?
1039  }
1040 
1041  position = nextNonWhitespace(cookieString, position);
1042  }
1043  }
1044 
1045  if (!cookie.name().isEmpty())
1046  result += cookie;
1047  }
1048 
1049  return result;
1050 }
1051 
1052 #ifndef QT_NO_DEBUG_STREAM
1054 {
1055  s.nospace() << "QNetworkCookie(" << cookie.toRawForm(QNetworkCookie::Full) << ')';
1056  return s.space();
1057 }
1058 #endif
1059 
QDateTime addSecs(int secs) const
Returns a QDateTime object containing a datetime s seconds later than the datetime of this object (or...
Definition: qdatetime.cpp:2869
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
double d
Definition: qnumeric_p.h:62
static QString fromPercentEncoding(const QByteArray &)
Returns a decoded copy of input.
Definition: qurl.cpp:5992
static QList< QNetworkCookie > parseSetCookieHeaderLine(const QByteArray &cookieString)
void setExpirationDate(const QDateTime &date)
Sets the expiration date of this cookie to date.
QString domain() const
Returns the domain this cookie is associated with.
static QByteArray toPercentEncoding(const QString &, const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray())
Returns an encoded copy of input.
Definition: qurl.cpp:6009
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QDebug operator<<(QDebug s, const QNetworkCookie &cookie)
bool isSessionCookie() const
Returns true if this cookie is a session cookie.
QSharedDataPointer< QNetworkCookiePrivate > d
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition: qdatetime.cpp:340
bool isNull() const
Returns true if the time is null (i.
Definition: qdatetime.h:158
QDebug & nospace()
Clears the stream&#39;s internal flag that records whether the last character was a space and returns a r...
Definition: qdebug.h:92
#define at(className, varName)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void setHttpOnly(bool enable)
Sets this cookie&#39;s "HttpOnly" flag to enable.
T1 first
Definition: qpair.h:65
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
T2 second
Definition: qpair.h:66
int matchedLength() const
Returns the length of the last matched string, or -1 if there was no match.
Definition: qregexp.cpp:4193
static bool isWhitespace(char c)
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QByteArray toLower() const
Returns a lowercase copy of the byte array.
bool isValid() const
Returns true if both the date and the time are valid; otherwise returns false.
Definition: qdatetime.cpp:2346
void setDomain(const QString &domain)
Sets the domain associated with this cookie to be domain.
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static bool isNumber(char s)
long ASN1_INTEGER_get ASN1_INTEGER * a
void setPath(const QString &path)
Sets the path associated with this cookie to be path.
RawForm
This enum is used with the toRawForm() function to declare which form of a cookie shall be returned...
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
~QNetworkCookie()
Destroys this QNetworkCookie object.
static int nextNonWhitespace(const QByteArray &text, int from)
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition: qlocale.cpp:1295
#define ADAY
static int sign(int x)
static QList< QNetworkCookie > parseCookies(const QByteArray &cookieString)
Parses the cookie string cookieString as received from a server response in the "Set-Cookie:" header...
bool operator==(const QNetworkCookie &other) const
Returns true if this cookie is equal to other.
Q_CORE_EXPORT void qDebug(const char *,...)
QByteArray toRawForm(RawForm form=Full) const
Returns the raw form of this QNetworkCookie.
static QByteArray toAce(const QString &)
Returns the ASCII Compatible Encoding of the given domain name domain.
Definition: qurl.cpp:6158
static bool isValueSeparator(char c)
The QTime class provides clock time functions.
Definition: qdatetime.h:148
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setName(const QByteArray &cookieName)
Sets the name of this cookie to be cookieName.
int indexIn(const QString &str, int offset=0, CaretMode caretMode=CaretAtZero) const
Attempts to find a match in str from position offset (0 by default).
Definition: qregexp.cpp:4136
QString path() const
Returns the path associated with this cookie.
#define AYEAR
static QDateTime parseDateString(const QByteArray &dateString)
QStringList capturedTexts() const
Returns a list of the captured text strings.
Definition: qregexp.cpp:4267
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QNetworkCookie(const QByteArray &name=QByteArray(), const QByteArray &value=QByteArray())
Create a new QNetworkCookie object, initializing the cookie name to name and its value to value...
void setSecure(bool enable)
Sets the secure flag of this cookie to enable.
const char * name
QDateTime expirationDate() const
Returns the expiration date for this cookie.
QByteArray trimmed() const
Returns a byte array that has whitespace removed from the start and the end.
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
#define AMONTH
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
bool isNull() const
Returns true if this byte array is null; otherwise returns false.
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
static bool isLWS(register char c)
static QString fromAce(const QByteArray &)
Returns the Unicode form of the given domain name domain, which is encoded in the ASCII Compatible En...
Definition: qurl.cpp:6134
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
QDateTime toUTC() const
Returns a datetime containing the date and time information in this datetime, but specified using the...
Definition: qdatetime.h:251
int length() const
Same as size().
Definition: qbytearray.h:356
The QNetworkCookie class holds one network cookie.
static QPair< QByteArray, QByteArray > nextField(const QByteArray &text, int &position, bool isNameValue)
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays...
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition: qlocale.h:773
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
bool isHttpOnly() const
Returns true if the "HttpOnly" flag is enabled for this cookie.
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
Q_OUTOFLINE_TEMPLATE QPair< T1, T2 > qMakePair(const T1 &x, const T2 &y)
Definition: qpair.h:102
void resize(int size)
Sets the size of the byte array to size bytes.
QByteArray name() const
Returns the name of this cookie.
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static QDateTime currentDateTime()
Returns the current datetime, as reported by the system clock, in the local time zone.
Definition: qdatetime.cpp:3138
bool isSecure() const
Returns true if the "secure" option was specified in the cookie string, false otherwise.
static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, int size)
QNetworkCookie & operator=(const QNetworkCookie &other)
Copies the contents of the QNetworkCookie object other to this object.
static int zoneOffsets[]
QByteArray & replace(int index, int len, const char *s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static const char months[]
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QByteArray value() const
Returns this cookies value, as specified in the cookie string.
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
void reserve(int size)
Attempts to allocate memory for at least size bytes.
Definition: qbytearray.h:449
static const KeyPair *const end
QDebug & space()
Writes a space character to the debug stream and returns a reference to the stream.
Definition: qdebug.h:91
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void setValue(const QByteArray &value)
Sets the value of this cookie to be value.
#define text
Definition: qobjectdefs.h:80
static const char zones[]
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
QBool contains(char c) const
Returns true if the byte array contains the character ch; otherwise returns false.
Definition: qbytearray.h:525
static bool isTerminator(char c)