void CookieJar::setCookies(const QVariantList &cookies) { QList<QNetworkCookie> newCookies; for (int i = 0; i < cookies.size(); ++i) { QNetworkCookie nc; QVariantMap cookie = cookies.at(i).toMap(); // // The field of domain and cookie name/value MUST be set, otherwise skip it. // if (cookie["domain"].isNull() || cookie["domain"].toString().isEmpty() || cookie["name"].isNull() || cookie["name"].toString().isEmpty() || cookie["value"].isNull() ) { continue; } else { nc.setDomain(cookie["domain"].toString()); nc.setName(cookie["name"].toByteArray()); nc.setValue(cookie["value"].toByteArray()); } if (cookie["path"].isNull() || cookie["path"].toString().isEmpty()) { nc.setPath("/"); } else { nc.setPath(cookie["path"].toString()); } if (cookie["httponly"].isNull()) { nc.setHttpOnly(false); } else { nc.setHttpOnly(cookie["httponly"].toBool()); } if (cookie["secure"].isNull()) { nc.setSecure(false); } else { nc.setSecure(cookie["secure"].toBool()); } if (!cookie["expires"].isNull()) { QString datetime = cookie["expires"].toString().replace(" GMT", ""); QDateTime expires = QDateTime::fromString(datetime, "ddd, dd MMM yyyy hh:mm:ss"); if (expires.isValid()) { nc.setExpirationDate(expires); } } newCookies.append(nc); } this->setAllCookies(newCookies); }
void NResponse::setSessionCookie(const QString & sessionId, bool secured) { QNetworkCookie sessionCookie; sessionCookie.setHttpOnly (true); sessionCookie.setName ("nawis_sessionId"); sessionCookie.setPath ("/"); sessionCookie.setSecure(secured); sessionCookie.setValue(sessionId.toAscii()); m_httpHeader.setValue("Set-Cookie", sessionCookie.toRawForm(QNetworkCookie::Full)); }
QNetworkCookie CookieDialog::cookie() { QNetworkCookie cookie; cookie.setDomain(m_domainLineEdit->text()); cookie.setName(m_nameLineEdit->text().toLatin1()); cookie.setValue(m_valueLineEdit->text().toLatin1()); cookie.setExpirationDate(QDateTime(m_dateEdit->date())); cookie.setPath(m_pathLineEdit->text()); cookie.setSecure(m_isSecureComboBox->currentText() == tr("yes")); cookie.setHttpOnly(m_isHttpOnlyComboBox->currentText() == tr("yes")); return cookie; }
void HttpWriterTest::writeSetCookieValue_data () { QTest::addColumn< QNetworkCookie > ("input"); QTest::addColumn< QString > ("result"); QNetworkCookie normal ("foo", "bar"); QNetworkCookie encoded ("foo", "b a;r"); QNetworkCookie maxAge ("foo", "bar"); QNetworkCookie maxAgePast ("foo", "bar"); QNetworkCookie domain ("foo", "bar"); QNetworkCookie path ("foo", "bar"); QNetworkCookie secure ("foo", "bar"); QNetworkCookie httpOnly ("foo", "bar"); QNetworkCookie complex ("foo", "b a;r"); maxAge.setExpirationDate (QDateTime::currentDateTime ().addSecs (123)); maxAgePast.setExpirationDate (QDateTime::currentDateTime ().addSecs (-100)); domain.setDomain ("nuriaproject.org"); path.setPath ("/foo/bar"); secure.setSecure (true); httpOnly.setHttpOnly (true); complex.setExpirationDate (QDateTime::currentDateTime ().addSecs (123)); complex.setDomain ("nuriaproject.org"); complex.setPath ("/foo/bar"); complex.setSecure (true); complex.setHttpOnly (true); QTest::newRow ("normal") << normal << "foo=bar"; QTest::newRow ("encoded") << encoded << "foo=b%20a%3Br"; QTest::newRow ("maxAge") << maxAge << "foo=bar; Max-Age=123"; QTest::newRow ("maxAge in past") << maxAgePast << "foo=bar; Max-Age=0"; QTest::newRow ("domain") << domain << "foo=bar; Domain=nuriaproject.org"; QTest::newRow ("path") << path << "foo=bar; Path=/foo/bar"; QTest::newRow ("secure") << secure << "foo=bar; Secure"; QTest::newRow ("httpOnly") << httpOnly << "foo=bar; HttpOnly"; QTest::newRow ("complex") << complex << "foo=b%20a%3Br; Domain=nuriaproject.org; " "Path=/foo/bar; Max-Age=123; Secure; HttpOnly"; }
PostMonster::HttpResponse Common::deserializeResponse(const QJsonObject &jsonResponse) { PostMonster::HttpResponse response; response.mimeType = jsonResponse["mimeType"].toString().toLatin1(); response.status = jsonResponse["status"].toInt(); QByteArray body; body.append(jsonResponse["body"].toString()); response.body.append(QByteArray::fromBase64(body)); foreach (const QJsonValue &jsonHeader, jsonResponse["headers"].toArray()) { QNetworkReply::RawHeaderPair header; header.first.append(jsonHeader.toObject()["name"].toString()); header.second.append(jsonHeader.toObject()["value"].toString()); response.headers << header; } foreach (const QJsonValue &value, jsonResponse["cookies"].toArray()) { const QJsonObject &jsonCookie = value.toObject(); QNetworkCookie cookie; if (jsonCookie.contains("expire")) cookie.setExpirationDate(QDateTime::fromString(jsonCookie["expire"].toString(), Qt::ISODate)); if (jsonCookie["httpOnly"].toBool()) cookie.setHttpOnly(true); if (jsonCookie["secure"].toBool()) cookie.setSecure(true); if (jsonCookie.contains("path")) cookie.setPath(jsonCookie["path"].toString()); cookie.setName(jsonCookie["name"].toString().toLatin1()); cookie.setValue(jsonCookie["value"].toString().toLatin1()); response.cookies << cookie; } return response; }
PostMonster::HttpRequest Common::deserializeRequest(const QJsonObject &jsonRequest) { PostMonster::HttpRequest request; request.url = jsonRequest["url"].toString(); request.method = jsonRequest["method"].toString().toLatin1(); request.encoding = jsonRequest["encoding"].toString().toLatin1(); request.body = QByteArray::fromBase64(jsonRequest["body"].toString().toLatin1()); foreach (const QJsonValue &value, jsonRequest["headers"].toArray()) { const QJsonObject &jsonHeader = value.toObject(); QNetworkReply::RawHeaderPair header; header.first = jsonHeader["name"].toString().toLatin1(); header.second = jsonHeader["value"].toString().toLatin1(); request.headers << header; } foreach (const QJsonValue &value, jsonRequest["cookies"].toArray()) { const QJsonObject &jsonCookie = value.toObject(); QNetworkCookie cookie; if (jsonCookie.contains("expire")) cookie.setExpirationDate(QDateTime::fromString(jsonCookie["expire"].toString(), Qt::ISODate)); if (jsonCookie["httpOnly"].toBool()) cookie.setHttpOnly(true); if (jsonCookie["secure"].toBool()) cookie.setSecure(true); if (jsonCookie.contains("path")) cookie.setPath(jsonCookie["path"].toString()); cookie.setName(jsonCookie["name"].toString().toLatin1()); cookie.setValue(jsonCookie["value"].toString().toLatin1()); request.cookies << cookie; } return request; }
void HttpWriterTest::writeSetCookies () { HttpWriter writer; // Data QByteArray expected = "Set-Cookie: expires=b%20a%3Br; Max-Age=0; Secure; HttpOnly\r\n" "Set-Cookie: session=foo\r\n"; QNetworkCookie expires ("expires", "b a;r"); expires.setExpirationDate (QDateTime::fromMSecsSinceEpoch (123)); expires.setSecure (true); expires.setHttpOnly (true); HttpClient::Cookies cookies { { "session", QNetworkCookie ("session", "foo") }, { "expires", expires } }; // QByteArray result = writer.writeSetCookies (cookies); QCOMPARE(result, expected); }
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl& url) const { QString requestUrl = url.toString(); QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url); const QList<QString>& registeredDomains = WebKit::instance()->identifierCookieDomainList(); foreach(QString d, registeredDomains) { if(requestUrl.startsWith(d)) { QNetworkCookie identifierCookie = WebKit::instance()->identifierCookie(); identifierCookie.setDomain(d); identifierCookie.setSecure(d.startsWith("https") ? true : false); cookies.append(identifierCookie); break; } } return cookies; }
bool CookieJar::setCookie(const QString& cookieName, const QString& value, int maxAge, const QString& path, const QString& domain, bool isSecure) { QNetworkCookie cookie; QUrl url = QString(isSecure ? "https://" : "http://" + QString(domain.startsWith('.') ? "www" : "") + domain + (path.isEmpty() ? "/" : path)); #ifdef U_CJ_DEBUG qDebug() << Q_FUNC_INFO << allCookies().count() << url; #endif cookie.setName(cookieName.toUtf8()); cookie.setValue(value.toUtf8()); cookie.setDomain(domain); cookie.setPath(path); cookie.setSecure(isSecure); if(maxAge != 0) { QDateTime expireDate = QDateTime::currentDateTimeUtc().addSecs(maxAge); cookie.setExpirationDate(expireDate); } #ifdef U_CJ_DEBUG qDebug() << Q_FUNC_INFO << cookie; #endif return setCookiesFromUrl(QList<QNetworkCookie>() << cookie, url); }
QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByteArray &cookieString) { // According to http://wp.netscape.com/newsref/std/cookie_spec.html,< // the Set-Cookie response header is of the format: // // Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure // // where only the NAME=VALUE part is mandatory // // We do not support RFC 2965 Set-Cookie2-style cookies QList<QNetworkCookie> result; QDateTime now = QDateTime::currentDateTime().toUTC(); int position = 0; const int length = cookieString.length(); while (position < length) { QNetworkCookie cookie; // The first part is always the "NAME=VALUE" part QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true); if (field.first.isEmpty() || field.second.isNull()) // parsing error break; cookie.setName(field.first); cookie.setValue(field.second); position = nextNonWhitespace(cookieString, position); bool endOfCookie = false; while (!endOfCookie && position < length) { switch (cookieString.at(position++)) { case ',': // end of the cookie endOfCookie = true; break; case ';': // new field in the cookie field = nextField(cookieString, position, false); field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive if (field.first == "expires") { position -= field.second.length(); int end; for (end = position; end < length; ++end) if (isValueSeparator(cookieString.at(end))) break; QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; QDateTime dt = parseDateString(dateString.toLower()); if (!dt.isValid()) { return result; } cookie.setExpirationDate(dt); } else if (field.first == "domain") { QByteArray rawDomain = field.second; QString maybeLeadingDot; if (rawDomain.startsWith('.')) { maybeLeadingDot = QLatin1Char('.'); rawDomain = rawDomain.mid(1); } QString normalizedDomain = QUrl::fromAce(QUrl::toAce(QString::fromUtf8(rawDomain))); if (normalizedDomain.isEmpty() && !rawDomain.isEmpty()) return result; cookie.setDomain(maybeLeadingDot + normalizedDomain); } else if (field.first == "max-age") { bool ok = false; int secs = field.second.toInt(&ok); if (!ok) return result; cookie.setExpirationDate(now.addSecs(secs)); } else if (field.first == "path") { QString path = QUrl::fromPercentEncoding(field.second); cookie.setPath(path); } else if (field.first == "secure") { cookie.setSecure(true); } else if (field.first == "httponly") { cookie.setHttpOnly(true); } else if (field.first == "comment") { //cookie.setComment(QString::fromUtf8(field.second)); } else if (field.first == "version") { if (field.second != "1") { // oops, we don't know how to handle this cookie return result; } } else { // got an unknown field in the cookie // what do we do? } position = nextNonWhitespace(cookieString, position); } } if (!cookie.name().isEmpty()) result += cookie; } return result; }
QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByteArray &cookieString) { // According to http://wp.netscape.com/newsref/std/cookie_spec.html,< // the Set-Cookie response header is of the format: // // Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure // // where only the NAME=VALUE part is mandatory // // We do not support RFC 2965 Set-Cookie2-style cookies QList<QNetworkCookie> result; const QDateTime now = QDateTime::currentDateTimeUtc(); int position = 0; const int length = cookieString.length(); while (position < length) { QNetworkCookie cookie; // The first part is always the "NAME=VALUE" part QPair<QByteArray,QByteArray> field = nextField(cookieString, position, true); if (field.first.isEmpty()) // parsing error break; cookie.setName(field.first); cookie.setValue(field.second); position = nextNonWhitespace(cookieString, position); while (position < length) { switch (cookieString.at(position++)) { case ';': // new field in the cookie field = nextField(cookieString, position, false); field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive if (field.first == "expires") { position -= field.second.length(); int end; for (end = position; end < length; ++end) if (isValueSeparator(cookieString.at(end))) break; QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; QDateTime dt = parseDateString(dateString.toLower()); if (dt.isValid()) cookie.setExpirationDate(dt); //if unparsed, ignore the attribute but not the whole cookie (RFC6265 section 5.2.1) } else if (field.first == "domain") { QByteArray rawDomain = field.second; //empty domain should be ignored (RFC6265 section 5.2.3) if (!rawDomain.isEmpty()) { QString maybeLeadingDot; if (rawDomain.startsWith('.')) { maybeLeadingDot = QLatin1Char('.'); rawDomain = rawDomain.mid(1); } //IDN domains are required by RFC6265, accepting utf8 as well doesn't break any test cases. QString normalizedDomain = QUrl::fromAce(QUrl::toAce(QString::fromUtf8(rawDomain))); if (!normalizedDomain.isEmpty()) { cookie.setDomain(maybeLeadingDot + normalizedDomain); } else { //Normalization fails for malformed domains, e.g. "..example.org", reject the cookie now //rather than accepting it but never sending it due to domain match failure, as the //strict reading of RFC6265 would indicate. return result; } } } else if (field.first == "max-age") { bool ok = false; int secs = field.second.toInt(&ok); if (ok) { if (secs <= 0) { //earliest representable time (RFC6265 section 5.2.2) cookie.setExpirationDate(QDateTime::fromSecsSinceEpoch(0)); } else { cookie.setExpirationDate(now.addSecs(secs)); } } //if unparsed, ignore the attribute but not the whole cookie (RFC6265 section 5.2.2) } else if (field.first == "path") { if (field.second.startsWith('/')) { // ### we should treat cookie paths as an octet sequence internally // However RFC6265 says we should assume UTF-8 for presentation as a string cookie.setPath(QString::fromUtf8(field.second)); } else { // if the path doesn't start with '/' then set the default path (RFC6265 section 5.2.4) // and also IETF test case path0030 which has valid and empty path in the same cookie cookie.setPath(QString()); } } else if (field.first == "secure") { cookie.setSecure(true); } else if (field.first == "httponly") { cookie.setHttpOnly(true); } else { // ignore unknown fields in the cookie (RFC6265 section 5.2, rule 6) } position = nextNonWhitespace(cookieString, position); } } if (!cookie.name().isEmpty()) result += cookie; } return result; }