[haiku-commits] haiku: hrev45264 - src/kits/network/libnetapi src/tests/kits/net/cookie headers/os/net

  • From: hamishm53@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 9 Feb 2013 18:11:32 +0100 (CET)

hrev45264 adds 6 changesets to branch 'master'
old head: dcaec19c9a11eec63fd86420326935c5097e48e9
new head: 64a1f5a020afbbb203b72bfb07e1b08d38431bfe
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=64a1f5a+%5Edcaec19

----------------------------------------------------------------------------

2e7b5f9: NetworkCookieJar: don't leak a new cookie if it has expired

05f42aa: NetworkCookie: set the default path according to RFC 6265

2db5d2b: NetworkCookie: remove unused cookie attributes and add HttpOnly

33462ef: NetworkCookie: bring SetCookie parsing in line with RFC 6265

c8bc218: NetworkCookie: fix domain/path matching, and validity checks

64a1f5a: NetworkCookieJar: various small fixes and updated tests

                                   [ Hamish Morrison <hamishm53@xxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 617 insertions(+), 658 deletions(-)
headers/os/net/NetworkCookie.h                  |  93 ++-
headers/os/net/NetworkCookieJar.h               |  27 +-
src/kits/network/libnetapi/NetworkCookie.cpp    | 711 +++++++++-----------
src/kits/network/libnetapi/NetworkCookieJar.cpp | 317 ++++-----
src/tests/kits/net/cookie/cookie_test.cpp       | 127 ++--

############################################################################

Commit:      2e7b5f9e185297670adc17f3aada0a4af6a48838
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2e7b5f9
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Sat Jan 26 19:23:34 2013 UTC

NetworkCookieJar: don't leak a new cookie if it has expired

----------------------------------------------------------------------------

diff --git a/src/kits/network/libnetapi/NetworkCookieJar.cpp 
b/src/kits/network/libnetapi/NetworkCookieJar.cpp
index eef91d1..5b8a945 100644
--- a/src/kits/network/libnetapi/NetworkCookieJar.cpp
+++ b/src/kits/network/libnetapi/NetworkCookieJar.cpp
@@ -20,14 +20,14 @@ const char* kArchivedCookieMessageName      =       
"be:cookie";
 
 
 BNetworkCookieJar::BNetworkCookieJar()
-       : 
+       :
        fCookieHashMap(new PrivateHashMap)
 {
 }
 
 
 BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&)
-       : 
+       :
        BArchivable(),
        fCookieHashMap(new PrivateHashMap)
 {
@@ -36,7 +36,7 @@ BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieJar&)
 
 
 BNetworkCookieJar::BNetworkCookieJar(const BNetworkCookieList& otherList)
-       : 
+       :
        fCookieHashMap(new PrivateHashMap)
 {
        AddCookies(otherList);
@@ -44,18 +44,18 @@ BNetworkCookieJar::BNetworkCookieJar(const 
BNetworkCookieList& otherList)
 
 
 BNetworkCookieJar::BNetworkCookieJar(BMessage* archive)
-       : 
+       :
        fCookieHashMap(new PrivateHashMap)
 {
        BMessage extractedCookie;
-       
+
        for (int32 i = 0;
                archive->FindMessage(kArchivedCookieMessageName, i, 
&extractedCookie)
                        == B_OK;
                i++) {
-               BNetworkCookie* heapCookie 
+               BNetworkCookie* heapCookie
                        = new(std::nothrow) BNetworkCookie(&extractedCookie);
-               
+
                if (heapCookie == NULL || !AddCookie(heapCookie))
                        break;
        }
@@ -65,7 +65,7 @@ BNetworkCookieJar::BNetworkCookieJar(BMessage* archive)
 BNetworkCookieJar::~BNetworkCookieJar()
 {
        BNetworkCookie* cookiePtr;
-       
+
        for (Iterator it(GetIterator()); (cookiePtr = it.Next()); )
                delete it.Remove();
 }
@@ -78,12 +78,12 @@ bool
 BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie)
 {
        BNetworkCookie* heapCookie = new(std::nothrow) BNetworkCookie(cookie);
-       
+
        if (!AddCookie(heapCookie)) {
                delete heapCookie;
                return false;
        }
-       
+
        return true;
 }
 
@@ -91,29 +91,27 @@ BNetworkCookieJar::AddCookie(const BNetworkCookie& cookie)
 bool
 BNetworkCookieJar::AddCookie(BNetworkCookie* cookie)
 {
-       if (cookie != NULL) {
-               HashString key(cookie->Domain());
-               
-               if (!fCookieHashMap->fHashMap.ContainsKey(key))
-                       fCookieHashMap->fHashMap.Put(key, new BList);
-                       
-               BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key);
-               
-               for (int32 i = 0; i < list->CountItems(); i++) {
-                       BNetworkCookie* c
-                               = 
reinterpret_cast<BNetworkCookie*>(list->ItemAt(i));
-                               
-                       if (c->Name() == cookie->Name()) {
-                               list->RemoveItem(i);
-                               break;
-                       }
+       if (cookie == NULL || cookie->ShouldDeleteNow())
+               return false;
+
+       HashString key(cookie->Domain());
+
+       if (!fCookieHashMap->fHashMap.ContainsKey(key))
+               fCookieHashMap->fHashMap.Put(key, new BList);
+
+       BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key);
+
+       for (int32 i = 0; i < list->CountItems(); i++) {
+               BNetworkCookie* c
+                       = reinterpret_cast<BNetworkCookie*>(list->ItemAt(i));
+
+               if (c->Name() == cookie->Name()) {
+                       list->RemoveItem(i);
+                       break;
                }
-               
-               // Discard the cookie if it's to be deleted
-               if (!cookie->ShouldDeleteNow())
-                       list->AddItem(cookie);
        }
-       
+
+       list->AddItem(cookie);
        return true;
 }
 
@@ -122,15 +120,15 @@ bool
 BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies)
 {
        for (int32 i = 0; i < cookies.CountItems(); i++) {
-               BNetworkCookie* cookiePtr 
+               BNetworkCookie* cookiePtr
                        = reinterpret_cast<BNetworkCookie*>(cookies.ItemAt(i));
-               
+
                // Using AddCookie by reference in order to avoid multiple
                // cookie jar share the same cookie pointers
                if (!AddCookie(*cookiePtr))
                        return false;
        }
-       
+
        return true;
 }
 
@@ -143,8 +141,8 @@ BNetworkCookieJar::DeleteOutdatedCookies()
 {
        int32 deleteCount = 0;
        BNetworkCookie* cookiePtr;
-       
-       for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) {           
        
+
+       for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
                if (cookiePtr->ShouldDeleteNow()) {
                        delete it.Remove();
                        deleteCount++;
@@ -160,8 +158,8 @@ BNetworkCookieJar::PurgeForExit()
 {
        int32 deleteCount = 0;
        BNetworkCookie* cookiePtr;
-       
-       for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) {           
        
+
+       for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
                if (cookiePtr->ShouldDeleteAtExit()) {
                        delete it.Remove();
                        deleteCount++;
@@ -182,10 +180,10 @@ BNetworkCookieJar::Archive(BMessage* into, bool deep) 
const
 
        if (error == B_OK) {
                BNetworkCookie* cookiePtr;
-       
-               for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) {
+
+               for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != 
NULL;) {
                        BMessage subArchive;
-                       
+
                        error = cookiePtr->Archive(&subArchive, deep);
                        if (error != B_OK)
                                return error;
@@ -205,7 +203,7 @@ BNetworkCookieJar::Instantiate(BMessage* archive)
 {
        if (archive->HasMessage(kArchivedCookieMessageName))
                return new(std::nothrow) BNetworkCookieJar(archive);
-               
+
        return NULL;
 }
 
@@ -242,11 +240,11 @@ BNetworkCookieJar::Flatten(void* buffer, ssize_t size) 
const
 {
        if (FlattenedSize() > size)
                return B_ERROR;
-               
-       fFlattened.CopyInto(reinterpret_cast<char*>(buffer), 0, 
+
+       fFlattened.CopyInto(reinterpret_cast<char*>(buffer), 0,
                fFlattened.Length());
        reinterpret_cast<char*>(buffer)[fFlattened.Length()] = 0;
-               
+
        return B_OK;
 }
 
@@ -262,13 +260,13 @@ BNetworkCookieJar::AllowsTypeCode(type_code) const
 status_t
 BNetworkCookieJar::Unflatten(type_code, const void* buffer, ssize_t size)
 {
-       BString flattenedCookies;       
+       BString flattenedCookies;
        flattenedCookies.SetTo(reinterpret_cast<const char*>(buffer), size);
-       
-       while (flattenedCookies.Length() > 0) {         
+
+       while (flattenedCookies.Length() > 0) {
                BNetworkCookie tempCookie;
                BString tempCookieLine;
-               
+
                int32 endOfLine = flattenedCookies.FindFirst('\n', 0);
                if (endOfLine == -1)
                        tempCookieLine = flattenedCookies;
@@ -276,11 +274,11 @@ BNetworkCookieJar::Unflatten(type_code, const void* 
buffer, ssize_t size)
                        flattenedCookies.MoveInto(tempCookieLine, 0, endOfLine);
                        flattenedCookies.Remove(0, 1);
                }
-               
+
                if (tempCookieLine.Length() != 0 && tempCookieLine[0] != '#') {
                        for (int32 field = 0; field < 7; field++) {
                                BString tempString;
-                               
+
                                int32 endOfField = 
tempCookieLine.FindFirst('\t', 0);
                                if (endOfField == -1)
                                        tempString = tempCookieLine;
@@ -288,42 +286,42 @@ BNetworkCookieJar::Unflatten(type_code, const void* 
buffer, ssize_t size)
                                        tempCookieLine.MoveInto(tempString, 0, 
endOfField);
                                        tempCookieLine.Remove(0, 1);
                                }
-                               
+
                                switch (field) {
                                        case 0:
                                                
tempCookie.SetDomain(tempString);
                                                break;
-                                       
+
                                        case 1:
                                                // TODO: Useless field ATM
                                                break;
-                                               
+
                                        case 2:
                                                tempCookie.SetPath(tempString);
                                                break;
-                                               
+
                                        case 3:
                                                tempCookie.SetSecure(tempString 
== "TRUE");
                                                break;
-                                               
+
                                        case 4:
                                                
tempCookie.SetExpirationDate(atoi(tempString));
                                                break;
-                                               
+
                                        case 5:
                                                tempCookie.SetName(tempString);
                                                break;
-                                       
+
                                        case 6:
                                                tempCookie.SetValue(tempString);
                                                break;
                                } // switch
                        } // for loop
-                       
+
                        AddCookie(tempCookie);
                }
-       }       
-       
+       }
+
        return B_OK;
 }
 
@@ -346,7 +344,7 @@ BNetworkCookieJar::GetUrlIterator(const BUrl& url) const
                copy.SetPath("/");
                return BNetworkCookieJar::UrlIterator(this, copy);
        }
-       
+
        return BNetworkCookieJar::UrlIterator(this, url);
 }
 
@@ -357,10 +355,10 @@ BNetworkCookieJar::_DoFlatten() const
        fFlattened.Truncate(0);
 
        BNetworkCookie* cookiePtr;
-       for (Iterator it(GetIterator()); (cookiePtr = it.Next()); ) {
-               fFlattened      << cookiePtr->Domain() << '\t' << "TRUE" << 
'\t' 
-                       << cookiePtr->Path() << '\t' 
-                       << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t' 
+       for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) {
+               fFlattened      << cookiePtr->Domain() << '\t' << "TRUE" << '\t'
+                       << cookiePtr->Path() << '\t'
+                       << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t'
                        << (int32)cookiePtr->ExpirationDate() << '\t'
                        << cookiePtr->Name() << '\t' << cookiePtr->Value() << 
'\n';
        }
@@ -395,7 +393,7 @@ BNetworkCookieJar::Iterator::Iterator(const 
BNetworkCookieJar* cookieJar)
 {
        fIterator = new(std::nothrow) PrivateIterator(
                fCookieJar->fCookieHashMap->fHashMap.GetIterator());
-       
+
        // Locate first cookie
        _FindNext();
 }
@@ -419,7 +417,7 @@ BNetworkCookieJar::Iterator::Next()
 {
        if (!fElement)
                return NULL;
-               
+
        BNetworkCookie* result = fElement;
        _FindNext();
        return result;
@@ -431,18 +429,18 @@ BNetworkCookieJar::Iterator::NextDomain()
 {
        if (!fElement)
                return NULL;
-       
+
        BNetworkCookie* result = fElement;
-               
+
        if (!fIterator->fCookieMapIterator.HasNext()) {
                fElement = NULL;
                return NULL;
        }
-               
+
        fList = *(fIterator->fCookieMapIterator.NextValue());
        fIndex = 0;
        fElement = reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
-       
+
        return result;
 }
 
@@ -452,7 +450,7 @@ BNetworkCookieJar::Iterator::Remove()
 {
        if (!fLastElement)
                return NULL;
-               
+
        BNetworkCookie* result = fLastElement;
 
        if (fIndex == 0) {
@@ -466,7 +464,7 @@ BNetworkCookieJar::Iterator::Remove()
                fList->RemoveItem(fIndex-1);
                fIndex--;
        }
-       
+
        fLastElement = NULL;
        return result;
 }
@@ -490,18 +488,18 @@ void
 BNetworkCookieJar::Iterator::_FindNext()
 {
        fLastElement = fElement;
-       
+
        fIndex++;
        if (fList && fIndex < fList->CountItems()) {
                fElement = 
reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
                return;
        }
-       
+
        if (!fIterator->fCookieMapIterator.HasNext()) {
                fElement = NULL;
                return;
        }
-       
+
        fLastList = fList;
        fList = *(fIterator->fCookieMapIterator.NextValue());
        fIndex = 0;
@@ -538,11 +536,11 @@ BNetworkCookieJar::UrlIterator::UrlIterator(const 
BNetworkCookieJar* cookieJar,
 
        if (domain[0] != '.')
                domain.Prepend(".");
-               
+
        //  Prepending another dot since _FindNext is going to
        // call _SupDomain()
        domain.Prepend(".");
-       
+
        fIterator = new(std::nothrow) PrivateIterator(
                fCookieJar->fCookieHashMap->fHashMap.GetIterator());
        fIterator->fKey.SetTo(domain, domain.Length());
@@ -569,7 +567,7 @@ BNetworkCookieJar::UrlIterator::Next()
 {
        if (!fElement)
                return NULL;
-               
+
        BNetworkCookie* result = fElement;
        _FindNext();
        return result;
@@ -581,15 +579,15 @@ BNetworkCookieJar::UrlIterator::Remove()
 {
        if (!fLastElement)
                return NULL;
-               
+
        BNetworkCookie* result = fLastElement;
 
        fLastList->RemoveItem(fLastIndex);
 
        if (fLastList->CountItems() == 0) {
-               HashString lastKey(fLastElement->Domain(), 
+               HashString lastKey(fLastElement->Domain(),
                        fLastElement->Domain().Length());
-               
+
                delete fCookieJar->fCookieHashMap->fHashMap.Remove(lastKey);
        }
 
@@ -620,10 +618,10 @@ BNetworkCookieJar::UrlIterator::_SupDomain()
 {
        BString domain(fIterator->fKey.GetString());
        int32 nextDot = domain.FindFirst('.', 1);
-               
+
        if (nextDot == -1)
                return false;
-       
+
        domain.Remove(0, nextDot);
        fIterator->fKey.SetTo(domain.String(), domain.Length());
        return true;
@@ -635,17 +633,17 @@ BNetworkCookieJar::UrlIterator::_FindNext()
 {
        fLastIndex = fIndex;
        fLastElement = fElement;
-       
+
        if (_FindPath())
                return;
-       
+
        fLastList = fList;
        do {
                if (!_SupDomain()) {
                        fElement = NULL;
                        return;
                }
-               
+
                _FindDomain();
        } while (!_FindPath());
 }
@@ -655,10 +653,10 @@ void
 BNetworkCookieJar::UrlIterator::_FindDomain()
 {
        fList = fCookieJar->fCookieHashMap->fHashMap.Get(fIterator->fKey);
-       
+
        if (fList == NULL)
                fElement = NULL;
-       
+
        fIndex = -1;
 }
 
@@ -669,15 +667,15 @@ BNetworkCookieJar::UrlIterator::_FindPath()
        fIndex++;
        if (fList && fIndex < fList->CountItems()) {
                do {
-                       fElement 
+                       fElement
                                = 
reinterpret_cast<BNetworkCookie*>(fList->ItemAt(fIndex));
-                       
-                       if (fElement->IsValidForPath(fUrl.Path()))              
                
+
+                       if (fElement->IsValidForPath(fUrl.Path()))
                                return true;
-                               
+
                        fIndex++;
                } while (fList && fIndex < fList->CountItems());
        }
-       
+
        return false;
 }

############################################################################

Commit:      05f42aaba4c6b4ad6e023e029e1e2b3c55ec4d25
URL:         http://cgit.haiku-os.org/haiku/commit/?id=05f42aa
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Wed Jan 30 14:35:11 2013 UTC

NetworkCookie: set the default path according to RFC 6265

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkCookie.h b/headers/os/net/NetworkCookie.h
index 168c9b1..9ba5bc3 100644
--- a/headers/os/net/NetworkCookie.h
+++ b/headers/os/net/NetworkCookie.h
@@ -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;
diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index 16fad67..475a21a 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -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));
+}

############################################################################

Commit:      2db5d2bc95b8b37ce6f2cd0547cd5e6336992388
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2db5d2b
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Wed Jan 30 16:49:37 2013 UTC

NetworkCookie: remove unused cookie attributes and add HttpOnly

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkCookie.h b/headers/os/net/NetworkCookie.h
index 9ba5bc3..5a6fd01 100644
--- a/headers/os/net/NetworkCookie.h
+++ b/headers/os/net/NetworkCookie.h
@@ -32,33 +32,27 @@ public:
                        BNetworkCookie&         ParseCookieString(const 
BString& cookieString);
 
        // Modify the cookie fields
-                       BNetworkCookie&         SetComment(const BString& 
comment);
-                       BNetworkCookie&         SetCommentUrl(const BString& 
commentUrl);
-                       BNetworkCookie&         SetDiscard(bool discard);
+                       BNetworkCookie&         SetName(const BString& name);
+                       BNetworkCookie&         SetValue(const BString& value);
                        BNetworkCookie&         SetDomain(const BString& 
domain);
+                       BNetworkCookie&         SetPath(const BString& path);
                        BNetworkCookie&         SetMaxAge(int32 maxAge);
                        BNetworkCookie&         SetExpirationDate(time_t 
expireDate);
                        BNetworkCookie&         SetExpirationDate(BDateTime& 
expireDate);
-                       BNetworkCookie&         SetPath(const BString& path);
                        BNetworkCookie&         SetSecure(bool secure);
-                       BNetworkCookie&         SetVersion(int8 version);
-                       BNetworkCookie&         SetName(const BString& name);
-                       BNetworkCookie&         SetValue(const BString& value);
+                       BNetworkCookie&         SetHttpOnly(bool httpOnly);
 
        // Access the cookie fields
-                       const BString&          CommentUrl() const;
-                       const BString&          Comment() const;
-                       bool                            Discard() const;
+                       const BString&          Name() const;
+                       const BString&          Value() const;
                        const BString&          Domain() const;
-                       int32                           MaxAge() const;
+                       const BString&          Path() 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&          Value() const;
+                       bool                            HttpOnly() const;
                        const BString&          RawCookie(bool full) const;
+
                        bool                            IsSessionCookie() const;
                        bool                            IsValid(bool strict = 
false) const;
                        bool                            IsValidForUrl(const 
BUrl& url) const;
@@ -66,16 +60,11 @@ public:
                        bool                            IsValidForPath(const 
BString& path) const;
 
        // 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                            HasValue() const;
+                       bool                            HasDomain() const;
+                       bool                            HasPath() const;
+                       bool                            HasExpirationDate() 
const;
 
        // Test if cookie could be deleted
                        bool                            ShouldDeleteAtExit() 
const;
@@ -104,23 +93,18 @@ private:
        mutable BString                         fRawFullCookie;
        mutable bool                            fRawFullCookieValid;
 
-                       BString                         fComment;
-                       BString                         fCommentUrl;
-                       bool                            fDiscard;
                        BString                         fDomain;
                        BDateTime                       fExpiration;
        mutable BString                         fExpirationString;
        mutable bool                            fExpirationStringValid;
                        BString                         fPath;
                        bool                            fSecure;
-                       int8                            fVersion;
+                       bool                            fHttpOnly;
                        BString                         fName;
                        BString                         fValue;
 
-                       bool                            fHasDiscard;
                        bool                            fHasExpirationDate;
                        bool                            fSessionCookie;
-                       bool                            fHasVersion;
 };
 
 #endif // _B_NETWORK_COOKIE_H_
diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index 475a21a..ca86851 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -7,35 +7,30 @@
  */
 
 
-#include <cstdlib>
-#include <ctime>
 #include <new>
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
 #include <HttpTime.h>
 #include <NetworkCookie.h>
 
-#include <cstdio>
 #define PRINT(x) printf x;
 
 using BPrivate::BHttpTime;
 
-static const char*     kArchivedCookieComment                  = 
"be:cookie.comment";
-static const char*     kArchivedCookieCommentUrl               = 
"be:cookie.commenturl";
-static const char*     kArchivedCookieDiscard                  = 
"be:cookie.discard";
-static const char*     kArchivedCookieDomain                   = 
"be:cookie.domain";
-static const char*     kArchivedCookieExpirationDate   = 
"be:cookie.expiredate";
-static const char*     kArchivedCookiePath                     = 
"be:cookie.path";
-static const char*     kArchivedCookieSecure                   = 
"be:cookie.secure";
-static const char*     kArchivedCookieVersion                  = 
"be:cookie.version";
-static const char*     kArchivedCookieName                     = 
"be:cookie.name";
-static const char*     kArchivedCookieValue                    = 
"be:cookie.value";
+static const char* kArchivedCookieName = "be:cookie.name";
+static const char* kArchivedCookieValue = "be:cookie.value";
+static const char* kArchivedCookieDomain = "be:cookie.domain";
+static const char* kArchivedCookiePath = "be:cookie.path";
+static const char* kArchivedCookieExpirationDate = "be:cookie.expirationdate";
+static const char* kArchivedCookieSecure = "be:cookie.secure";
+static const char* kArchivedCookieHttpOnly = "be:cookie.httponly";
 
 
 BNetworkCookie::BNetworkCookie(const char* name, const char* value)
        :
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fVersion(0),
        fName(name),
        fValue(value),
        fSessionCookie(true)
@@ -45,12 +40,6 @@ BNetworkCookie::BNetworkCookie(const char* name, const char* 
value)
 
 
 BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
-       :
-       BArchivable(),
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fVersion(0),
-       fSessionCookie(true)
 {
        _Reset();
        *this = other;
@@ -58,11 +47,6 @@ BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
 
 
 BNetworkCookie::BNetworkCookie(const BString& cookieString)
-       :
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fVersion(0),
-       fSessionCookie(true)
 {
        _Reset();
        ParseCookieString(cookieString);
@@ -71,11 +55,6 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString)
 
 BNetworkCookie::BNetworkCookie(const BString& cookieString,
        const BUrl& url)
-       :
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fVersion(0),
-       fSessionCookie(true)
 {
        _Reset();
        ParseCookieStringFromUrl(cookieString, url);
@@ -84,9 +63,6 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString,
 
 BNetworkCookie::BNetworkCookie(BMessage* archive)
        :
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fVersion(0),
        fSessionCookie(true)
 {
        _Reset();
@@ -94,17 +70,10 @@ BNetworkCookie::BNetworkCookie(BMessage* archive)
        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;
+       archive->FindBool(kArchivedCookieHttpOnly, &fHttpOnly);
 
        int32 expiration;
        if (archive->FindInt32(kArchivedCookieExpirationDate, &expiration)
@@ -115,12 +84,6 @@ BNetworkCookie::BNetworkCookie(BMessage* archive)
 
 
 BNetworkCookie::BNetworkCookie()
-       :
-       fDiscard(false),
-       fExpiration(BDateTime::CurrentDateTime(B_GMT_TIME)),
-       fPath("/"),
-       fVersion(0),
-       fSessionCookie(true)
 {
        _Reset();
 }
@@ -169,28 +132,29 @@ BNetworkCookie::ParseCookieString(const BString& string)
 
 
 BNetworkCookie&
-BNetworkCookie::SetComment(const BString& comment)
+BNetworkCookie::SetName(const BString& name)
 {
-       fComment = comment;
+       fName = name;
        fRawFullCookieValid = false;
+       fRawCookieValid = false;
        return *this;
 }
 
 
 BNetworkCookie&
-BNetworkCookie::SetCommentUrl(const BString& commentUrl)
+BNetworkCookie::SetValue(const BString& value)
 {
-       fCommentUrl = commentUrl;
+       fValue = value;
        fRawFullCookieValid = false;
+       fRawCookieValid = false;
        return *this;
 }
 
 
 BNetworkCookie&
-BNetworkCookie::SetDiscard(bool discard)
+BNetworkCookie::SetPath(const BString& path)
 {
-       fDiscard = discard;
-       fHasDiscard = true;
+       fPath = path;
        fRawFullCookieValid = false;
        return *this;
 }
@@ -250,15 +214,6 @@ BNetworkCookie::SetExpirationDate(BDateTime& expireDate)
 
 
 BNetworkCookie&
-BNetworkCookie::SetPath(const BString& path)
-{
-       fPath = path;
-       fRawFullCookieValid = false;
-       return *this;
-}
-
-
-BNetworkCookie&
 BNetworkCookie::SetSecure(bool secure)
 {
        fSecure = secure;
@@ -268,31 +223,10 @@ BNetworkCookie::SetSecure(bool secure)
 
 
 BNetworkCookie&
-BNetworkCookie::SetVersion(int8 version)
-{
-       fVersion = version;
-       fHasVersion = true;
-       fRawCookieValid = false;
-       return *this;
-}
-
-
-BNetworkCookie&
-BNetworkCookie::SetName(const BString& name)
-{
-       fName = name;
-       fRawFullCookieValid = false;
-       fRawCookieValid = false;
-       return *this;
-}
-
-
-BNetworkCookie&
-BNetworkCookie::SetValue(const BString& value)
+BNetworkCookie::SetHttpOnly(bool httpOnly)
 {
-       fValue = value;
+       fHttpOnly = httpOnly;
        fRawFullCookieValid = false;
-       fRawCookieValid = false;
        return *this;
 }
 
@@ -301,23 +235,16 @@ BNetworkCookie::SetValue(const BString& value)
 
 
 const BString&
-BNetworkCookie::Comment() const
+BNetworkCookie::Name() const
 {
-       return fComment;
+       return fName;
 }
 
 
 const BString&
-BNetworkCookie::CommentUrl() const
-{
-       return fCommentUrl;
-}
-
-
-bool
-BNetworkCookie::Discard() const
+BNetworkCookie::Value() const
 {
-       return fDiscard;
+       return fValue;
 }
 
 
@@ -328,10 +255,10 @@ BNetworkCookie::Domain() const
 }
 
 
-int32
-BNetworkCookie::MaxAge() const
+const BString&
+BNetworkCookie::Path() const
 {
-       return fExpiration.Time_t() - 
BDateTime::CurrentDateTime(B_GMT_TIME).Time_t();
+       return fPath;
 }
 
 
@@ -356,13 +283,6 @@ BNetworkCookie::ExpirationString() const
 }
 
 
-const BString&
-BNetworkCookie::Path() const
-{
-       return fPath;
-}
-
-
 bool
 BNetworkCookie::Secure() const
 {
@@ -370,24 +290,10 @@ BNetworkCookie::Secure() const
 }
 
 
-int8
-BNetworkCookie::Version() const
-{
-       return fVersion;
-}
-
-
-const BString&
-BNetworkCookie::Name() const
-{
-       return fName;
-}
-
-
-const BString&
-BNetworkCookie::Value() const
+bool
+BNetworkCookie::HttpOnly() const
 {
-       return fValue;
+       return fHttpOnly;
 }
 
 
@@ -400,23 +306,16 @@ BNetworkCookie::RawCookie(bool full) const
 
                fRawFullCookie << fName << "=" << fValue;
 
-               if (HasCommentUrl())
-                       fRawFullCookie << "; Comment-Url=" << fCommentUrl;
-               if (HasComment())
-                       fRawFullCookie << "; Comment=" << fComment;
-               if (HasDiscard())
-                       fRawFullCookie << "; Discard=" << 
(fDiscard?"true":"false");
                if (HasDomain())
                        fRawFullCookie << "; Domain=" << fDomain;
                if (HasExpirationDate())
-                       fRawFullCookie << "; Max-Age=" << MaxAge();
-//                     fRawFullCookie << "; Expires=" << ExpirationString();
+                       fRawFullCookie << "; Expires=" << ExpirationString();
                if (HasPath())
                        fRawFullCookie << "; Path=" << fPath;
-               if (Secure() && fSecure)
-                       fRawFullCookie << "; Secure=" << 
(fSecure?"true":"false");
-               if (HasVersion())
-                       fRawFullCookie << ", Version=" << fVersion;
+               if (Secure())
+                       fRawFullCookie << "; Secure";
+               if (HttpOnly())
+                       fRawFullCookie << "; HttpOnly";
 
        } else if (!full && !fRawCookieValid) {
                fRawCookie.Truncate(0);
@@ -425,7 +324,7 @@ BNetworkCookie::RawCookie(bool full) const
                fRawCookie << fName << "=" << fValue;
        }
 
-       return full?fRawFullCookie:fRawCookie;
+       return full ? fRawFullCookie : fRawCookie;
 }
 
 
@@ -442,13 +341,14 @@ BNetworkCookie::IsSessionCookie() const
 bool
 BNetworkCookie::IsValid(bool strict) const
 {
-       return HasName() && HasValue() && (!strict || HasVersion());
+       return HasName() && HasValue();
 }
 
 
 bool
 BNetworkCookie::IsValidForUrl(const BUrl& url) const
 {
+       // TODO: Take secure attribute into account
        BString urlHost = url.Host();
        BString urlPath = url.Path();
 
@@ -480,23 +380,16 @@ BNetworkCookie::IsValidForPath(const BString& path) const
 
 
 bool
-BNetworkCookie::HasCommentUrl() const
-{
-       return fCommentUrl.Length() > 0;
-}
-
-
-bool
-BNetworkCookie::HasComment() const
+BNetworkCookie::HasName() const
 {
-       return fComment.Length() > 0;
+       return fName.Length() > 0;
 }
 
 
 bool
-BNetworkCookie::HasDiscard() const
+BNetworkCookie::HasValue() const
 {
-       return fHasDiscard;
+       return fValue.Length() > 0;
 }
 
 
@@ -515,27 +408,6 @@ 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
 BNetworkCookie::HasExpirationDate() const
 {
        return fHasExpirationDate;
@@ -548,16 +420,14 @@ BNetworkCookie::HasExpirationDate() const
 bool
 BNetworkCookie::ShouldDeleteAtExit() const
 {
-       return (HasDiscard() && Discard())
-               || (!IsSessionCookie() && ShouldDeleteNow())
-               || IsSessionCookie();
+       return IsSessionCookie() || ShouldDeleteNow();
 }
 
 
 bool
 BNetworkCookie::ShouldDeleteNow() const
 {
-       if (!IsSessionCookie() && HasExpirationDate())
+       if (HasExpirationDate())
                return (BDateTime::CurrentDateTime(B_GMT_TIME) > fExpiration);
 
        return false;
@@ -585,24 +455,6 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
 
 
        // 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)
@@ -628,8 +480,8 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
                        return error;
        }
 
-       if (HasVersion()) {
-               error = into->AddInt8(kArchivedCookieVersion, fVersion);
+       if (HttpOnly()) {
+               error = into->AddBool(kArchivedCookieHttpOnly, fHttpOnly);
                if (error != B_OK)
                        return error;
        }
@@ -663,21 +515,16 @@ BNetworkCookie::operator=(const BNetworkCookie& other)
        fExpirationString                       = other.fExpirationString;
        fExpirationStringValid          = other.fExpirationStringValid;
 
-       fComment                                        = other.fComment;
-       fCommentUrl                                     = other.fCommentUrl;
-       fDiscard                                        = other.fDiscard;
+       fName                                           = other.fName;
+       fValue                                          = other.fValue;
        fDomain                                         = other.fDomain;
-       fExpiration                                     = other.fExpiration;
        fPath                                           = other.fPath;
+       fExpiration                                     = other.fExpiration;
        fSecure                                         = other.fSecure;
-       fVersion                                        = other.fVersion;
-       fName                                           = other.fName;
-       fValue                                          = other.fValue;
+       fHttpOnly                                       = other.fHttpOnly;
 
-       fHasDiscard                                     = other.fHasDiscard;
        fHasExpirationDate                      = other.fHasExpirationDate;
        fSessionCookie                          = other.fSessionCookie;
-       fHasVersion                                     = other.fHasVersion;
 
        return *this;
 }
@@ -708,21 +555,16 @@ BNetworkCookie::operator!=(const BNetworkCookie& other)
 void
 BNetworkCookie::_Reset()
 {
-       fComment.Truncate(0);
-       fCommentUrl.Truncate(0);
        fDomain.Truncate(0);
        fPath.Truncate(0);
        fName.Truncate(0);
        fValue.Truncate(0);
-       fDiscard                                = false;
        fSecure                                 = false;
-       fVersion                                = 0;
-       fExpiration                     = 0;
+       fHttpOnly                               = false;
+       fExpiration                     = BDateTime();
 
-       fHasDiscard                     = false;
        fHasExpirationDate              = false;
        fSessionCookie                  = true;
-       fHasVersion                     = false;
 
        fRawCookieValid                 = false;
        fRawFullCookieValid     = false;
@@ -782,17 +624,8 @@ BNetworkCookie::_ExtractNameValuePair(const BString& 
cookieString,
        name.Trim();
        value.Trim();
 
-       // Cookie comment
-       if (name == "comment")
-               SetComment(value);
-       // Cookie comment URL
-       else if (name == "comment-url")
-               SetCommentUrl(value);
-       // Cookie discard flag
-       else if (name == "discard")
-               SetDiscard(value.Length() == 0 || value.ToLower() == "true");
        // Cookie max-age
-       else if (name == "maxage")
+       if (name == "maxage")
                SetMaxAge(atoi(value.String()));
        // Cookie expiration date
        else if (name == "expires") {
@@ -807,9 +640,6 @@ BNetworkCookie::_ExtractNameValuePair(const BString& 
cookieString,
        // Cookie secure flag
        else if (name == "secure")
                SetSecure(value.Length() == 0 || value.ToLower() == "true");
-       // Cookie version
-       else if (name == "version")
-               SetVersion(atoi(value.String()));
 }
 
 

############################################################################

Commit:      33462ef54a6c481491c9716726619b5bb25c0dcf
URL:         http://cgit.haiku-os.org/haiku/commit/?id=33462ef
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Thu Jan 31 18:53:25 2013 UTC

NetworkCookie: bring SetCookie parsing in line with RFC 6265

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkCookie.h b/headers/os/net/NetworkCookie.h
index 5a6fd01..7db429f 100644
--- a/headers/os/net/NetworkCookie.h
+++ b/headers/os/net/NetworkCookie.h
@@ -17,7 +17,6 @@ class BNetworkCookie : public BArchivable {
 public:
                                                                
BNetworkCookie(const char* name,
                                                                        const 
char* value);
-                                                               
BNetworkCookie(const BNetworkCookie& other);
                                                                
BNetworkCookie(const BString& cookieString);
                                                                
BNetworkCookie(const BString& cookieString,
                                                                        const 
BUrl& url);
@@ -25,7 +24,7 @@ public:
                                                                
BNetworkCookie();
        virtual                                         ~BNetworkCookie();
 
-       // Parse a "SetCookie" string, or "name=value"
+       // Parse a "SetCookie" string
 
                        BNetworkCookie&         ParseCookieStringFromUrl(const 
BString& string,
                                                                        const 
BUrl& url);
@@ -53,6 +52,7 @@ public:
                        bool                            HttpOnly() const;
                        const BString&          RawCookie(bool full) const;
 
+                       bool                            IsHostOnly() const;
                        bool                            IsSessionCookie() const;
                        bool                            IsValid(bool strict = 
false) const;
                        bool                            IsValidForUrl(const 
BUrl& url) const;
@@ -76,34 +76,36 @@ public:
        static  BArchivable*            Instantiate(BMessage* archive);
 
        // Overloaded operators
-                       BNetworkCookie&         operator=(const BNetworkCookie& 
other);
                        BNetworkCookie&         operator=(const char* string);
                        bool                            operator==(const 
BNetworkCookie& other);
                        bool                            operator!=(const 
BNetworkCookie& other);
 private:
                        void                            _Reset();
-                       void                            _ExtractNameValuePair(
-                                                                       const 
BString& cookieString, int16* index,
-                                                                       bool 
parseField = false);
-                       void                            
_SetDefaultPathForUrl(const BUrl& url);
+                       int32                           
_ExtractNameValuePair(const BString& string,
+                                                                       
BString& name, BString& value,
+                                                                       int32 
index);
+                       int32                           
_ExtractAttributeValuePair(
+                                                                       const 
BString& string, BString& name,
+                                                                       
BString& value, int32 index);
+                       BString                         
_DefaultPathForUrl(const BUrl& url);
 
 private:
        mutable BString                         fRawCookie;
        mutable bool                            fRawCookieValid;
        mutable BString                         fRawFullCookie;
        mutable bool                            fRawFullCookieValid;
-
-                       BString                         fDomain;
-                       BDateTime                       fExpiration;
        mutable BString                         fExpirationString;
        mutable bool                            fExpirationStringValid;
+
+                       BString                         fName;
+                       BString                         fValue;
+                       BString                         fDomain;
                        BString                         fPath;
+                       BDateTime                       fExpiration;
                        bool                            fSecure;
                        bool                            fHttpOnly;
-                       BString                         fName;
-                       BString                         fValue;
 
-                       bool                            fHasExpirationDate;
+                       bool                            fHostOnly;
                        bool                            fSessionCookie;
 };
 
diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index ca86851..a06335a 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -1,9 +1,10 @@
 /*
- * Copyright 2010 Haiku Inc. All rights reserved.
+ * Copyright 2010-2013 Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             Christophe Huriaux, c.huriaux@xxxxxxxxx
+ *             Hamish Morrison, hamishm53@xxxxxxxxx
  */
 
 
@@ -13,11 +14,10 @@
 #include <stdlib.h>
 #include <time.h>
 
+#include <Debug.h>
 #include <HttpTime.h>
 #include <NetworkCookie.h>
 
-#define PRINT(x) printf x;
-
 using BPrivate::BHttpTime;
 
 static const char* kArchivedCookieName = "be:cookie.name";
@@ -27,22 +27,14 @@ static const char* kArchivedCookiePath = "be:cookie.path";
 static const char* kArchivedCookieExpirationDate = "be:cookie.expirationdate";
 static const char* kArchivedCookieSecure = "be:cookie.secure";
 static const char* kArchivedCookieHttpOnly = "be:cookie.httponly";
+static const char* kArchivedCookieHostOnly = "be:cookie.hostonly";
 
 
 BNetworkCookie::BNetworkCookie(const char* name, const char* value)
-       :
-       fName(name),
-       fValue(value),
-       fSessionCookie(true)
-{
-       _Reset();
-}
-
-
-BNetworkCookie::BNetworkCookie(const BNetworkCookie& other)
 {
        _Reset();
-       *this = other;
+       fName = name;
+       fValue = value;
 }
 
 
@@ -62,8 +54,6 @@ BNetworkCookie::BNetworkCookie(const BString& cookieString,
 
 
 BNetworkCookie::BNetworkCookie(BMessage* archive)
-       :
-       fSessionCookie(true)
 {
        _Reset();
 
@@ -74,6 +64,7 @@ BNetworkCookie::BNetworkCookie(BMessage* archive)
        archive->FindString(kArchivedCookiePath, &fPath);
        archive->FindBool(kArchivedCookieSecure, &fSecure);
        archive->FindBool(kArchivedCookieHttpOnly, &fHttpOnly);
+       archive->FindBool(kArchivedCookieHostOnly, &fHostOnly);
 
        int32 expiration;
        if (archive->FindInt32(kArchivedCookieExpirationDate, &expiration)
@@ -101,19 +92,61 @@ BNetworkCookie&
 BNetworkCookie::ParseCookieStringFromUrl(const BString& string,
        const BUrl& url)
 {
-       BString cookieString(string);
-       int16 index = 0;
-
        _Reset();
 
-       // Default values from url
-       SetDomain(url.Host());
-       _SetDefaultPathForUrl(url);
+       BString name;
+       BString value;
+       int32 index = 0;
+
+       // Parse the name and value of the cookie
+       index = _ExtractNameValuePair(string, name, value, index);
+       // The set-cookie-string is not valid
+       if (index == -1)
+               return *this;
+
+       SetName(name);
+       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);
+       }
 
-       _ExtractNameValuePair(cookieString, &index);
+       // If no domain was specified, we set a host-only domain from the URL
+       if (!HasDomain()) {
+               SetDomain(url.Host());
+               fHostOnly = true;
+       }
 
-       while (index < cookieString.Length())
-               _ExtractNameValuePair(cookieString, &index, true);
+       // If no path was specified we compute the default path from the URL
+       if (!HasPath())
+               SetPath(_DefaultPathForUrl(url));
 
        return *this;
 }
@@ -164,6 +197,7 @@ BNetworkCookie&
 BNetworkCookie::SetDomain(const BString& domain)
 {
        fDomain = domain;
+       fHostOnly = false;
 
        //  We always use pre-dotted domains for tail matching
        if (fDomain.ByteAt(0) != '.')
@@ -200,13 +234,11 @@ BNetworkCookie::SetExpirationDate(BDateTime& expireDate)
                fSessionCookie = true;
                fExpirationStringValid = false;
                fRawFullCookieValid = false;
-               fHasExpirationDate = false;
        } else {
                fExpiration = expireDate;
                fSessionCookie = false;
                fExpirationStringValid = false;
                fRawFullCookieValid = false;
-               fHasExpirationDate = true;
        }
 
        return *this;
@@ -332,6 +364,13 @@ BNetworkCookie::RawCookie(bool full) const
 
 
 bool
+BNetworkCookie::IsHostOnly() const
+{
+       return fHostOnly;
+}
+
+
+bool
 BNetworkCookie::IsSessionCookie() const
 {
        return fSessionCookie;
@@ -410,7 +449,7 @@ BNetworkCookie::HasPath() const
 bool
 BNetworkCookie::HasExpirationDate() const
 {
-       return fHasExpirationDate;
+       return !IsSessionCookie();
 }
 
 
@@ -461,7 +500,7 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
                        return error;
        }
 
-       if (fHasExpirationDate) {
+       if (HasExpirationDate()) {
                error = into->AddInt32(kArchivedCookieExpirationDate,
                        fExpiration.Time_t());
                if (error != B_OK)
@@ -486,6 +525,12 @@ BNetworkCookie::Archive(BMessage* into, bool deep) const
                        return error;
        }
 
+       if (IsHostOnly()) {
+               error = into->AddBool(kArchivedCookieHostOnly, true);
+               if (error != B_OK)
+                       return error;
+       }
+
        return B_OK;
 }
 
@@ -505,32 +550,6 @@ BNetworkCookie::Instantiate(BMessage* archive)
 
 
 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;
-
-       fName                                           = other.fName;
-       fValue                                          = other.fValue;
-       fDomain                                         = other.fDomain;
-       fPath                                           = other.fPath;
-       fExpiration                                     = other.fExpiration;
-       fSecure                                         = other.fSecure;
-       fHttpOnly                                       = other.fHttpOnly;
-
-       fHasExpirationDate                      = other.fHasExpirationDate;
-       fSessionCookie                          = other.fSessionCookie;
-
-       return *this;
-}
-
-
-BNetworkCookie&
 BNetworkCookie::operator=(const char* string)
 {
        return ParseCookieString(string);
@@ -555,109 +574,133 @@ BNetworkCookie::operator!=(const BNetworkCookie& other)
 void
 BNetworkCookie::_Reset()
 {
-       fDomain.Truncate(0);
-       fPath.Truncate(0);
        fName.Truncate(0);
        fValue.Truncate(0);
-       fSecure                                 = false;
-       fHttpOnly                               = false;
-       fExpiration                     = BDateTime();
+       fDomain.Truncate(0);
+       fPath.Truncate(0);
+       fExpiration = BDateTime();
+       fSecure = false;
+       fHttpOnly = false;
 
-       fHasExpirationDate              = false;
-       fSessionCookie                  = true;
+       fSessionCookie = true;
+       fHostOnly = true;
 
-       fRawCookieValid                 = false;
-       fRawFullCookieValid     = false;
-       fExpirationStringValid  = false;
+       fRawCookieValid = false;
+       fRawFullCookieValid = false;
+       fExpirationStringValid = false;
 }
 
 
-void
+int32
+skip_whitespace_forward(const BString& string, int32 index)
+{
+       while (index < string.Length() && (string[index] == ' '
+                       || string[index] == '\t'))
+               index++;
+       return index;
+}
+
+
+int32
+skip_whitespace_backward(const BString& string, int32 index)
+{
+       while (index >= 0 && (string[index] == ' ' || string[index] == '\t'))
+               index--;
+       return index;
+}
+
+
+int32
 BNetworkCookie::_ExtractNameValuePair(const BString& cookieString,
-       int16* index, bool parseField)
+       BString& name, BString& value, int32 index)
 {
-       // Skip whitespaces
-       while (cookieString.ByteAt(*index) == ' '
-               && *index < cookieString.Length())
-               (*index)++;
+       // Find our name-value-pair and the delimiter.
+       int32 firstEquals = cookieString.FindFirst('=', index);
+       int32 nameValueEnd = cookieString.FindFirst(';', index);
 
-       if (*index >= cookieString.Length())
-               return;
+       // If the set-cookie-string lacks a semicolon, the name-value-pair
+       // is the whole string.
+       if (nameValueEnd == -1)
+               nameValueEnd = cookieString.Length();
 
+       // If the name-value-pair lacks an equals, the parse should fail.
+       if (firstEquals == -1 || firstEquals > nameValueEnd)
+               return -1;
 
-       // Look for a name=value pair
-       int16 firstSemiColon = cookieString.FindFirst(";", *index);
-       int16 firstEqual = cookieString.FindFirst("=", *index);
+       int32 first = skip_whitespace_forward(cookieString, index);
+       int32 last = skip_whitespace_backward(cookieString, firstEquals - 1);
 
-       BString name;
-       BString value;
+       // If we lack a name, fail to parse.
+       if (first > last)
+               return -1;
 
-       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.Length() - *index);
+       cookieString.CopyInto(name, first, last - first + 1);
 
-               *index = cookieString.Length() + 1;
-       } else {
-               if (firstEqual != -1 && firstEqual < firstSemiColon) {
-                       cookieString.CopyInto(name, *index, firstEqual - 
*index);
-                       cookieString.CopyInto(value, firstEqual + 1,
-                               firstSemiColon - firstEqual - 1);
-               } else
-                       cookieString.CopyInto(value, *index, firstSemiColon - 
*index);
-
-               *index = firstSemiColon + 1;
-       }
+       first = skip_whitespace_forward(cookieString, firstEquals + 1);
+       last = skip_whitespace_backward(cookieString, nameValueEnd - 1);
+       if (first <= last)
+               cookieString.CopyInto(value, first, last - first + 1);
+       else
+               value.SetTo("");
+
+       return nameValueEnd;
+}
+
+
+int32
+BNetworkCookie::_ExtractAttributeValuePair(const BString& cookieString,
+       BString& attribute, BString& value, int32 index)
+{
+       // Find the end of our cookie-av.
+       int32 cookieAVEnd = cookieString.FindFirst(';', index);
+
+       // If the unparsed-attributes lacks a semicolon, then the cookie-av is 
the
+       // whole string.
+       if (cookieAVEnd == -1)
+               cookieAVEnd = cookieString.Length();
 
-       // Cookie name/value pair
-       if (!parseField) {
-               SetName(name);
-               SetValue(value);
-               return;
+       int32 attributeNameEnd = cookieString.FindFirst('=', index);
+       // If the cookie-av has no equals, the attribute-name is the entire
+       // cookie-av and the attribute-value is empty.
+       if (attributeNameEnd == -1 || attributeNameEnd > cookieAVEnd)
+               attributeNameEnd = cookieAVEnd;
+
+       int32 first = skip_whitespace_forward(cookieString, index);
+       int32 last = skip_whitespace_backward(cookieString, attributeNameEnd - 
1);
+
+       if (first <= last)
+               cookieString.CopyInto(attribute, first, last - first + 1);
+       else
+               attribute.SetTo("");
+
+       if (attributeNameEnd == cookieAVEnd) {
+               value.SetTo("");
+               return cookieAVEnd;
        }
 
-       name.ToLower();
-       name.Trim();
-       value.Trim();
-
-       // Cookie max-age
-       if (name == "maxage")
-               SetMaxAge(atoi(value.String()));
-       // Cookie expiration date
-       else if (name == "expires") {
-               BHttpTime date(value);
-               SetExpirationDate(date.Parse());
-       // Cookie valid domain
-       } else if (name == "domain")
-               SetDomain(value);
-       // Cookie valid path
-       else if (name == "path")
-               SetPath(value);
-       // Cookie secure flag
-       else if (name == "secure")
-               SetSecure(value.Length() == 0 || value.ToLower() == "true");
+       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;
 }
 
 
-void
-BNetworkCookie::_SetDefaultPathForUrl(const BUrl& url)
+BString
+BNetworkCookie::_DefaultPathForUrl(const BUrl& url)
 {
        const BString& path = url.Path();
-       if (path.IsEmpty() || path.ByteAt(0) != '/') {
-               SetPath("/");
-               return;
-       }
+       if (path.IsEmpty() || path.ByteAt(0) != '/')
+               return "";
 
        int32 index = path.FindLast('/');
-       if (index == 0) {
-               SetPath("/");
-               return;
-       }
+       if (index == 0)
+               return "";
 
        BString newPath = path;
-       SetPath(newPath.Truncate(index));
+       newPath.Truncate(index);
+       return newPath;
 }

############################################################################

Commit:      c8bc218363618030e5db44eb268a1da456596a9f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c8bc218
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Mon Feb  4 00:06:42 2013 UTC

NetworkCookie: fix domain/path matching, and validity checks

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkCookie.h b/headers/os/net/NetworkCookie.h
index 7db429f..dc9b78d 100644
--- a/headers/os/net/NetworkCookie.h
+++ b/headers/os/net/NetworkCookie.h
@@ -54,7 +54,7 @@ public:
 
                        bool                            IsHostOnly() const;
                        bool                            IsSessionCookie() const;
-                       bool                            IsValid(bool strict = 
false) const;
+                       bool                            IsValid() const;
                        bool                            IsValidForUrl(const 
BUrl& url) const;
                        bool                            IsValidForDomain(const 
BString& domain) const;
                        bool                            IsValidForPath(const 
BString& path) const;
diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index a06335a..e4a5311 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -378,16 +378,18 @@ BNetworkCookie::IsSessionCookie() const
 
 
 bool
-BNetworkCookie::IsValid(bool strict) const
+BNetworkCookie::IsValid() const
 {
-       return HasName() && HasValue();
+       return HasName() && HasDomain() && HasPath();
 }
 
 
 bool
 BNetworkCookie::IsValidForUrl(const BUrl& url) const
 {
-       // TODO: Take secure attribute into account
+       if (IsSecure() && url.Protocol() != "https")
+               return false;
+
        BString urlHost = url.Host();
        BString urlPath = url.Path();
 
@@ -398,20 +400,53 @@ BNetworkCookie::IsValidForUrl(const BUrl& url) const
 bool
 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 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
 BNetworkCookie::IsValidForPath(const BString& path) const
 {
-       if (fPath.Length() > path.Length())
+       const BString& cookiePath = Path();
+       if (path.Length() < cookiePath.Length())
+               return false;
+
+       // The cookie path must be a prefix of the path string
+       if (path.Compare(cookiePath, cookiePath.Length()) != 0)
                return false;
 
-       return path.FindFirst(fPath) == 0;
+       // 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;
 }
 
 

############################################################################

Revision:    hrev45264
Commit:      64a1f5a020afbbb203b72bfb07e1b08d38431bfe
URL:         http://cgit.haiku-os.org/haiku/commit/?id=64a1f5a
Author:      Hamish Morrison <hamishm53@xxxxxxxxx>
Date:        Thu Feb  7 17:59:43 2013 UTC

NetworkCookieJar: various small fixes and updated tests

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkCookieJar.h 
b/headers/os/net/NetworkCookieJar.h
index 31cd196..9c3e775 100644
--- a/headers/os/net/NetworkCookieJar.h
+++ b/headers/os/net/NetworkCookieJar.h
@@ -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.
  */
 #ifndef _B_NETWORK_COOKIE_JAR_H_
@@ -24,7 +24,7 @@ public:
                        class UrlIterator;
                        struct PrivateIterator;
                        struct PrivateHashMap;
-       
+
 public:
                                                                
BNetworkCookieJar();
                                                                
BNetworkCookieJar(
@@ -34,16 +34,15 @@ public:
                                                                
BNetworkCookieJar(BMessage* archive);
        virtual                                         ~BNetworkCookieJar();
 
-                       bool                            AddCookie(const 
BNetworkCookie& cookie);
-                       bool                            
AddCookie(BNetworkCookie* cookie);                      
-                       bool                            AddCookies(
-                                                                       const 
BNetworkCookieList& cookies);
+                       status_t                        AddCookie(const 
BNetworkCookie& cookie);
+                       status_t                        
AddCookie(BNetworkCookie* cookie);
+                       status_t                        AddCookies(const 
BNetworkCookieList& cookies);
 
                        uint32                          DeleteOutdatedCookies();
                        uint32                          PurgeForExit();
 
        // BArchivable members
-       virtual status_t                        Archive(BMessage* into, 
+       virtual status_t                        Archive(BMessage* into,
                                                                        bool 
deep = true) const;
        static  BArchivable*            Instantiate(BMessage* archive);
 
@@ -54,20 +53,20 @@ public:
        virtual status_t                        Flatten(void* buffer, ssize_t 
size)
                                                                        const;
        virtual bool                            AllowsTypeCode(type_code code) 
const;
-       virtual status_t                        Unflatten(type_code code, 
+       virtual status_t                        Unflatten(type_code code,
                                                                        const 
void* buffer, ssize_t size);
 
        // Iterators
                        Iterator                        GetIterator() const;
                        UrlIterator                     GetUrlIterator(const 
BUrl& url) const;
-                       
+
 private:
                        void                            _DoFlatten() const;
-       
+
 private:
        friend  class Iterator;
        friend  class UrlIterator;
-       
+
                        PrivateHashMap*         fCookieHashMap;
        mutable BString                         fFlattened;
 };
@@ -117,7 +116,7 @@ private:
                                                                
UrlIterator(const BNetworkCookieJar* map,
                                                                        const 
BUrl& url);
 
-                       bool                            _SupDomain();
+                       bool                            _SuperDomain();
                        void                            _FindNext();
                        void                            _FindDomain();
                        bool                            _FindPath();
@@ -131,10 +130,10 @@ private:
                        BNetworkCookieList* fLastList;
                        BNetworkCookie*         fElement;
                        BNetworkCookie*         fLastElement;
-                       
+
                        int32                           fIndex;
                        int32                           fLastIndex;
-                       
+
                        BUrl                            fUrl;
 };
 
diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index e4a5311..25b5e5c 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -100,14 +100,15 @@ BNetworkCookie::ParseCookieStringFromUrl(const BString& 
string,
 
        // Parse the name and value of the cookie
        index = _ExtractNameValuePair(string, name, value, index);
-       // The set-cookie-string is not valid
-       if (index == -1)
+       if (index == -1) {
+               // The set-cookie-string is not valid
                return *this;
+       }
 
        SetName(name);
        SetValue(value);
 
-       // Parse the remaining cookie attributes
+       // Parse the remaining cookie attributes.
        while (index < string.Length()) {
                ASSERT(string[index] == ';');
                index++;
@@ -119,12 +120,12 @@ BNetworkCookie::ParseCookieStringFromUrl(const BString& 
string,
                else if (name.ICompare("httponly") == 0)
                        SetHttpOnly(true);
 
-               // The following attributes require a value
+               // The following attributes require a value.
                if (value.IsEmpty())
                        continue;
 
                if (name.ICompare("max-age") == 0) {
-                       // Validate the max-age value
+                       // Validate the max-age value.
                        char* end = NULL;
                        long maxAge = strtol(value.String(), &end, 10);
                        if (*end == '\0')
@@ -132,20 +133,31 @@ BNetworkCookie::ParseCookieStringFromUrl(const BString& 
string,
                } else if (name.ICompare("expires") == 0) {
                        BHttpTime date(value);
                        SetExpirationDate(date.Parse());
-               } else if (name.ICompare("domain") == 0)
+               } else if (name.ICompare("domain") == 0) {
                        SetDomain(value);
-               else if (name.ICompare("path") == 0)
+               } else if (name.ICompare("path") == 0) {
                        SetPath(value);
+               }
        }
 
-       // If no domain was specified, we set a host-only domain from the URL
+       // 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 we compute the default path from the URL
-       if (!HasPath())
+       // 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;
@@ -187,6 +199,7 @@ BNetworkCookie::SetValue(const BString& value)
 BNetworkCookie&
 BNetworkCookie::SetPath(const BString& path)
 {
+       // TODO: canonicalize the path
        fPath = path;
        fRawFullCookieValid = false;
        return *this;
@@ -196,13 +209,10 @@ BNetworkCookie::SetPath(const BString& path)
 BNetworkCookie&
 BNetworkCookie::SetDomain(const BString& domain)
 {
+       // TODO: canonicalize the domain
        fDomain = domain;
        fHostOnly = false;
 
-       //  We always use pre-dotted domains for tail matching
-       if (fDomain.ByteAt(0) != '.')
-               fDomain.Prepend(".");
-
        fRawFullCookieValid = false;
        return *this;
 }
@@ -387,13 +397,10 @@ BNetworkCookie::IsValid() const
 bool
 BNetworkCookie::IsValidForUrl(const BUrl& url) const
 {
-       if (IsSecure() && url.Protocol() != "https")
+       if (Secure() && url.Protocol() != "https")
                return false;
 
-       BString urlHost = url.Host();
-       BString urlPath = url.Path();
-
-       return IsValidForDomain(urlHost) && IsValidForPath(urlPath);
+       return IsValidForDomain(url.Host()) && IsValidForPath(url.Path());
 }
 
 
diff --git a/src/kits/network/libnetapi/NetworkCookieJar.cpp 
b/src/kits/network/libnetapi/NetworkCookieJar.cpp
index 5b8a945..cfe3efd 100644
--- a/src/kits/network/libnetapi/NetworkCookieJar.cpp
+++ b/src/kits/network/libnetapi/NetworkCookieJar.cpp
@@ -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.
  *
  * Authors:
  *             Christophe Huriaux, c.huriaux@xxxxxxxxx
+ *             Hamish Morrison, hamishm53@xxxxxxxxx
  */
 
 
-#include <new>
-
 #include <Debug.h>
 #include <HashMap.h>
 #include <HashString.h>
 #include <Message.h>
 #include <NetworkCookieJar.h>
+
+#include <new>
+
 #include "NetworkCookieJarPrivate.h"
 
-const char* kArchivedCookieMessageName =       "be:cookie";
+
+const char* kArchivedCookieMessageName = "be:cookie";
 
 
 BNetworkCookieJar::BNetworkCookieJar()
        :
-       fCookieHashMap(new PrivateHashMap)
+       fCookieHashMap(new PrivateHashMap())
 {
 }

[ *** diff truncated: 531 lines dropped *** ]



Other related posts:

  • » [haiku-commits] haiku: hrev45264 - src/kits/network/libnetapi src/tests/kits/net/cookie headers/os/net - hamishm53