poco/Net/src/HTTPCookie.cpp

393 lines
6.8 KiB
C++
Raw Normal View History

2012-04-29 18:52:25 +00:00
//
// HTTPCookie.cpp
//
// Library: Net
// Package: HTTP
// Module: HTTPCookie
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
2012-04-29 18:52:25 +00:00
//
#include "Poco/Net/HTTPCookie.h"
#include "Poco/Net/NameValueCollection.h"
#include "Poco/Timestamp.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeParser.h"
#include "Poco/NumberFormatter.h"
#include "Poco/NumberParser.h"
#include "Poco/String.h"
#include "Poco/URI.h"
using Poco::Timestamp;
using Poco::DateTime;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
using Poco::DateTimeParser;
using Poco::NumberFormatter;
using Poco::NumberParser;
using Poco::icompare;
namespace Poco {
namespace Net {
HTTPCookie::HTTPCookie():
_version(0),
_secure(false),
_maxAge(-1),
_httpOnly(false),
_sameSite(SAME_SITE_NOT_SPECIFIED)
2012-04-29 18:52:25 +00:00
{
}
2012-04-29 18:52:25 +00:00
HTTPCookie::HTTPCookie(const std::string& name):
_version(0),
_name(name),
_secure(false),
_maxAge(-1),
_httpOnly(false),
_sameSite(SAME_SITE_NOT_SPECIFIED)
2012-04-29 18:52:25 +00:00
{
}
HTTPCookie::HTTPCookie(const NameValueCollection& nvc):
_version(0),
_secure(false),
_maxAge(-1),
_httpOnly(false),
_sameSite(SAME_SITE_NOT_SPECIFIED)
2012-04-29 18:52:25 +00:00
{
for (const auto& p: nvc)
2012-04-29 18:52:25 +00:00
{
const std::string& name = p.first;
const std::string& value = p.second;
2012-04-29 18:52:25 +00:00
if (icompare(name, "comment") == 0)
{
setComment(value);
}
else if (icompare(name, "domain") == 0)
{
setDomain(value);
}
else if (icompare(name, "path") == 0)
{
setPath(value);
}
2014-03-07 18:01:48 +01:00
else if (icompare(name, "priority") == 0)
{
setPriority(value);
}
2012-04-29 18:52:25 +00:00
else if (icompare(name, "max-age") == 0)
{
setMaxAge(NumberParser::parse(value));
}
else if (icompare(name, "secure") == 0)
{
setSecure(true);
}
else if (icompare(name, "expires") == 0)
{
int tzd;
DateTime exp = DateTimeParser::parse(value, tzd);
Timestamp now;
2014-03-06 15:23:02 +00:00
setMaxAge((int) ((exp.timestamp() - now) / Timestamp::resolution()));
2012-04-29 18:52:25 +00:00
}
else if (icompare(name, "SameSite") == 0)
{
if (icompare(value, "None") == 0)
_sameSite = SAME_SITE_NONE;
else if (icompare(value, "Lax") == 0)
_sameSite = SAME_SITE_LAX;
else if (icompare(value, "Strict") == 0)
_sameSite = SAME_SITE_STRICT;
}
2012-04-29 18:52:25 +00:00
else if (icompare(name, "version") == 0)
{
setVersion(NumberParser::parse(value));
}
else if (icompare(name, "HttpOnly") == 0)
{
setHttpOnly(true);
}
else if (_name.empty())
2012-04-29 18:52:25 +00:00
{
setName(name);
setValue(value);
}
}
}
2012-04-29 18:52:25 +00:00
HTTPCookie::HTTPCookie(const std::string& name, const std::string& value):
_version(0),
_name(name),
_value(value),
_secure(false),
_maxAge(-1),
_httpOnly(false),
_sameSite(SAME_SITE_NOT_SPECIFIED)
2012-04-29 18:52:25 +00:00
{
}
2012-04-29 18:52:25 +00:00
HTTPCookie::HTTPCookie(const HTTPCookie& cookie):
_version(cookie._version),
_name(cookie._name),
_value(cookie._value),
_comment(cookie._comment),
_domain(cookie._domain),
_path(cookie._path),
_priority(cookie._priority),
2012-04-29 18:52:25 +00:00
_secure(cookie._secure),
_maxAge(cookie._maxAge),
_httpOnly(cookie._httpOnly),
_sameSite(cookie._sameSite)
2012-04-29 18:52:25 +00:00
{
}
HTTPCookie::~HTTPCookie()
{
}
2012-04-29 18:52:25 +00:00
HTTPCookie& HTTPCookie::operator = (const HTTPCookie& cookie)
{
if (&cookie != this)
{
_version = cookie._version;
_name = cookie._name;
_value = cookie._value;
_comment = cookie._comment;
_domain = cookie._domain;
_path = cookie._path;
_priority = cookie._priority;
2012-04-29 18:52:25 +00:00
_secure = cookie._secure;
_maxAge = cookie._maxAge;
_httpOnly = cookie._httpOnly;
_sameSite = cookie._sameSite;
2012-04-29 18:52:25 +00:00
}
return *this;
}
2012-04-29 18:52:25 +00:00
void HTTPCookie::setVersion(int version)
{
_version = version;
}
2012-04-29 18:52:25 +00:00
void HTTPCookie::setName(const std::string& name)
{
_name = name;
}
2012-04-29 18:52:25 +00:00
void HTTPCookie::setValue(const std::string& value)
{
_value = value;
}
2012-04-29 18:52:25 +00:00
void HTTPCookie::setComment(const std::string& comment)
{
_comment = comment;
}
void HTTPCookie::setDomain(const std::string& domain)
{
_domain = domain;
}
void HTTPCookie::setPath(const std::string& path)
{
_path = path;
}
2014-03-07 18:01:48 +01:00
void HTTPCookie::setPriority(const std::string& priority)
{
_priority = priority;
}
2012-04-29 18:52:25 +00:00
void HTTPCookie::setSecure(bool secure)
{
_secure = secure;
}
void HTTPCookie::setMaxAge(int maxAge)
2012-04-29 18:52:25 +00:00
{
_maxAge = maxAge;
}
void HTTPCookie::setHttpOnly(bool flag)
{
_httpOnly = flag;
}
void HTTPCookie::setSameSite(SameSite value)
{
_sameSite = value;
}
2012-04-29 18:52:25 +00:00
std::string HTTPCookie::toString() const
{
std::string result;
result.reserve(256);
result.append(_name);
result.append("=");
if (_version == 0)
{
// Netscape cookie
result.append(_value);
if (!_domain.empty())
{
result.append("; domain=");
result.append(_domain);
}
if (!_path.empty())
{
result.append("; path=");
result.append(_path);
}
if (!_priority.empty())
{
result.append("; Priority=");
result.append(_priority);
}
if (_maxAge != -1)
2012-04-29 18:52:25 +00:00
{
Timestamp ts;
2014-03-06 15:23:02 +00:00
ts += _maxAge * Timestamp::resolution();
2012-04-29 18:52:25 +00:00
result.append("; expires=");
DateTimeFormatter::append(result, ts, DateTimeFormat::HTTP_FORMAT);
}
switch (_sameSite)
{
case SAME_SITE_NONE:
result.append("; SameSite=None");
break;
case SAME_SITE_LAX:
result.append("; SameSite=Lax");
break;
case SAME_SITE_STRICT:
result.append("; SameSite=Strict");
break;
case SAME_SITE_NOT_SPECIFIED:
break;
}
2012-04-29 18:52:25 +00:00
if (_secure)
{
result.append("; secure");
}
if (_httpOnly)
{
result.append("; HttpOnly");
}
}
else
{
// RFC 2109 cookie
result.append("\"");
result.append(_value);
result.append("\"");
if (!_comment.empty())
{
result.append("; Comment=\"");
result.append(_comment);
result.append("\"");
}
if (!_domain.empty())
{
result.append("; Domain=\"");
result.append(_domain);
result.append("\"");
}
if (!_path.empty())
{
result.append("; Path=\"");
result.append(_path);
result.append("\"");
}
if (!_priority.empty())
{
result.append("; Priority=\"");
result.append(_priority);
result.append("\"");
}
if (_maxAge != -1)
2012-04-29 18:52:25 +00:00
{
result.append("; Max-Age=\"");
NumberFormatter::append(result, _maxAge);
result.append("\"");
}
switch (_sameSite)
{
case SAME_SITE_NONE:
result.append("; SameSite=None");
break;
case SAME_SITE_LAX:
result.append("; SameSite=Lax");
break;
case SAME_SITE_STRICT:
result.append("; SameSite=Strict");
break;
case SAME_SITE_NOT_SPECIFIED:
break;
}
2012-04-29 18:52:25 +00:00
if (_secure)
{
result.append("; secure");
}
if (_httpOnly)
{
result.append("; HttpOnly");
}
result.append("; Version=\"1\"");
}
return result;
}
namespace
{
static const std::string ILLEGAL_CHARS("()[]/|\\',;");
}
std::string HTTPCookie::escape(const std::string& str)
{
std::string result;
Poco::URI::encode(str, ILLEGAL_CHARS, result);
return result;
}
std::string HTTPCookie::unescape(const std::string& str)
{
std::string result;
Poco::URI::decode(str, result);
return result;
}
} } // namespace Poco::Net