Merge branch 'master' into sam460ex

This commit is contained in:
François Revol
2013-02-10 21:55:20 +01:00
17 changed files with 706 additions and 920 deletions
+31 -44
View File
@@ -17,7 +17,6 @@ class BNetworkCookie : public BArchivable {
public: public:
BNetworkCookie(const char* name, BNetworkCookie(const char* name,
const char* value); const char* value);
BNetworkCookie(const BNetworkCookie& other);
BNetworkCookie(const BString& cookieString); BNetworkCookie(const BString& cookieString);
BNetworkCookie(const BString& cookieString, BNetworkCookie(const BString& cookieString,
const BUrl& url); const BUrl& url);
@@ -25,57 +24,47 @@ public:
BNetworkCookie(); BNetworkCookie();
virtual ~BNetworkCookie(); virtual ~BNetworkCookie();
// Parse a "SetCookie" string, or "name=value" // Parse a "SetCookie" string
BNetworkCookie& ParseCookieStringFromUrl(const BString& string, BNetworkCookie& ParseCookieStringFromUrl(const BString& string,
const BUrl& url); const BUrl& url);
BNetworkCookie& ParseCookieString(const BString& cookieString); BNetworkCookie& ParseCookieString(const BString& cookieString);
// Modify the cookie fields // Modify the cookie fields
BNetworkCookie& SetComment(const BString& comment); BNetworkCookie& SetName(const BString& name);
BNetworkCookie& SetCommentUrl(const BString& commentUrl); BNetworkCookie& SetValue(const BString& value);
BNetworkCookie& SetDiscard(bool discard);
BNetworkCookie& SetDomain(const BString& domain); BNetworkCookie& SetDomain(const BString& domain);
BNetworkCookie& SetPath(const BString& path);
BNetworkCookie& SetMaxAge(int32 maxAge); BNetworkCookie& SetMaxAge(int32 maxAge);
BNetworkCookie& SetExpirationDate(time_t expireDate); BNetworkCookie& SetExpirationDate(time_t expireDate);
BNetworkCookie& SetExpirationDate(BDateTime& expireDate); BNetworkCookie& SetExpirationDate(BDateTime& expireDate);
BNetworkCookie& SetPath(const BString& path);
BNetworkCookie& SetSecure(bool secure); BNetworkCookie& SetSecure(bool secure);
BNetworkCookie& SetVersion(int8 version); BNetworkCookie& SetHttpOnly(bool httpOnly);
BNetworkCookie& SetName(const BString& name);
BNetworkCookie& SetValue(const BString& value);
// Access the cookie fields // Access the cookie fields
const BString& CommentUrl() const;
const BString& Comment() const;
bool Discard() const;
const BString& Domain() const;
int32 MaxAge() const;
time_t ExpirationDate() const;
const BString& ExpirationString() const;
const BString& Path() const;
bool Secure() const;
int8 Version() const;
const BString& Name() const; const BString& Name() const;
const BString& Value() const; const BString& Value() const;
const BString& Domain() const;
const BString& Path() const;
time_t ExpirationDate() const;
const BString& ExpirationString() const;
bool Secure() const;
bool HttpOnly() const;
const BString& RawCookie(bool full) const; const BString& RawCookie(bool full) const;
bool IsHostOnly() const;
bool IsSessionCookie() const; bool IsSessionCookie() const;
bool IsValid(bool strict = false) const; bool IsValid() const;
bool IsValidForUrl(const BUrl& url) const; bool IsValidForUrl(const BUrl& url) const;
bool IsValidForDomain(const BString& domain) const; bool IsValidForDomain(const BString& domain) const;
bool IsValidForPath(const BString& path) const; bool IsValidForPath(const BString& path) const;
// Test if cookie fields are defined // Test if cookie fields are defined
bool HasCommentUrl() const;
bool HasComment() const;
bool HasDiscard() const;
bool HasDomain() const;
bool HasMaxAge() const;
bool HasExpirationDate() const;
bool HasPath() const;
bool HasVersion() const;
bool HasName() const; bool HasName() const;
bool HasValue() const; bool HasValue() const;
bool HasDomain() const;
bool HasPath() const;
bool HasExpirationDate() const;
// Test if cookie could be deleted // Test if cookie could be deleted
bool ShouldDeleteAtExit() const; bool ShouldDeleteAtExit() const;
@@ -87,39 +76,37 @@ public:
static BArchivable* Instantiate(BMessage* archive); static BArchivable* Instantiate(BMessage* archive);
// Overloaded operators // Overloaded operators
BNetworkCookie& operator=(const BNetworkCookie& other);
BNetworkCookie& operator=(const char* string); BNetworkCookie& operator=(const char* string);
bool operator==(const BNetworkCookie& other); bool operator==(const BNetworkCookie& other);
bool operator!=(const BNetworkCookie& other); bool operator!=(const BNetworkCookie& other);
private: private:
void _Reset(); void _Reset();
void _ExtractNameValuePair( int32 _ExtractNameValuePair(const BString& string,
const BString& cookieString, int16* index, BString& name, BString& value,
bool parseField = false); int32 index);
int32 _ExtractAttributeValuePair(
const BString& string, BString& name,
BString& value, int32 index);
BString _DefaultPathForUrl(const BUrl& url);
private: private:
mutable BString fRawCookie; mutable BString fRawCookie;
mutable bool fRawCookieValid; mutable bool fRawCookieValid;
mutable BString fRawFullCookie; mutable BString fRawFullCookie;
mutable bool fRawFullCookieValid; mutable bool fRawFullCookieValid;
BString fComment;
BString fCommentUrl;
bool fDiscard;
BString fDomain;
BDateTime fExpiration;
mutable BString fExpirationString; mutable BString fExpirationString;
mutable bool fExpirationStringValid; mutable bool fExpirationStringValid;
BString fPath;
bool fSecure;
int8 fVersion;
BString fName; BString fName;
BString fValue; BString fValue;
BString fDomain;
BString fPath;
BDateTime fExpiration;
bool fSecure;
bool fHttpOnly;
bool fHasDiscard; bool fHostOnly;
bool fHasExpirationDate;
bool fSessionCookie; bool fSessionCookie;
bool fHasVersion;
}; };
#endif // _B_NETWORK_COOKIE_H_ #endif // _B_NETWORK_COOKIE_H_
+5 -6
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010 Haiku Inc. All rights reserved. * Copyright 2010-2013 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _B_NETWORK_COOKIE_JAR_H_ #ifndef _B_NETWORK_COOKIE_JAR_H_
@@ -34,10 +34,9 @@ public:
BNetworkCookieJar(BMessage* archive); BNetworkCookieJar(BMessage* archive);
virtual ~BNetworkCookieJar(); virtual ~BNetworkCookieJar();
bool AddCookie(const BNetworkCookie& cookie); status_t AddCookie(const BNetworkCookie& cookie);
bool AddCookie(BNetworkCookie* cookie); status_t AddCookie(BNetworkCookie* cookie);
bool AddCookies( status_t AddCookies(const BNetworkCookieList& cookies);
const BNetworkCookieList& cookies);
uint32 DeleteOutdatedCookies(); uint32 DeleteOutdatedCookies();
uint32 PurgeForExit(); uint32 PurgeForExit();
@@ -117,7 +116,7 @@ private:
UrlIterator(const BNetworkCookieJar* map, UrlIterator(const BNetworkCookieJar* map,
const BUrl& url); const BUrl& url);
bool _SupDomain(); bool _SuperDomain();
void _FindNext(); void _FindNext();
void _FindDomain(); void _FindDomain();
bool _FindPath(); bool _FindPath();
+23 -19
View File
@@ -73,12 +73,12 @@ AppearancePrefView::AppearancePrefView(const char* name,
fTerminalMessenger(messenger) fTerminalMessenger(messenger)
{ {
const char* kColorTable[] = { const char* kColorTable[] = {
B_TRANSLATE("Text"), B_TRANSLATE_MARK("Text"),
B_TRANSLATE("Background"), B_TRANSLATE_MARK("Background"),
B_TRANSLATE("Cursor"), B_TRANSLATE_MARK("Cursor"),
B_TRANSLATE("Text under cursor"), B_TRANSLATE_MARK("Text under cursor"),
B_TRANSLATE("Selected text"), B_TRANSLATE_MARK("Selected text"),
B_TRANSLATE("Selected background"), B_TRANSLATE_MARK("Selected background"),
NULL NULL
}; };
@@ -272,11 +272,14 @@ AppearancePrefView::MessageReceived(BMessage* msg)
case MSG_COLOR_CHANGED: case MSG_COLOR_CHANGED:
{ {
rgb_color oldColor = PrefHandler::Default()->getRGB( const BMessage* itemMessage
fColorField->Menu()->FindMarked()->Label()); = fColorField->Menu()->FindMarked()->Message();
const char* label = NULL;
if (itemMessage->FindString("label", &label) != B_OK)
break;
rgb_color oldColor = PrefHandler::Default()->getRGB(label);
if (oldColor != fColorControl->ValueAsColor()) { if (oldColor != fColorControl->ValueAsColor()) {
PrefHandler::Default()->setRGB( PrefHandler::Default()->setRGB(label,
fColorField->Menu()->FindMarked()->Label(),
fColorControl->ValueAsColor()); fColorControl->ValueAsColor());
modified = true; modified = true;
} }
@@ -300,9 +303,12 @@ AppearancePrefView::MessageReceived(BMessage* msg)
} }
case MSG_COLOR_FIELD_CHANGED: case MSG_COLOR_FIELD_CHANGED:
fColorControl->SetValue(PrefHandler::Default()->getRGB( {
fColorField->Menu()->FindMarked()->Label())); const char* label = NULL;
if (msg->FindString("label", &label) == B_OK)
fColorControl->SetValue(PrefHandler::Default()->getRGB(label));
break; break;
}
case MSG_BLINK_CURSOR_CHANGED: case MSG_BLINK_CURSOR_CHANGED:
if (PrefHandler::Default()->getBool(PREF_BLINK_CURSOR) if (PrefHandler::Default()->getBool(PREF_BLINK_CURSOR)
@@ -514,23 +520,21 @@ AppearancePrefView::_MakeMenu(uint32 msg, const char** items,
{ {
BPopUpMenu* menu = new BPopUpMenu(""); BPopUpMenu* menu = new BPopUpMenu("");
int32 i = 0;
while (*items) { while (*items) {
if (strcmp((*items), "") == 0) if (strcmp((*items), "") == 0)
menu->AddSeparatorItem(); menu->AddSeparatorItem();
else { else {
BMessage* message = new BMessage(msg); BMessage* message = new BMessage(msg);
menu->AddItem(new BMenuItem((*items), message)); message->AddString("label", *items);
BMenuItem* item = new BMenuItem(B_TRANSLATE(*items), message);
menu->AddItem(item);
if (strcmp(*items, defaultItemName) == 0)
item->SetMarked(true);
} }
items++; items++;
i++;
} }
BMenuItem* defaultItem = menu->FindItem(defaultItemName);
if (defaultItem)
defaultItem->SetMarked(true);
return menu; return menu;
} }
+297 -362
View File
@@ -1,68 +1,44 @@
/* /*
* Copyright 2010 Haiku Inc. All rights reserved. * Copyright 2010-2013 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Christophe Huriaux, [email protected] * Christophe Huriaux, [email protected]
* Hamish Morrison, [email protected]
*/ */
#include <cstdlib>
#include <ctime>
#include <new> #include <new>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Debug.h>
#include <HttpTime.h> #include <HttpTime.h>
#include <NetworkCookie.h> #include <NetworkCookie.h>
#include <cstdio>
#define PRINT(x) printf x;
using BPrivate::BHttpTime; using BPrivate::BHttpTime;
static const char* kArchivedCookieComment = "be:cookie.comment"; static const char* kArchivedCookieName = "be:cookie.name";
static const char* kArchivedCookieCommentUrl = "be:cookie.commenturl"; static const char* kArchivedCookieValue = "be:cookie.value";
static const char* kArchivedCookieDiscard = "be:cookie.discard"; static const char* kArchivedCookieDomain = "be:cookie.domain";
static const char* kArchivedCookieDomain = "be:cookie.domain"; static const char* kArchivedCookiePath = "be:cookie.path";
static const char* kArchivedCookieExpirationDate = "be:cookie.expiredate"; static const char* kArchivedCookieExpirationDate = "be:cookie.expirationdate";
static const char* kArchivedCookiePath = "be:cookie.path"; static const char* kArchivedCookieSecure = "be:cookie.secure";
static const char* kArchivedCookieSecure = "be:cookie.secure"; static const char* kArchivedCookieHttpOnly = "be:cookie.httponly";
static const char* kArchivedCookieVersion = "be:cookie.version"; static const char* kArchivedCookieHostOnly = "be:cookie.hostonly";
static const char* kArchivedCookieName = "be:cookie.name";
static const char* kArchivedCookieValue = "be:cookie.value";
BNetworkCookie::BNetworkCookie(const char* name, const char* value) BNetworkCookie::BNetworkCookie(const char* name, const char* value)
:
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fVersion(0),
fName(name),
fValue(value),
fSessionCookie(true)
{ {
_Reset(); _Reset();
} fName = name;
fValue = value;
BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
:
BArchivable(),
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fVersion(0),
fSessionCookie(true)
{
_Reset();
*this = other;
} }
BNetworkCookie::BNetworkCookie(const BString& cookieString) BNetworkCookie::BNetworkCookie(const BString& cookieString)
:
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fVersion(0),
fSessionCookie(true)
{ {
_Reset(); _Reset();
ParseCookieString(cookieString); ParseCookieString(cookieString);
@@ -71,11 +47,6 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString)
BNetworkCookie::BNetworkCookie(const BString& cookieString, BNetworkCookie::BNetworkCookie(const BString& cookieString,
const BUrl& url) const BUrl& url)
:
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fVersion(0),
fSessionCookie(true)
{ {
_Reset(); _Reset();
ParseCookieStringFromUrl(cookieString, url); ParseCookieStringFromUrl(cookieString, url);
@@ -83,28 +54,17 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString,
BNetworkCookie::BNetworkCookie(BMessage* archive) BNetworkCookie::BNetworkCookie(BMessage* archive)
:
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fVersion(0),
fSessionCookie(true)
{ {
_Reset(); _Reset();
archive->FindString(kArchivedCookieName, &fName); archive->FindString(kArchivedCookieName, &fName);
archive->FindString(kArchivedCookieValue, &fValue); archive->FindString(kArchivedCookieValue, &fValue);
archive->FindString(kArchivedCookieComment, &fComment);
archive->FindString(kArchivedCookieCommentUrl, &fCommentUrl);
archive->FindString(kArchivedCookieDomain, &fDomain); archive->FindString(kArchivedCookieDomain, &fDomain);
archive->FindString(kArchivedCookiePath, &fPath); archive->FindString(kArchivedCookiePath, &fPath);
archive->FindBool(kArchivedCookieSecure, &fSecure); archive->FindBool(kArchivedCookieSecure, &fSecure);
archive->FindBool(kArchivedCookieHttpOnly, &fHttpOnly);
if (archive->FindBool(kArchivedCookieDiscard, &fDiscard) == B_OK) archive->FindBool(kArchivedCookieHostOnly, &fHostOnly);
fHasDiscard = true;
if (archive->FindInt8(kArchivedCookieVersion, &fVersion) == B_OK)
fHasVersion = true;
int32 expiration; int32 expiration;
if (archive->FindInt32(kArchivedCookieExpirationDate, &expiration) if (archive->FindInt32(kArchivedCookieExpirationDate, &expiration)
@@ -115,12 +75,6 @@ BNetworkCookie::BNetworkCookie(BMessage* archive)
BNetworkCookie::BNetworkCookie() BNetworkCookie::BNetworkCookie()
:
fDiscard(false),
fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
fPath("/"),
fVersion(0),
fSessionCookie(true)
{ {
_Reset(); _Reset();
} }
@@ -138,19 +92,73 @@ BNetworkCookie&
BNetworkCookie::ParseCookieStringFromUrl(const BString& string, BNetworkCookie::ParseCookieStringFromUrl(const BString& string,
const BUrl& url) const BUrl& url)
{ {
BString cookieString(string);
int16 index = 0;
_Reset(); _Reset();
// Default values from url BString name;
SetDomain(url.Host()); BString value;
SetPath(url.Path()); int32 index = 0;
_ExtractNameValuePair(cookieString, &index); // Parse the name and value of the cookie
index = _ExtractNameValuePair(string, name, value, index);
if (index == -1) {
// The set-cookie-string is not valid
return *this;
}
while (index < cookieString.Length()) SetName(name);
_ExtractNameValuePair(cookieString, &index, true); SetValue(value);
// Parse the remaining cookie attributes.
while (index < string.Length()) {
ASSERT(string[index] == ';');
index++;
index = _ExtractAttributeValuePair(string, name, value, index);
if (name.ICompare("secure") == 0)
SetSecure(true);
else if (name.ICompare("httponly") == 0)
SetHttpOnly(true);
// The following attributes require a value.
if (value.IsEmpty())
continue;
if (name.ICompare("max-age") == 0) {
// Validate the max-age value.
char* end = NULL;
long maxAge = strtol(value.String(), &end, 10);
if (*end == '\0')
SetMaxAge((int)maxAge);
} else if (name.ICompare("expires") == 0) {
BHttpTime date(value);
SetExpirationDate(date.Parse());
} else if (name.ICompare("domain") == 0) {
SetDomain(value);
} else if (name.ICompare("path") == 0) {
SetPath(value);
}
}
// If no domain was specified, we set a host-only domain from the URL.
if (!HasDomain()) {
SetDomain(url.Host());
fHostOnly = true;
} else {
// Otherwise the setting URL must domain-match the domain it set.
if (!IsValidForDomain(url.Host())) {
// Invalidate the cookie.
_Reset();
return *this;
}
// We should also reject cookies with domains that match public
// suffixes.
}
// If no path was specified or the path is invalid, we compute the default
// path from the URL.
if (!HasPath() || Path()[0] != '/')
SetPath(_DefaultPathForUrl(url));
return *this; return *this;
} }
@@ -169,28 +177,30 @@ BNetworkCookie::ParseCookieString(const BString& string)
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetComment(const BString& comment) BNetworkCookie::SetName(const BString& name)
{ {
fComment = comment; fName = name;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fRawCookieValid = false;
return *this; return *this;
} }
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetCommentUrl(const BString& commentUrl) BNetworkCookie::SetValue(const BString& value)
{ {
fCommentUrl = commentUrl; fValue = value;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fRawCookieValid = false;
return *this; return *this;
} }
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetDiscard(bool discard) BNetworkCookie::SetPath(const BString& path)
{ {
fDiscard = discard; // TODO: canonicalize the path
fHasDiscard = true; fPath = path;
fRawFullCookieValid = false; fRawFullCookieValid = false;
return *this; return *this;
} }
@@ -199,11 +209,9 @@ BNetworkCookie::SetDiscard(bool discard)
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetDomain(const BString& domain) BNetworkCookie::SetDomain(const BString& domain)
{ {
// TODO: canonicalize the domain
fDomain = domain; fDomain = domain;
fHostOnly = false;
// We always use pre-dotted domains for tail matching
if (fDomain.ByteAt(0) != '.')
fDomain.Prepend(".");
fRawFullCookieValid = false; fRawFullCookieValid = false;
return *this; return *this;
@@ -236,28 +244,17 @@ BNetworkCookie::SetExpirationDate(BDateTime& expireDate)
fSessionCookie = true; fSessionCookie = true;
fExpirationStringValid = false; fExpirationStringValid = false;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fHasExpirationDate = false;
} else { } else {
fExpiration = expireDate; fExpiration = expireDate;
fSessionCookie = false; fSessionCookie = false;
fExpirationStringValid = false; fExpirationStringValid = false;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fHasExpirationDate = true;
} }
return *this; return *this;
} }
BNetworkCookie&
BNetworkCookie::SetPath(const BString& path)
{
fPath = path;
fRawFullCookieValid = false;
return *this;
}
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetSecure(bool secure) BNetworkCookie::SetSecure(bool secure)
{ {
@@ -268,31 +265,10 @@ BNetworkCookie::SetSecure(bool secure)
BNetworkCookie& BNetworkCookie&
BNetworkCookie::SetVersion(int8 version) BNetworkCookie::SetHttpOnly(bool httpOnly)
{ {
fVersion = version; fHttpOnly = httpOnly;
fHasVersion = true;
fRawCookieValid = false;
return *this;
}
BNetworkCookie&
BNetworkCookie::SetName(const BString& name)
{
fName = name;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fRawCookieValid = false;
return *this;
}
BNetworkCookie&
BNetworkCookie::SetValue(const BString& value)
{
fValue = value;
fRawFullCookieValid = false;
fRawCookieValid = false;
return *this; return *this;
} }
@@ -301,23 +277,16 @@ BNetworkCookie::SetValue(const BString& value)
const BString& const BString&
BNetworkCookie::Comment() const BNetworkCookie::Name() const
{ {
return fComment; return fName;
} }
const BString& const BString&
BNetworkCookie::CommentUrl() const BNetworkCookie::Value() const
{ {
return fCommentUrl; return fValue;
}
bool
BNetworkCookie::Discard() const
{
return fDiscard;
} }
@@ -328,10 +297,10 @@ BNetworkCookie::Domain() const
} }
int32 const BString&
BNetworkCookie::MaxAge() const BNetworkCookie::Path() const
{ {
return fExpiration.Time_t() - BDateTime::CurrentDateTime(B_GMT_TIME).Time_t(); return fPath;
} }
@@ -356,13 +325,6 @@ BNetworkCookie::ExpirationString() const
} }
const BString&
BNetworkCookie::Path() const
{
return fPath;
}
bool bool
BNetworkCookie::Secure() const BNetworkCookie::Secure() const
{ {
@@ -370,24 +332,10 @@ BNetworkCookie::Secure() const
} }
int8 bool
BNetworkCookie::Version() const BNetworkCookie::HttpOnly() const
{ {
return fVersion; return fHttpOnly;
}
const BString&
BNetworkCookie::Name() const
{
return fName;
}
const BString&
BNetworkCookie::Value() const
{
return fValue;
} }
@@ -400,23 +348,16 @@ BNetworkCookie::RawCookie(bool full) const
fRawFullCookie << fName << "=" << fValue; fRawFullCookie << fName << "=" << fValue;
if (HasCommentUrl())
fRawFullCookie << "; Comment-Url=" << fCommentUrl;
if (HasComment())
fRawFullCookie << "; Comment=" << fComment;
if (HasDiscard())
fRawFullCookie << "; Discard=" << (fDiscard?"true":"false");
if (HasDomain()) if (HasDomain())
fRawFullCookie << "; Domain=" << fDomain; fRawFullCookie << "; Domain=" << fDomain;
if (HasExpirationDate()) if (HasExpirationDate())
fRawFullCookie << "; Max-Age=" << MaxAge(); fRawFullCookie << "; Expires=" << ExpirationString();
// fRawFullCookie << "; Expires=" << ExpirationString();
if (HasPath()) if (HasPath())
fRawFullCookie << "; Path=" << fPath; fRawFullCookie << "; Path=" << fPath;
if (Secure() && fSecure) if (Secure())
fRawFullCookie << "; Secure=" << (fSecure?"true":"false"); fRawFullCookie << "; Secure";
if (HasVersion()) if (HttpOnly())
fRawFullCookie << ", Version=" << fVersion; fRawFullCookie << "; HttpOnly";
} else if (!full && !fRawCookieValid) { } else if (!full && !fRawCookieValid) {
fRawCookie.Truncate(0); fRawCookie.Truncate(0);
@@ -425,13 +366,20 @@ BNetworkCookie::RawCookie(bool full) const
fRawCookie << fName << "=" << fValue; fRawCookie << fName << "=" << fValue;
} }
return full?fRawFullCookie:fRawCookie; return full ? fRawFullCookie : fRawCookie;
} }
// #pragma mark Cookie test // #pragma mark Cookie test
bool
BNetworkCookie::IsHostOnly() const
{
return fHostOnly;
}
bool bool
BNetworkCookie::IsSessionCookie() const BNetworkCookie::IsSessionCookie() const
{ {
@@ -440,39 +388,72 @@ BNetworkCookie::IsSessionCookie() const
bool bool
BNetworkCookie::IsValid(bool strict) const BNetworkCookie::IsValid() const
{ {
return HasName() && HasValue() && (!strict || HasVersion()); return HasName() && HasDomain() && HasPath();
} }
bool bool
BNetworkCookie::IsValidForUrl(const BUrl& url) const BNetworkCookie::IsValidForUrl(const BUrl& url) const
{ {
BString urlHost = url.Host(); if (Secure() && url.Protocol() != "https")
BString urlPath = url.Path(); return false;
return IsValidForDomain(urlHost) && IsValidForPath(urlPath); return IsValidForDomain(url.Host()) && IsValidForPath(url.Path());
} }
bool bool
BNetworkCookie::IsValidForDomain(const BString& domain) const BNetworkCookie::IsValidForDomain(const BString& domain) const
{ {
if (fDomain.Length() > domain.Length()) // TODO: canonicalize both domains
const BString& cookieDomain = Domain();
int32 difference = domain.Length() - cookieDomain.Length();
// If the cookie domain is longer than the domain string it cannot
// be valid.
if (difference < 0)
return false; return false;
return domain.FindLast(fDomain) == (domain.Length() - fDomain.Length()); // If the cookie is host-only the domains must match exactly.
if (IsHostOnly())
return domain == cookieDomain;
// Otherwise, the domains must match exactly, or the cookie domain
// must be a suffix with the preceeding character being a dot.
const char* suffix = domain.String() + difference;
if (strcmp(suffix, cookieDomain.String()) == 0) {
if (difference == 0)
return true;
else if (domain[difference - 1] == '.')
return true;
}
return false;
} }
bool bool
BNetworkCookie::IsValidForPath(const BString& path) const BNetworkCookie::IsValidForPath(const BString& path) const
{ {
if (fPath.Length() > path.Length()) const BString& cookiePath = Path();
if (path.Length() < cookiePath.Length())
return false; return false;
return path.FindFirst(fPath) == 0; // The cookie path must be a prefix of the path string
if (path.Compare(cookiePath, cookiePath.Length()) != 0)
return false;
// The paths match if they are identical, or if the last
// character of the prefix is a slash, or if the character
// after the prefix is a slash.
if (path.Length() == cookiePath.Length()
|| cookiePath[cookiePath.Length() - 1] == '/'
|| path[cookiePath.Length()] == '/')
return true;
return false;
} }
@@ -480,23 +461,16 @@ BNetworkCookie::IsValidForPath(const BString& path) const
bool bool
BNetworkCookie::HasCommentUrl() const BNetworkCookie::HasName() const
{ {
return fCommentUrl.Length() > 0; return fName.Length() > 0;
} }
bool bool
BNetworkCookie::HasComment() const BNetworkCookie::HasValue() const
{ {
return fComment.Length() > 0; return fValue.Length() > 0;
}
bool
BNetworkCookie::HasDiscard() const
{
return fHasDiscard;
} }
@@ -514,31 +488,10 @@ BNetworkCookie::HasPath() const
} }
bool
BNetworkCookie::HasVersion() const
{
return fHasVersion;
}
bool
BNetworkCookie::HasName() const
{
return fName.Length() > 0;
}
bool
BNetworkCookie::HasValue() const
{
return fValue.Length() > 0;
}
bool bool
BNetworkCookie::HasExpirationDate() const BNetworkCookie::HasExpirationDate() const
{ {
return fHasExpirationDate; return !IsSessionCookie();
} }
@@ -548,16 +501,14 @@ BNetworkCookie::HasExpirationDate() const
bool bool
BNetworkCookie::ShouldDeleteAtExit() const BNetworkCookie::ShouldDeleteAtExit() const
{ {
return (HasDiscard() && Discard()) return IsSessionCookie() || ShouldDeleteNow();
|| (!IsSessionCookie() && ShouldDeleteNow())
|| IsSessionCookie();
} }
bool bool
BNetworkCookie::ShouldDeleteNow() const BNetworkCookie::ShouldDeleteNow() const
{ {
if (!IsSessionCookie() && HasExpirationDate()) if (HasExpirationDate())
return (BDateTime::CurrentDateTime(B_GMT_TIME) > fExpiration); return (BDateTime::CurrentDateTime(B_GMT_TIME) > fExpiration);
return false; return false;
@@ -585,31 +536,13 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
// We add optional fields only if they're defined // 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()) { if (HasDomain()) {
error = into->AddString(kArchivedCookieDomain, fDomain); error = into->AddString(kArchivedCookieDomain, fDomain);
if (error != B_OK) if (error != B_OK)
return error; return error;
} }
if (fHasExpirationDate) { if (HasExpirationDate()) {
error = into->AddInt32(kArchivedCookieExpirationDate, error = into->AddInt32(kArchivedCookieExpirationDate,
fExpiration.Time_t()); fExpiration.Time_t());
if (error != B_OK) if (error != B_OK)
@@ -628,8 +561,14 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
return error; return error;
} }
if (HasVersion()) { if (HttpOnly()) {
error = into->AddInt8(kArchivedCookieVersion, fVersion); error = into->AddBool(kArchivedCookieHttpOnly, fHttpOnly);
if (error != B_OK)
return error;
}
if (IsHostOnly()) {
error = into->AddBool(kArchivedCookieHostOnly, true);
if (error != B_OK) if (error != B_OK)
return error; return error;
} }
@@ -652,37 +591,6 @@ BNetworkCookie::Instantiate(BMessage* archive)
// #pragma mark Overloaded operators // #pragma mark Overloaded operators
BNetworkCookie&
BNetworkCookie::operator=(const BNetworkCookie& other)
{
// Should we prefer to discard the cache ?
fRawCookie = other.fRawCookie;
fRawCookieValid = other.fRawCookieValid;
fRawFullCookie = other.fRawFullCookie;
fRawFullCookieValid = other.fRawFullCookieValid;
fExpirationString = other.fExpirationString;
fExpirationStringValid = other.fExpirationStringValid;
fComment = other.fComment;
fCommentUrl = other.fCommentUrl;
fDiscard = other.fDiscard;
fDomain = other.fDomain;
fExpiration = other.fExpiration;
fPath = other.fPath;
fSecure = other.fSecure;
fVersion = other.fVersion;
fName = other.fName;
fValue = other.fValue;
fHasDiscard = other.fHasDiscard;
fHasExpirationDate = other.fHasExpirationDate;
fSessionCookie = other.fSessionCookie;
fHasVersion = other.fHasVersion;
return *this;
}
BNetworkCookie& BNetworkCookie&
BNetworkCookie::operator=(const char* string) BNetworkCookie::operator=(const char* string)
{ {
@@ -708,106 +616,133 @@ BNetworkCookie::operator!=(const BNetworkCookie& other)
void void
BNetworkCookie::_Reset() BNetworkCookie::_Reset()
{ {
fComment.Truncate(0);
fCommentUrl.Truncate(0);
fDomain.Truncate(0);
fPath.Truncate(0);
fName.Truncate(0); fName.Truncate(0);
fValue.Truncate(0); fValue.Truncate(0);
fDiscard = false; fDomain.Truncate(0);
fSecure = false; fPath.Truncate(0);
fVersion = 0; fExpiration = BDateTime();
fExpiration = 0; fSecure = false;
fHttpOnly = false;
fHasDiscard = false; fSessionCookie = true;
fHasExpirationDate = false; fHostOnly = true;
fSessionCookie = true;
fHasVersion = false;
fRawCookieValid = false; fRawCookieValid = false;
fRawFullCookieValid = false; fRawFullCookieValid = false;
fExpirationStringValid = false; fExpirationStringValid = false;
} }
void int32
BNetworkCookie::_ExtractNameValuePair(const BString& cookieString, skip_whitespace_forward(const BString& string, int32 index)
int16* index, bool parseField)
{ {
// Skip whitespaces while (index < string.Length() && (string[index] == ' '
while (cookieString.ByteAt(*index) == ' ' || string[index] == '\t'))
&& *index < cookieString.Length()) index++;
(*index)++; return index;
}
if (*index >= cookieString.Length())
return;
int32
skip_whitespace_backward(const BString& string, int32 index)
// Look for a name=value pair {
int16 firstSemiColon = cookieString.FindFirst(";", *index); while (index >= 0 && (string[index] == ' ' || string[index] == '\t'))
int16 firstEqual = cookieString.FindFirst("=", *index); index--;
return index;
BString name; }
BString value;
if (firstSemiColon == -1) { int32
if (firstEqual != -1) { BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
cookieString.CopyInto(name, *index, firstEqual - *index); BString& name, BString& value, int32 index)
cookieString.CopyInto(value, firstEqual + 1, {
cookieString.Length() - firstEqual - 1); // Find our name-value-pair and the delimiter.
} else int32 firstEquals = cookieString.FindFirst('=', index);
cookieString.CopyInto(value, *index, int32 nameValueEnd = cookieString.FindFirst(';', index);
cookieString.Length() - *index);
// If the set-cookie-string lacks a semicolon, the name-value-pair
*index = cookieString.Length() + 1; // is the whole string.
} else { if (nameValueEnd == -1)
if (firstEqual != -1 && firstEqual < firstSemiColon) { nameValueEnd = cookieString.Length();
cookieString.CopyInto(name, *index, firstEqual - *index);
cookieString.CopyInto(value, firstEqual + 1, // If the name-value-pair lacks an equals, the parse should fail.
firstSemiColon - firstEqual - 1); if (firstEquals == -1 || firstEquals > nameValueEnd)
} else return -1;
cookieString.CopyInto(value, *index, firstSemiColon - *index);
int32 first = skip_whitespace_forward(cookieString, index);
*index = firstSemiColon + 1; int32 last = skip_whitespace_backward(cookieString, firstEquals - 1);
}
// If we lack a name, fail to parse.
// Cookie name/value pair if (first > last)
if (!parseField) { return -1;
SetName(name);
SetValue(value); cookieString.CopyInto(name, first, last - first + 1);
return;
} first = skip_whitespace_forward(cookieString, firstEquals + 1);
last = skip_whitespace_backward(cookieString, nameValueEnd - 1);
name.ToLower(); if (first <= last)
name.Trim(); cookieString.CopyInto(value, first, last - first + 1);
value.Trim(); else
value.SetTo("");
// Cookie comment
if (name == "comment") return nameValueEnd;
SetComment(value); }
// Cookie comment URL
else if (name == "comment-url")
SetCommentUrl(value); int32
// Cookie discard flag BNetworkCookie::_ExtractAttributeValuePair(const BString& cookieString,
else if (name == "discard") BString& attribute, BString& value, int32 index)
SetDiscard(value.Length() == 0 || value.ToLower() == "true"); {
// Cookie max-age // Find the end of our cookie-av.
else if (name == "maxage") int32 cookieAVEnd = cookieString.FindFirst(';', index);
SetMaxAge(atoi(value.String()));
// Cookie expiration date // If the unparsed-attributes lacks a semicolon, then the cookie-av is the
else if (name == "expires") { // whole string.
BHttpTime date(value); if (cookieAVEnd == -1)
SetExpirationDate(date.Parse()); cookieAVEnd = cookieString.Length();
// Cookie valid domain
} else if (name == "domain") int32 attributeNameEnd = cookieString.FindFirst('=', index);
SetDomain(value); // If the cookie-av has no equals, the attribute-name is the entire
// Cookie valid path // cookie-av and the attribute-value is empty.
else if (name == "path") if (attributeNameEnd == -1 || attributeNameEnd > cookieAVEnd)
SetPath(value); attributeNameEnd = cookieAVEnd;
// Cookie secure flag
else if (name == "secure") int32 first = skip_whitespace_forward(cookieString, index);
SetSecure(value.Length() == 0 || value.ToLower() == "true"); int32 last = skip_whitespace_backward(cookieString, attributeNameEnd - 1);
// Cookie version
else if (name == "version") if (first <= last)
SetVersion(atoi(value.String())); cookieString.CopyInto(attribute, first, last - first + 1);
else
attribute.SetTo("");
if (attributeNameEnd == cookieAVEnd) {
value.SetTo("");
return cookieAVEnd;
}
first = skip_whitespace_forward(cookieString, attributeNameEnd + 1);
last = skip_whitespace_backward(cookieString, cookieAVEnd - 1);
if (first <= last)
cookieString.CopyInto(value, first, last - first + 1);
else
value.SetTo("");
return cookieAVEnd;
}
BString
BNetworkCookie::_DefaultPathForUrl(const BUrl& url)
{
const BString& path = url.Path();
if (path.IsEmpty() || path.ByteAt(0) != '/')
return "";
int32 index = path.FindLast('/');
if (index == 0)
return "";
BString newPath = path;
newPath.Truncate(index);
return newPath;
} }
+100 -85
View File
@@ -1,35 +1,37 @@
/* /*
* Copyright 2010 Haiku Inc. All rights reserved. * Copyright 2010-2013 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Christophe Huriaux, [email protected] * Christophe Huriaux, [email protected]
* Hamish Morrison, [email protected]
*/ */
#include <new>
#include <Debug.h> #include <Debug.h>
#include <HashMap.h> #include <HashMap.h>
#include <HashString.h> #include <HashString.h>
#include <Message.h> #include <Message.h>
#include <NetworkCookieJar.h> #include <NetworkCookieJar.h>
#include <new>
#include "NetworkCookieJarPrivate.h" #include "NetworkCookieJarPrivate.h"
const char* kArchivedCookieMessageName = "be:cookie";
const char* kArchivedCookieMessageName = "be:cookie";
BNetworkCookieJar::BNetworkCookieJar() BNetworkCookieJar::BNetworkCookieJar()
: :
fCookieHashMap(new PrivateHashMap) fCookieHashMap(new PrivateHashMap())
{ {
} }
BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&) BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&)
: :
BArchivable(), fCookieHashMap(new PrivateHashMap())
fCookieHashMap(new PrivateHashMap)
{ {
// TODO // TODO
} }
@@ -37,7 +39,7 @@ BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&)
BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList) BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList)
: :
fCookieHashMap(new PrivateHashMap) fCookieHashMap(new PrivateHashMap())
{ {
AddCookies(otherList); AddCookies(otherList);
} }
@@ -45,19 +47,22 @@ BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList)
BNetworkCookieJar::BNetworkCookieJar(BMessage* archive) BNetworkCookieJar::BNetworkCookieJar(BMessage* archive)
: :
fCookieHashMap(new PrivateHashMap) fCookieHashMap(new PrivateHashMap())
{ {
BMessage extractedCookie; BMessage extractedCookie;
for (int32 i = 0; for (int32 i = 0; archive->FindMessage(kArchivedCookieMessageName, i,
archive->FindMessage(kArchivedCookieMessageName, i, &extractedCookie) &extractedCookie) == B_OK; i++) {
== B_OK;
i++) {
BNetworkCookie* heapCookie BNetworkCookie* heapCookie
= new(std::nothrow) BNetworkCookie(&extractedCookie); = new(std::nothrow) BNetworkCookie(&extractedCookie);
if (heapCookie == NULL || !AddCookie(heapCookie)) if (heapCookie == NULL)
break; break;
if (!AddCookie(heapCookie)) {
delete heapCookie;
continue;
}
} }
} }
@@ -66,7 +71,7 @@ BNetworkCookieJar::~BNetworkCookieJar()
{ {
BNetworkCookie* cookiePtr; BNetworkCookie* cookiePtr;
for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;)
delete it.Remove(); delete it.Remove();
} }
@@ -74,51 +79,58 @@ BNetworkCookieJar::~BNetworkCookieJar()
// #pragma mark Add cookie to cookie jar // #pragma mark Add cookie to cookie jar
bool status_t
BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie) BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie)
{ {
BNetworkCookie* heapCookie = new(std::nothrow) BNetworkCookie(cookie); BNetworkCookie* heapCookie = new(std::nothrow) BNetworkCookie(cookie);
if (heapCookie == NULL)
return B_NO_MEMORY;
if (!AddCookie(heapCookie)) { status_t result = AddCookie(heapCookie);
if (result != B_OK) {
delete heapCookie; delete heapCookie;
return false; return result;
} }
return true; return B_OK;
} }
bool status_t
BNetworkCookieJar::AddCookie(BNetworkCookie* cookie) BNetworkCookieJar::AddCookie(BNetworkCookie* cookie)
{ {
if (cookie != NULL) { if (cookie == NULL)
HashString key(cookie->Domain()); return B_BAD_VALUE;
if (!fCookieHashMap->fHashMap.ContainsKey(key)) HashString key(cookie->Domain());
fCookieHashMap->fHashMap.Put(key, new BList);
BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key); BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key);
if (list == NULL) {
for (int32 i = 0; i < list->CountItems(); i++) { list = new(std::nothrow) BNetworkCookieList();
BNetworkCookie* c if (list == NULL || fCookieHashMap->fHashMap.Put(key, list) != B_OK)
= reinterpret_cast<BNetworkCookie*>(list->ItemAt(i)); return B_NO_MEMORY;
if (c->Name() == cookie->Name()) {
list->RemoveItem(i);
break;
}
}
// Discard the cookie if it's to be deleted
if (!cookie->ShouldDeleteNow())
list->AddItem(cookie);
} }
return true; for (int32 i = 0; i < list->CountItems(); i++) {
BNetworkCookie* c
= reinterpret_cast<BNetworkCookie*>(list->ItemAt(i));
if (c->Name() == cookie->Name() && c->Path() == cookie->Path()) {
list->RemoveItem(i);
break;
}
}
if (cookie->ShouldDeleteNow())
delete cookie;
else
list->AddItem(cookie);
return B_OK;
} }
bool status_t
BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies) BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies)
{ {
for (int32 i = 0; i < cookies.CountItems(); i++) { for (int32 i = 0; i < cookies.CountItems(); i++) {
@@ -127,11 +139,12 @@ BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies)
// Using AddCookie by reference in order to avoid multiple // Using AddCookie by reference in order to avoid multiple
// cookie jar share the same cookie pointers // cookie jar share the same cookie pointers
if (!AddCookie(*cookiePtr)) status_t result = AddCookie(*cookiePtr);
return false; if (result != B_OK)
return result;
} }
return true; return B_OK;
} }
@@ -144,7 +157,7 @@ BNetworkCookieJar::DeleteOutdatedCookies()
int32 deleteCount = 0; int32 deleteCount = 0;
BNetworkCookie* cookiePtr; BNetworkCookie* cookiePtr;
for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
if (cookiePtr->ShouldDeleteNow()) { if (cookiePtr->ShouldDeleteNow()) {
delete it.Remove(); delete it.Remove();
deleteCount++; deleteCount++;
@@ -161,7 +174,7 @@ BNetworkCookieJar::PurgeForExit()
int32 deleteCount = 0; int32 deleteCount = 0;
BNetworkCookie* cookiePtr; BNetworkCookie* cookiePtr;
for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
if (cookiePtr->ShouldDeleteAtExit()) { if (cookiePtr->ShouldDeleteAtExit()) {
delete it.Remove(); delete it.Remove();
deleteCount++; deleteCount++;
@@ -183,7 +196,7 @@ BNetworkCookieJar::Archive(BMessage* into, bool deep) const
if (error == B_OK) { if (error == B_OK) {
BNetworkCookie* cookiePtr; BNetworkCookie* cookiePtr;
for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
BMessage subArchive; BMessage subArchive;
error = cookiePtr->Archive(&subArchive, deep); error = cookiePtr->Archive(&subArchive, deep);
@@ -357,7 +370,7 @@ BNetworkCookieJar::_DoFlatten() const
fFlattened.Truncate(0); fFlattened.Truncate(0);
BNetworkCookie* cookiePtr; BNetworkCookie* cookiePtr;
for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) { for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
fFlattened << cookiePtr->Domain() << '\t' << "TRUE" << '\t' fFlattened << cookiePtr->Domain() << '\t' << "TRUE" << '\t'
<< cookiePtr->Path() << '\t' << cookiePtr->Path() << '\t'
<< (cookiePtr->Secure()?"TRUE":"FALSE") << '\t' << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t'
@@ -439,7 +452,7 @@ BNetworkCookieJar::Iterator::NextDomain()
return NULL; return NULL;
} }
fList = *(fIterator->fCookieMapIterator.NextValue()); fList = *fIterator->fCookieMapIterator.NextValue();
fIndex = 0; fIndex = 0;
fElement = reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex)); fElement = reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
@@ -463,8 +476,8 @@ BNetworkCookieJar::Iterator::Remove()
else else
fLastList->RemoveItem(fLastList->CountItems() - 1); fLastList->RemoveItem(fLastList->CountItems() - 1);
} else { } else {
fList->RemoveItem(fIndex-1);
fIndex--; fIndex--;
fList->RemoveItem(fIndex);
} }
fLastElement = NULL; fLastElement = NULL;
@@ -476,12 +489,18 @@ BNetworkCookieJar::Iterator&
BNetworkCookieJar::Iterator::operator=(const BNetworkCookieJar::Iterator& other) BNetworkCookieJar::Iterator::operator=(const BNetworkCookieJar::Iterator& other)
{ {
fCookieJar = other.fCookieJar; fCookieJar = other.fCookieJar;
fIterator = other.fIterator;
fLastList = other.fLastList; fLastList = other.fLastList;
fList = other.fList; fList = other.fList;
fElement = other.fElement; fElement = other.fElement;
fLastElement = other.fLastElement; fLastElement = other.fLastElement;
fIndex = other.fIndex; fIndex = other.fIndex;
fIterator = new(std::nothrow) PrivateIterator(*other.fIterator);
if (fIterator == NULL) {
// Make the iterator unusable.
fElement = NULL;
fLastElement = NULL;
}
return *this; return *this;
} }
@@ -529,25 +548,22 @@ BNetworkCookieJar::UrlIterator::UrlIterator(const BNetworkCookieJar* cookieJar,
fLastElement(NULL), fLastElement(NULL),
fIndex(0), fIndex(0),
fLastIndex(0), fLastIndex(0),
fUrl(const_cast<BUrl&>(url)) fUrl(url)
{ {
BString domain(url.Host()); BString domain = url.Host();
if (!domain.Length()) if (!domain.Length())
return; return;
if (domain[0] != '.')
domain.Prepend(".");
// Prepending another dot since _FindNext is going to
// call _SupDomain()
domain.Prepend(".");
fIterator = new(std::nothrow) PrivateIterator( fIterator = new(std::nothrow) PrivateIterator(
fCookieJar->fCookieHashMap->fHashMap.GetIterator()); fCookieJar->fCookieHashMap->fHashMap.GetIterator());
fIterator->fKey.SetTo(domain, domain.Length());
_FindNext(); if (fIterator != NULL) {
// Prepending a dot since _FindNext is going to call _SupDomain()
domain.Prepend(".");
fIterator->fKey.SetTo(domain, domain.Length());
_FindNext();
}
} }
@@ -609,23 +625,28 @@ BNetworkCookieJar::UrlIterator::operator=(
fLastElement = other.fLastElement; fLastElement = other.fLastElement;
fIndex = other.fIndex; fIndex = other.fIndex;
fLastIndex = other.fLastIndex; fLastIndex = other.fLastIndex;
fUrl = other.fUrl;
fIterator = other.fIterator; fIterator = new(std::nothrow) PrivateIterator(*other.fIterator);
if (fIterator == NULL) {
// Make the iterator unusable.
fElement = NULL;
fLastElement = NULL;
}
return *this; return *this;
} }
bool bool
BNetworkCookieJar::UrlIterator::_SupDomain() BNetworkCookieJar::UrlIterator::_SuperDomain()
{ {
BString domain(fIterator->fKey.GetString()); const char* domain = fIterator->fKey.GetString();
int32 nextDot = domain.FindFirst('.', 1); const char* nextDot = strchr(domain, '.');
if (nextDot == -1) if (nextDot == NULL)
return false; return false;
domain.Remove(0, nextDot); fIterator->fKey.SetTo(nextDot + 1);
fIterator->fKey.SetTo(domain.String(), domain.Length());
return true; return true;
} }
@@ -635,19 +656,16 @@ BNetworkCookieJar::UrlIterator::_FindNext()
{ {
fLastIndex = fIndex; fLastIndex = fIndex;
fLastElement = fElement; fLastElement = fElement;
if (_FindPath())
return;
fLastList = fList; fLastList = fList;
do {
if (!_SupDomain()) { while (!_FindPath()) {
if (!_SuperDomain()) {
fElement = NULL; fElement = NULL;
return; return;
} }
_FindDomain(); _FindDomain();
} while (!_FindPath()); }
} }
@@ -667,16 +685,13 @@ bool
BNetworkCookieJar::UrlIterator::_FindPath() BNetworkCookieJar::UrlIterator::_FindPath()
{ {
fIndex++; fIndex++;
if (fList && fIndex < fList->CountItems()) { while (fList && fIndex < fList->CountItems()) {
do { fElement = reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
fElement
= reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
if (fElement->IsValidForPath(fUrl.Path())) if (fElement->IsValidForPath(fUrl.Path()))
return true; return true;
fIndex++; fIndex++;
} while (fList && fIndex < fList->CountItems());
} }
return false; return false;
+1 -1
View File
@@ -140,7 +140,7 @@ const uint32 kUpdateVolumeSpaceBar = 'UpSB';
const uint32 kShowVolumeSpaceBar = 'ShSB'; const uint32 kShowVolumeSpaceBar = 'ShSB';
const uint32 kSpaceBarColorChanged = 'SBcc'; const uint32 kSpaceBarColorChanged = 'SBcc';
const uint32 kMoveFilesToTrashChanged = 'STdm'; const uint32 kDontMoveFilesToTrashChanged = 'STdm';
const uint32 kAskBeforeDeleteFileChanged = 'STad'; const uint32 kAskBeforeDeleteFileChanged = 'STad';
} // namespace BPrivate } // namespace BPrivate
+8 -8
View File
@@ -604,7 +604,7 @@ BContainerWindow::BContainerWindow(LockingList<BWindow>* list,
app->StartWatching(this, kWindowsShowFullPathChanged); app->StartWatching(this, kWindowsShowFullPathChanged);
app->StartWatching(this, kSingleWindowBrowseChanged); app->StartWatching(this, kSingleWindowBrowseChanged);
app->StartWatching(this, kShowNavigatorChanged); app->StartWatching(this, kShowNavigatorChanged);
app->StartWatching(this, kMoveFilesToTrashChanged); app->StartWatching(this, kDontMoveFilesToTrashChanged);
app->Unlock(); app->Unlock();
} }
@@ -625,7 +625,7 @@ BContainerWindow::~BContainerWindow()
app->StopWatching(this, kWindowsShowFullPathChanged); app->StopWatching(this, kWindowsShowFullPathChanged);
app->StopWatching(this, kSingleWindowBrowseChanged); app->StopWatching(this, kSingleWindowBrowseChanged);
app->StopWatching(this, kShowNavigatorChanged); app->StopWatching(this, kShowNavigatorChanged);
app->StopWatching(this, kMoveFilesToTrashChanged); app->StopWatching(this, kDontMoveFilesToTrashChanged);
app->Unlock(); app->Unlock();
} }
@@ -1687,10 +1687,10 @@ BContainerWindow::MessageReceived(BMessage* message)
settings.SingleWindowBrowse()); settings.SingleWindowBrowse());
break; break;
case kMoveFilesToTrashChanged: case kDontMoveFilesToTrashChanged:
{ {
bool dontMoveToTrash bool dontMoveToTrash
= settings.MoveFilesToTrash(); = settings.DontMoveFilesToTrash();
BMenuItem* item BMenuItem* item
= fFileContextMenu->FindItem(kMoveToTrash); = fFileContextMenu->FindItem(kMoveToTrash);
@@ -1934,8 +1934,8 @@ BContainerWindow::AddFileMenu(BMenu* menu)
menu->AddItem(new BMenuItem(B_TRANSLATE("Duplicate"), menu->AddItem(new BMenuItem(B_TRANSLATE("Duplicate"),
new BMessage(kDuplicateSelection), 'D')); new BMessage(kDuplicateSelection), 'D'));
menu->AddItem(new BMenuItem(TrackerSettings().MoveFilesToTrash() menu->AddItem(new BMenuItem(TrackerSettings().DontMoveFilesToTrash()
? B_TRANSLATE("Move to Trash") : B_TRANSLATE("Delete"), ? B_TRANSLATE("Delete") : B_TRANSLATE("Move to Trash"),
new BMessage(kMoveToTrash), 'T')); new BMessage(kMoveToTrash), 'T'));
menu->AddSeparatorItem(); menu->AddSeparatorItem();
@@ -2758,8 +2758,8 @@ BContainerWindow::AddFileContextMenus(BMenu* menu)
} }
if (!IsTrash() && !InTrash()) { if (!IsTrash() && !InTrash()) {
menu->AddItem(new BMenuItem(TrackerSettings().MoveFilesToTrash() menu->AddItem(new BMenuItem(TrackerSettings().DontMoveFilesToTrash()
? B_TRANSLATE("Move to Trash") : B_TRANSLATE("Delete"), ? B_TRANSLATE("Delete") : B_TRANSLATE("Move to Trash"),
new BMessage(kMoveToTrash), 'T')); new BMessage(kMoveToTrash), 'T'));
// add separator for copy to/move to items (navigation items) // add separator for copy to/move to items (navigation items)
+2 -2
View File
@@ -2842,9 +2842,9 @@ status_t
_DeleteTask(BObjectList<entry_ref>* list, bool confirm) _DeleteTask(BObjectList<entry_ref>* list, bool confirm)
{ {
if (confirm) { if (confirm) {
bool MoveToTrash = TrackerSettings().MoveFilesToTrash(); bool dontMoveToTrash = TrackerSettings().DontMoveFilesToTrash();
if (MoveToTrash) { if (!dontMoveToTrash) {
BAlert* alert = new BAlert("", BAlert* alert = new BAlert("",
B_TRANSLATE_NOCOLLECT(kDeleteConfirmationStr), B_TRANSLATE_NOCOLLECT(kDeleteConfirmationStr),
B_TRANSLATE("Cancel"), B_TRANSLATE("Move to Trash"), B_TRANSLATE("Cancel"), B_TRANSLATE("Move to Trash"),
+3 -3
View File
@@ -885,9 +885,9 @@ TFilePanel::AddFileContextMenus(BMenu* menu)
new BMessage(kGetInfo), 'I')); new BMessage(kGetInfo), 'I'));
menu->AddItem(new BMenuItem(B_TRANSLATE("Edit name"), menu->AddItem(new BMenuItem(B_TRANSLATE("Edit name"),
new BMessage(kEditItem), 'E')); new BMessage(kEditItem), 'E'));
menu->AddItem(new BMenuItem(TrackerSettings().MoveFilesToTrash() menu->AddItem(new BMenuItem(TrackerSettings().DontMoveFilesToTrash()
? B_TRANSLATE("Move to Trash") ? B_TRANSLATE("Delete")
: B_TRANSLATE("Delete"), : B_TRANSLATE("Move to Trash"),
new BMessage(kMoveToTrash), 'T')); new BMessage(kMoveToTrash), 'T'));
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Cut"), menu->AddItem(new BMenuItem(B_TRANSLATE("Cut"),
+2 -2
View File
@@ -2323,7 +2323,7 @@ BPoseView::MessageReceived(BMessage* message)
{ {
TrackerSettings settings; TrackerSettings settings;
if ((modifiers() & B_SHIFT_KEY) != 0 || !settings.MoveFilesToTrash()) if ((modifiers() & B_SHIFT_KEY) != 0 || settings.DontMoveFilesToTrash())
DeleteSelection(true, settings.AskBeforeDeleteFile()); DeleteSelection(true, settings.AskBeforeDeleteFile());
else else
MoveSelectionToTrash(); MoveSelectionToTrash();
@@ -6461,7 +6461,7 @@ BPoseView::KeyDown(const char* bytes, int32 count)
} else { } else {
TrackerSettings settings; TrackerSettings settings;
if ((modifiers() & B_SHIFT_KEY) != 0 || !settings.MoveFilesToTrash()) if ((modifiers() & B_SHIFT_KEY) != 0 || settings.DontMoveFilesToTrash())
DeleteSelection(true, settings.AskBeforeDeleteFile()); DeleteSelection(true, settings.AskBeforeDeleteFile());
else else
MoveSelectionToTrash(); MoveSelectionToTrash();
+1 -1
View File
@@ -491,7 +491,7 @@ BPoseView::DeleteProperty(BMessage* _SCRIPTING_ONLY(specifier),
if (error == B_OK) { if (error == B_OK) {
TrackerSettings settings; TrackerSettings settings;
if (settings.MoveFilesToTrash()) { if (!settings.DontMoveFilesToTrash()) {
// move the list we build into trash, don't make the // move the list we build into trash, don't make the
// trashing task select the next item // trashing task select the next item
MoveListToTrash(entryList, false, false); MoveListToTrash(entryList, false, false);
-148
View File
@@ -947,151 +947,3 @@ SpaceBarSettingsView::IsRevertable() const
|| fFreeSpaceColor != settings.FreeSpaceColor() || fFreeSpaceColor != settings.FreeSpaceColor()
|| fWarningSpaceColor != settings.WarningSpaceColor(); || fWarningSpaceColor != settings.WarningSpaceColor();
} }
// #pragma mark -
TrashSettingsView::TrashSettingsView()
:
SettingsView("TrashSettingsView")
{
fMoveFilesToTrashCheckBox = new BCheckBox("",
B_TRANSLATE("Move deleted files to Trash first"),
new BMessage(kMoveFilesToTrashChanged));
fAskBeforeDeleteFileCheckBox = new BCheckBox("",
B_TRANSLATE("Ask before deleting for good"),
new BMessage(kAskBeforeDeleteFileChanged));
const float spacing = be_control_look->DefaultItemSpacing();
BGroupLayout* layout = GroupLayout();
layout->SetOrientation(B_VERTICAL);
layout->SetSpacing(0);
BGroupLayoutBuilder(layout)
.Add(fMoveFilesToTrashCheckBox)
.Add(fAskBeforeDeleteFileCheckBox)
.AddGlue()
.SetInsets(spacing, spacing, spacing, spacing);
}
void
TrashSettingsView::AttachedToWindow()
{
fMoveFilesToTrashCheckBox->SetTarget(this);
fAskBeforeDeleteFileCheckBox->SetTarget(this);
}
void
TrashSettingsView::MessageReceived(BMessage* message)
{
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
if (!tracker)
return;
TrackerSettings settings;
switch (message->what) {
case kMoveFilesToTrashChanged:
settings.SetMoveFilesToTrash(
fMoveFilesToTrashCheckBox->Value() == 1);
tracker->SendNotices(kMoveFilesToTrashChanged);
Window()->PostMessage(kSettingsContentsModified);
break;
case kAskBeforeDeleteFileChanged:
settings.SetAskBeforeDeleteFile(
fAskBeforeDeleteFileCheckBox->Value() == 1);
tracker->SendNotices(kAskBeforeDeleteFileChanged);
Window()->PostMessage(kSettingsContentsModified);
break;
default:
_inherited::MessageReceived(message);
break;
}
}
void
TrashSettingsView::SetDefaults()
{
TrackerSettings settings;
settings.SetMoveFilesToTrash(true);
settings.SetAskBeforeDeleteFile(true);
ShowCurrentSettings();
_SendNotices();
}
bool
TrashSettingsView::IsDefaultable() const
{
TrackerSettings settings;
return settings.MoveFilesToTrash() != true
|| settings.AskBeforeDeleteFile() != true;
}
void
TrashSettingsView::Revert()
{
TrackerSettings settings;
settings.SetMoveFilesToTrash(fMoveFilesToTrash);
settings.SetAskBeforeDeleteFile(fAskBeforeDeleteFile);
ShowCurrentSettings();
_SendNotices();
}
void
TrashSettingsView::_SendNotices()
{
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
if (!tracker)
return;
tracker->SendNotices(kMoveFilesToTrashChanged);
tracker->SendNotices(kAskBeforeDeleteFileChanged);
}
void
TrashSettingsView::ShowCurrentSettings()
{
TrackerSettings settings;
fMoveFilesToTrashCheckBox->SetValue(settings.MoveFilesToTrash());
fAskBeforeDeleteFileCheckBox->SetValue(settings.AskBeforeDeleteFile());
}
void
TrashSettingsView::RecordRevertSettings()
{
TrackerSettings settings;
fMoveFilesToTrash = settings.MoveFilesToTrash();
fAskBeforeDeleteFile = settings.AskBeforeDeleteFile();
}
bool
TrashSettingsView::IsRevertable() const
{
return fMoveFilesToTrash
!= (fMoveFilesToTrashCheckBox->Value() > 0)
|| fAskBeforeDeleteFile
!= (fAskBeforeDeleteFileCheckBox->Value() > 0);
}
-27
View File
@@ -163,33 +163,6 @@ class SpaceBarSettingsView : public SettingsView {
typedef SettingsView _inherited; typedef SettingsView _inherited;
}; };
class TrashSettingsView : public SettingsView {
public:
TrashSettingsView();
virtual void MessageReceived(BMessage* message);
virtual void AttachedToWindow();
virtual void SetDefaults();
virtual bool IsDefaultable() const;
virtual void Revert();
virtual void ShowCurrentSettings();
virtual void RecordRevertSettings();
virtual bool IsRevertable() const;
private:
void _SendNotices();
BCheckBox* fMoveFilesToTrashCheckBox;
BCheckBox* fAskBeforeDeleteFileCheckBox;
bool fMoveFilesToTrash;
bool fAskBeforeDeleteFile;
typedef SettingsView _inherited;
};
} // namespace BPrivate } // namespace BPrivate
using namespace BPrivate; using namespace BPrivate;
+7 -7
View File
@@ -82,7 +82,7 @@ class TTrackerState : public Settings {
HexScalarValueSetting* fFreeSpaceColor; HexScalarValueSetting* fFreeSpaceColor;
HexScalarValueSetting* fWarningSpaceColor; HexScalarValueSetting* fWarningSpaceColor;
BooleanValueSetting* fMoveFilesToTrash; BooleanValueSetting* fDontMoveFilesToTrash;
BooleanValueSetting* fAskBeforeDeleteFile; BooleanValueSetting* fAskBeforeDeleteFile;
Benaphore fInitLock; Benaphore fInitLock;
@@ -202,8 +202,8 @@ TTrackerState::LoadSettingsIfNeeded()
Add(fWarningSpaceColor Add(fWarningSpaceColor
= new HexScalarValueSetting("WarningSpaceColor", 0xc0cb0000, "", "")); = new HexScalarValueSetting("WarningSpaceColor", 0xc0cb0000, "", ""));
Add(fMoveFilesToTrash Add(fDontMoveFilesToTrash
= new BooleanValueSetting("MoveFilesToTrash", true)); = new BooleanValueSetting("DontMoveFilesToTrash", false));
Add(fAskBeforeDeleteFile Add(fAskBeforeDeleteFile
= new BooleanValueSetting("AskBeforeDeleteFile", true)); = new BooleanValueSetting("AskBeforeDeleteFile", true));
@@ -509,16 +509,16 @@ TrackerSettings::SetRecentFoldersCount(int32 count)
bool bool
TrackerSettings::MoveFilesToTrash() TrackerSettings::DontMoveFilesToTrash()
{ {
return gTrackerState.fMoveFilesToTrash->Value(); return gTrackerState.fDontMoveFilesToTrash->Value();
} }
void void
TrackerSettings::SetMoveFilesToTrash(bool enabled) TrackerSettings::SetDontMoveFilesToTrash(bool enabled)
{ {
gTrackerState.fMoveFilesToTrash->SetValue(enabled); gTrackerState.fDontMoveFilesToTrash->SetValue(enabled);
} }
+2 -2
View File
@@ -118,8 +118,8 @@ class TrackerSettings {
bool ClockIs24Hr(); bool ClockIs24Hr();
void SetClockTo24Hr(bool); void SetClockTo24Hr(bool);
bool MoveFilesToTrash(); bool DontMoveFilesToTrash();
void SetMoveFilesToTrash(bool); void SetDontMoveFilesToTrash(bool);
bool AskBeforeDeleteFile(); bool AskBeforeDeleteFile();
void SetAskBeforeDeleteFile(bool); void SetAskBeforeDeleteFile(bool);
@@ -114,8 +114,6 @@ TrackerSettingsWindow::TrackerSettingsWindow()
new DesktopSettingsView())); new DesktopSettingsView()));
fSettingsTypeListView->AddItem(new SettingsItem(B_TRANSLATE("Windows"), fSettingsTypeListView->AddItem(new SettingsItem(B_TRANSLATE("Windows"),
new WindowsSettingsView())); new WindowsSettingsView()));
fSettingsTypeListView->AddItem(new SettingsItem(B_TRANSLATE("Trash"),
new TrashSettingsView()));
fSettingsTypeListView->AddItem(new SettingsItem( fSettingsTypeListView->AddItem(new SettingsItem(
B_TRANSLATE("Volume icons"), new SpaceBarSettingsView())); B_TRANSLATE("Volume icons"), new SpaceBarSettingsView()));
+51 -28
View File
@@ -20,58 +20,81 @@ using std::cout;
using std::endl; using std::endl;
typedef struct typedef struct {
{
const char* cookieString; const char* cookieString;
const char* url;
struct struct
{ {
bool valid;
const char* name; const char* name;
const char* value; const char* value;
const char* domain; const char* domain;
const char* path; const char* path;
bool secure; bool secure;
bool discard; bool httponly;
bool session; bool session;
int32 maxAge; BDateTime expire;
} expected; } expected;
} ExplodeTest; } ExplodeTest;
const ExplodeTest kTestExplode[] =
// Cookie string ExplodeTest kTestExplode[] =
// Name Value Domain Path Secure Discard Session maxAge // Cookie string URL
// -------- --------- --------- --------- ------ ------- -------- ------- // ------------- -------------
// Valid Name Value Domain Path Secure HttpOnly Session Expiration
// --------- -------- --------- ----------------- --------- -------- -------- ------- ----------
{ {
{ "name=value", // Normal cookies
{ "name", "value", "", "", false, false, true, 0 } }, { "name=value", "http://www.example.com/path/path",
{ "name=value;secure=true", { true, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } },
{ "name", "value", "", "", true, false, true, 0 } }, { "name=value; domain=example.com; path=/; secure", "http://www.example.com/path/path",
{ "name=value;secure=false;maxage=5", { true, "name", "value", "example.com", "/" , true, false, true, BDateTime() } },
{ "name", "value", "", "", false, false, false, 5 } }, { "name=value; httponly; secure", "http://www.example.com/path/path",
{ "name=value;discard=true", { true, "name", "value", "www.example.com", "/path", true, true, true, BDateTime() } },
{ "name", "value", "", "", false, true, true, 0 } }, { "name=value; expires=Wed, 20 Feb 2013 20:00:00 UTC", "http://www.example.com/path/path",
{ true, "name", "value", "www.example.com", "/path", false, false, false,
BDateTime(BDate(2012, 2, 20), BTime(20, 0, 0, 0)) } },
// Valid cookie with bad form
{ "name= ; domain =example.com ;path=/; secure = yup ; blahblah ;)", "http://www.example.com/path/path",
{ true, "name", "", "example.com", "/" , true, false, true, BDateTime() } },
// Invalid path, default path should be used instead
{ "name=value; path=invalid", "http://www.example.com/path/path",
{ true, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } },
// Setting for other subdomain (invalid)
{ "name=value; domain=subdomain.example.com", "http://www.example.com/path/path",
{ false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } },
// Various invalid cookies
{ "name", "http://www.example.com/path/path",
{ false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } },
{ "; domain=example.com", "http://www.example.com/path/path",
{ false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } }
}; };
void explodeImplodeTest() void explodeImplodeTest()
{ {
uint8 testIndex; uint32 testIndex;
BNetworkCookie cookie; BNetworkCookie cookie;
for (testIndex = 0; testIndex < (sizeof(kTestExplode) / sizeof(ExplodeTest)); testIndex++) for (testIndex = 0; testIndex < (sizeof(kTestExplode) / sizeof(ExplodeTest)); testIndex++)
{ {
cookie.ParseCookieString(kTestExplode[testIndex].cookieString); BUrl url(kTestExplode[testIndex].url);
cookie.ParseCookieStringFromUrl(kTestExplode[testIndex].cookieString, url);
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.name) == BString(cookie.Name())); ASSERT(testIndex, kTestExplode[testIndex].expected.valid == cookie.IsValid());
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.value) == BString(cookie.Value()));
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.domain) == BString(cookie.Domain()));
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.path) == BString(cookie.Path()));
ASSERT(testIndex, kTestExplode[testIndex].expected.secure == cookie.Secure());
ASSERT(testIndex, kTestExplode[testIndex].expected.discard == cookie.Discard());
ASSERT(testIndex, kTestExplode[testIndex].expected.session == cookie.IsSessionCookie());
if (!cookie.IsSessionCookie()) if (kTestExplode[testIndex].expected.valid) {
ASSERT(testIndex, kTestExplode[testIndex].expected.maxAge == cookie.MaxAge()); ASSERT(testIndex, BString(kTestExplode[testIndex].expected.name) == cookie.Name());
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.value) == cookie.Value());
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.domain) == cookie.Domain());
ASSERT(testIndex, BString(kTestExplode[testIndex].expected.path) == cookie.Path());
ASSERT(testIndex, kTestExplode[testIndex].expected.secure == cookie.Secure());
ASSERT(testIndex, kTestExplode[testIndex].expected.httponly == cookie.HttpOnly());
ASSERT(testIndex, kTestExplode[testIndex].expected.session == cookie.IsSessionCookie());
if (!cookie.IsSessionCookie())
ASSERT(testIndex, kTestExplode[testIndex].expected.expire.Time_t() == cookie.ExpirationDate());
}
} }
} }