NetworkCookie: set the default path according to RFC 6265
This commit is contained in:
parent
2e7b5f9e18
commit
05f42aaba4
@ -24,13 +24,13 @@ public:
|
||||
BNetworkCookie(BMessage* archive);
|
||||
BNetworkCookie();
|
||||
virtual ~BNetworkCookie();
|
||||
|
||||
|
||||
// Parse a "SetCookie" string, or "name=value"
|
||||
|
||||
BNetworkCookie& ParseCookieStringFromUrl(const BString& string,
|
||||
|
||||
BNetworkCookie& ParseCookieStringFromUrl(const BString& string,
|
||||
const BUrl& url);
|
||||
BNetworkCookie& ParseCookieString(const BString& cookieString);
|
||||
|
||||
|
||||
// Modify the cookie fields
|
||||
BNetworkCookie& SetComment(const BString& comment);
|
||||
BNetworkCookie& SetCommentUrl(const BString& commentUrl);
|
||||
@ -44,7 +44,7 @@ public:
|
||||
BNetworkCookie& SetVersion(int8 version);
|
||||
BNetworkCookie& SetName(const BString& name);
|
||||
BNetworkCookie& SetValue(const BString& value);
|
||||
|
||||
|
||||
// Access the cookie fields
|
||||
const BString& CommentUrl() const;
|
||||
const BString& Comment() const;
|
||||
@ -64,7 +64,7 @@ public:
|
||||
bool IsValidForUrl(const BUrl& url) const;
|
||||
bool IsValidForDomain(const BString& domain) const;
|
||||
bool IsValidForPath(const BString& path) const;
|
||||
|
||||
|
||||
// Test if cookie fields are defined
|
||||
bool HasCommentUrl() const;
|
||||
bool HasComment() const;
|
||||
@ -76,16 +76,16 @@ public:
|
||||
bool HasVersion() const;
|
||||
bool HasName() const;
|
||||
bool HasValue() const;
|
||||
|
||||
|
||||
// Test if cookie could be deleted
|
||||
bool ShouldDeleteAtExit() const;
|
||||
bool ShouldDeleteNow() const;
|
||||
|
||||
|
||||
// BArchivable members
|
||||
virtual status_t Archive(BMessage* into,
|
||||
bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
|
||||
// Overloaded operators
|
||||
BNetworkCookie& operator=(const BNetworkCookie& other);
|
||||
BNetworkCookie& operator=(const char* string);
|
||||
@ -94,15 +94,16 @@ public:
|
||||
private:
|
||||
void _Reset();
|
||||
void _ExtractNameValuePair(
|
||||
const BString& cookieString, int16* index,
|
||||
const BString& cookieString, int16* index,
|
||||
bool parseField = false);
|
||||
|
||||
void _SetDefaultPathForUrl(const BUrl& url);
|
||||
|
||||
private:
|
||||
mutable BString fRawCookie;
|
||||
mutable bool fRawCookieValid;
|
||||
mutable BString fRawFullCookie;
|
||||
mutable bool fRawFullCookieValid;
|
||||
|
||||
|
||||
BString fComment;
|
||||
BString fCommentUrl;
|
||||
bool fDiscard;
|
||||
@ -115,7 +116,7 @@ private:
|
||||
int8 fVersion;
|
||||
BString fName;
|
||||
BString fValue;
|
||||
|
||||
|
||||
bool fHasDiscard;
|
||||
bool fHasExpirationDate;
|
||||
bool fSessionCookie;
|
||||
|
@ -32,7 +32,7 @@ static const char* kArchivedCookieValue = "be:cookie.value";
|
||||
|
||||
|
||||
BNetworkCookie::BNetworkCookie(const char* name, const char* value)
|
||||
:
|
||||
:
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
fVersion(0),
|
||||
@ -45,7 +45,7 @@ BNetworkCookie::BNetworkCookie(const char* name, const char* value)
|
||||
|
||||
|
||||
BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
|
||||
:
|
||||
:
|
||||
BArchivable(),
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
@ -58,7 +58,7 @@ BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
|
||||
|
||||
|
||||
BNetworkCookie::BNetworkCookie(const BString& cookieString)
|
||||
:
|
||||
:
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
fVersion(0),
|
||||
@ -71,7 +71,7 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString)
|
||||
|
||||
BNetworkCookie::BNetworkCookie(const BString& cookieString,
|
||||
const BUrl& url)
|
||||
:
|
||||
:
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
fVersion(0),
|
||||
@ -83,29 +83,29 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString,
|
||||
|
||||
|
||||
BNetworkCookie::BNetworkCookie(BMessage* archive)
|
||||
:
|
||||
:
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
fVersion(0),
|
||||
fSessionCookie(true)
|
||||
{
|
||||
_Reset();
|
||||
|
||||
|
||||
archive->FindString(kArchivedCookieName, &fName);
|
||||
archive->FindString(kArchivedCookieValue, &fValue);
|
||||
|
||||
|
||||
archive->FindString(kArchivedCookieComment, &fComment);
|
||||
archive->FindString(kArchivedCookieCommentUrl, &fCommentUrl);
|
||||
archive->FindString(kArchivedCookieDomain, &fDomain);
|
||||
archive->FindString(kArchivedCookiePath, &fPath);
|
||||
archive->FindBool(kArchivedCookieSecure, &fSecure);
|
||||
|
||||
|
||||
if (archive->FindBool(kArchivedCookieDiscard, &fDiscard) == B_OK)
|
||||
fHasDiscard = true;
|
||||
|
||||
|
||||
if (archive->FindInt8(kArchivedCookieVersion, &fVersion) == B_OK)
|
||||
fHasVersion = true;
|
||||
|
||||
|
||||
int32 expiration;
|
||||
if (archive->FindInt32(kArchivedCookieExpirationDate, &expiration)
|
||||
== B_OK) {
|
||||
@ -115,7 +115,7 @@ BNetworkCookie::BNetworkCookie(BMessage* archive)
|
||||
|
||||
|
||||
BNetworkCookie::BNetworkCookie()
|
||||
:
|
||||
:
|
||||
fDiscard(false),
|
||||
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
|
||||
fPath("/"),
|
||||
@ -140,19 +140,19 @@ BNetworkCookie::ParseCookieStringFromUrl(const BString& string,
|
||||
{
|
||||
BString cookieString(string);
|
||||
int16 index = 0;
|
||||
|
||||
|
||||
_Reset();
|
||||
|
||||
|
||||
// Default values from url
|
||||
SetDomain(url.Host());
|
||||
SetPath(url.Path());
|
||||
|
||||
_SetDefaultPathForUrl(url);
|
||||
|
||||
_ExtractNameValuePair(cookieString, &index);
|
||||
|
||||
while (index < cookieString.Length())
|
||||
_ExtractNameValuePair(cookieString, &index, true);
|
||||
|
||||
return *this;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -200,11 +200,11 @@ BNetworkCookie&
|
||||
BNetworkCookie::SetDomain(const BString& domain)
|
||||
{
|
||||
fDomain = domain;
|
||||
|
||||
|
||||
// We always use pre-dotted domains for tail matching
|
||||
if (fDomain.ByteAt(0) != '.')
|
||||
fDomain.Prepend(".");
|
||||
|
||||
|
||||
fRawFullCookieValid = false;
|
||||
return *this;
|
||||
}
|
||||
@ -244,7 +244,7 @@ BNetworkCookie::SetExpirationDate(BDateTime& expireDate)
|
||||
fRawFullCookieValid = false;
|
||||
fHasExpirationDate = true;
|
||||
}
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -346,12 +346,12 @@ const BString&
|
||||
BNetworkCookie::ExpirationString() const
|
||||
{
|
||||
BHttpTime date(ExpirationDate());
|
||||
|
||||
|
||||
if (!fExpirationStringValid) {
|
||||
fExpirationString = date.ToString(BPrivate::B_HTTP_TIME_FORMAT_COOKIE);
|
||||
fExpirationStringValid = true;
|
||||
}
|
||||
|
||||
|
||||
return fExpirationString;
|
||||
}
|
||||
|
||||
@ -397,9 +397,9 @@ BNetworkCookie::RawCookie(bool full) const
|
||||
if (full && !fRawFullCookieValid) {
|
||||
fRawFullCookie.Truncate(0);
|
||||
fRawFullCookieValid = true;
|
||||
|
||||
|
||||
fRawFullCookie << fName << "=" << fValue;
|
||||
|
||||
|
||||
if (HasCommentUrl())
|
||||
fRawFullCookie << "; Comment-Url=" << fCommentUrl;
|
||||
if (HasComment())
|
||||
@ -417,11 +417,11 @@ BNetworkCookie::RawCookie(bool full) const
|
||||
fRawFullCookie << "; Secure=" << (fSecure?"true":"false");
|
||||
if (HasVersion())
|
||||
fRawFullCookie << ", Version=" << fVersion;
|
||||
|
||||
|
||||
} else if (!full && !fRawCookieValid) {
|
||||
fRawCookie.Truncate(0);
|
||||
fRawCookieValid = true;
|
||||
|
||||
|
||||
fRawCookie << fName << "=" << fValue;
|
||||
}
|
||||
|
||||
@ -451,7 +451,7 @@ BNetworkCookie::IsValidForUrl(const BUrl& url) const
|
||||
{
|
||||
BString urlHost = url.Host();
|
||||
BString urlPath = url.Path();
|
||||
|
||||
|
||||
return IsValidForDomain(urlHost) && IsValidForPath(urlPath);
|
||||
}
|
||||
|
||||
@ -461,7 +461,7 @@ BNetworkCookie::IsValidForDomain(const BString& domain) const
|
||||
{
|
||||
if (fDomain.Length() > domain.Length())
|
||||
return false;
|
||||
|
||||
|
||||
return domain.FindLast(fDomain) == (domain.Length() - fDomain.Length());
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ BNetworkCookie::IsValidForPath(const BString& path) const
|
||||
{
|
||||
if (fPath.Length() > path.Length())
|
||||
return false;
|
||||
|
||||
|
||||
return path.FindFirst(fPath) == 0;
|
||||
}
|
||||
|
||||
@ -559,7 +559,7 @@ BNetworkCookie::ShouldDeleteNow() const
|
||||
{
|
||||
if (!IsSessionCookie() && HasExpirationDate())
|
||||
return (BDateTime::CurrentDateTime(B_GMT_TIME) > fExpiration);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -574,60 +574,60 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
|
||||
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
|
||||
error = into->AddString(kArchivedCookieName, fName);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
|
||||
error = into->AddString(kArchivedCookieValue, fValue);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
|
||||
|
||||
|
||||
// We add optional fields only if they're defined
|
||||
if (HasComment()) {
|
||||
error = into->AddString(kArchivedCookieComment, fComment);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (HasCommentUrl()) {
|
||||
error = into->AddString(kArchivedCookieCommentUrl, fCommentUrl);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (HasDiscard()) {
|
||||
error = into->AddBool(kArchivedCookieDiscard, fDiscard);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (HasDomain()) {
|
||||
error = into->AddString(kArchivedCookieDomain, fDomain);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (fHasExpirationDate) {
|
||||
error = into->AddInt32(kArchivedCookieExpirationDate,
|
||||
error = into->AddInt32(kArchivedCookieExpirationDate,
|
||||
fExpiration.Time_t());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (HasPath()) {
|
||||
error = into->AddString(kArchivedCookiePath, fPath);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (Secure()) {
|
||||
error = into->AddBool(kArchivedCookieSecure, fSecure);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (HasVersion()) {
|
||||
error = into->AddInt8(kArchivedCookieVersion, fVersion);
|
||||
if (error != B_OK)
|
||||
@ -652,7 +652,7 @@ BNetworkCookie::Instantiate(BMessage* archive)
|
||||
// #pragma mark Overloaded operators
|
||||
|
||||
|
||||
BNetworkCookie&
|
||||
BNetworkCookie&
|
||||
BNetworkCookie::operator=(const BNetworkCookie& other)
|
||||
{
|
||||
// Should we prefer to discard the cache ?
|
||||
@ -662,7 +662,7 @@ BNetworkCookie::operator=(const BNetworkCookie& other)
|
||||
fRawFullCookieValid = other.fRawFullCookieValid;
|
||||
fExpirationString = other.fExpirationString;
|
||||
fExpirationStringValid = other.fExpirationStringValid;
|
||||
|
||||
|
||||
fComment = other.fComment;
|
||||
fCommentUrl = other.fCommentUrl;
|
||||
fDiscard = other.fDiscard;
|
||||
@ -673,12 +673,12 @@ BNetworkCookie::operator=(const BNetworkCookie& other)
|
||||
fVersion = other.fVersion;
|
||||
fName = other.fName;
|
||||
fValue = other.fValue;
|
||||
|
||||
|
||||
fHasDiscard = other.fHasDiscard;
|
||||
fHasExpirationDate = other.fHasExpirationDate;
|
||||
fSessionCookie = other.fSessionCookie;
|
||||
fHasVersion = other.fHasVersion;
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -723,7 +723,7 @@ BNetworkCookie::_Reset()
|
||||
fHasExpirationDate = false;
|
||||
fSessionCookie = true;
|
||||
fHasVersion = false;
|
||||
|
||||
|
||||
fRawCookieValid = false;
|
||||
fRawFullCookieValid = false;
|
||||
fExpirationStringValid = false;
|
||||
@ -731,32 +731,32 @@ BNetworkCookie::_Reset()
|
||||
|
||||
|
||||
void
|
||||
BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
|
||||
BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
|
||||
int16* index, bool parseField)
|
||||
{
|
||||
// Skip whitespaces
|
||||
while (cookieString.ByteAt(*index) == ' '
|
||||
&& *index < cookieString.Length())
|
||||
(*index)++;
|
||||
|
||||
|
||||
if (*index >= cookieString.Length())
|
||||
return;
|
||||
|
||||
|
||||
|
||||
// Look for a name=value pair
|
||||
int16 firstSemiColon = cookieString.FindFirst(";", *index);
|
||||
int16 firstEqual = cookieString.FindFirst("=", *index);
|
||||
|
||||
|
||||
BString name;
|
||||
BString value;
|
||||
|
||||
|
||||
if (firstSemiColon == -1) {
|
||||
if (firstEqual != -1) {
|
||||
cookieString.CopyInto(name, *index, firstEqual - *index);
|
||||
cookieString.CopyInto(value, firstEqual + 1,
|
||||
cookieString.Length() - firstEqual - 1);
|
||||
} else
|
||||
cookieString.CopyInto(value, *index,
|
||||
cookieString.CopyInto(value, *index,
|
||||
cookieString.Length() - *index);
|
||||
|
||||
*index = cookieString.Length() + 1;
|
||||
@ -799,7 +799,7 @@ BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
|
||||
BHttpTime date(value);
|
||||
SetExpirationDate(date.Parse());
|
||||
// Cookie valid domain
|
||||
} else if (name == "domain")
|
||||
} else if (name == "domain")
|
||||
SetDomain(value);
|
||||
// Cookie valid path
|
||||
else if (name == "path")
|
||||
@ -811,3 +811,23 @@ BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
|
||||
else if (name == "version")
|
||||
SetVersion(atoi(value.String()));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BNetworkCookie::_SetDefaultPathForUrl(const BUrl& url)
|
||||
{
|
||||
const BString& path = url.Path();
|
||||
if (path.IsEmpty() || path.ByteAt(0) != '/') {
|
||||
SetPath("/");
|
||||
return;
|
||||
}
|
||||
|
||||
int32 index = path.FindLast('/');
|
||||
if (index == 0) {
|
||||
SetPath("/");
|
||||
return;
|
||||
}
|
||||
|
||||
BString newPath = path;
|
||||
SetPath(newPath.Truncate(index));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user