--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/httpfilters/cookie/ManagerSrc/Cookie.cpp Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,1624 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: implementation of class CCookie
+*
+*
+*/
+
+
+// INCLUDE FILES
+ // System includes
+#include <httpstringconstants.h>
+#include <http/rhttpheaders.h>
+#include <http/rhttpsession.h>
+#include <Uri8.h>
+
+ // User includes
+#include "cookie.h"
+#include "CookieCommonConstants.h"
+
+
+const TUint8 KDayOfWeekSeparator = ',';
+// const TUint8 KTimeSeparator = ':';
+
+_LIT8 ( KUT, "UT" );
+_LIT8 ( KGMT, "GMT" );
+_LIT8 ( KEST, "EST" );
+_LIT8 ( KEDT, "EDT" );
+_LIT8 ( KCST, "CST" );
+_LIT8 ( KCDT, "CDT" );
+_LIT8 ( KMST, "MST" );
+_LIT8 ( KMDT, "MDT" );
+_LIT8 ( KPST, "PST" );
+_LIT8 ( KPDT, "PDT" );
+
+const TUint8 KLocalTimeZoneSeparator1 = '+';
+const TUint8 KLocalTimeZoneSeparator2 = '-';
+
+const TInt KDateTokenCount = 3;
+const TInt KTimeTokenCount = 3;
+const TInt KAsciiTokenCount = 4;
+
+_LIT8( KLocalSeparators, " -");
+_LIT8( KLocalTimeSeparator, ":");
+
+_LIT8( KLocalMonthNames, "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" );
+
+
+
+
+// ---------------------------------------------------------
+// CCookie::NewL
+// ---------------------------------------------------------
+//
+EXPORT_C CCookie* CCookie::NewL( RHTTPHeaders aRequestHeaders, TInt aPartIndex,
+ RStringF aFieldName, RStringPool aStringPool,
+ const TUriC8& aUri )
+ {
+ CCookie* self = new (ELeave) CCookie( aStringPool );
+
+ CleanupStack::PushL( self );
+
+ self->ConstructL( aRequestHeaders, aPartIndex, aFieldName, aUri );
+
+ CleanupStack::Pop(); // self
+
+ return self;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::NewL
+// ---------------------------------------------------------
+//
+EXPORT_C CCookie* CCookie::NewL( RStringPool aStringPool )
+ {
+ return new (ELeave) CCookie( aStringPool );
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::~CCookie
+// ---------------------------------------------------------
+//
+EXPORT_C CCookie::~CCookie()
+ {
+ // go through each attribute closing any attribute strings
+ TInt numAttributes = iAttributes.Count();
+ for ( TInt ii = 0; ii < numAttributes; ++ii )
+ {
+ iAttributes[ii].Close();
+ }
+
+ iAttributes.Close();
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::AddDefaultPathL
+// ---------------------------------------------------------
+//
+void CCookie::AddDefaultPathL( const TUriC8& aUri )
+ {
+ // RFC2965 : Defaults to the path of the request URL that generated the
+ // Set-Cookie2 response, up to and including the right-most /.
+ // Note : there is a contradiction as we must not include the right-most /
+ // per RFC2109, which is obsolete. Decision : we support RFC2965.
+ const TUint8 KCookiePathSeparator = '/';
+ TPtrC8 requestPath;
+ if ( aUri.IsPresent( EUriPath ) )
+ {
+ requestPath.Set( aUri.Extract( EUriPath ) );
+
+ TInt sepPos = requestPath.LocateReverse( KCookiePathSeparator );
+ // if / is not the last character
+ if ( 0 <= sepPos && ( ( sepPos + 1 != requestPath.Length() ) ) )
+ {
+ // then remove characters after the right-most /
+ requestPath.Set( requestPath.Left( sepPos + 1 ) );
+ }
+ }
+ else
+ {
+ requestPath.Set( &KCookiePathSeparator,
+ sizeof( KCookiePathSeparator ) );
+ }
+
+ RStringF defPath = iStringPool.OpenFStringL( requestPath );
+ THTTPHdrVal defPathVal( defPath );
+ SetAttribute( EPath, defPathVal, ETrue );// ignore the result
+ defPath.Close();
+ }
+
+// ---------------------------------------------------------
+// CCookie::AddToRequestL
+// ---------------------------------------------------------
+//
+EXPORT_C void CCookie::AddToRequestL( RHTTPHeaders aRequestHeaders,
+ TInt aPartIndex ) const
+ {
+ const TStringTable& commonStringTable = RHTTPSession::GetTable();
+
+ // We're writing out the "Cookie:" string
+ RStringF cookieString =
+ iStringPool.StringF( HTTP::ECookie, commonStringTable );
+ aRequestHeaders.SetFieldL( cookieString, THTTPHdrVal() );
+
+ THTTPHdrVal hVal;
+
+ // We're writing out the Version attribute - it is a serious error if this
+ // attribute is missing
+ if ( Attribute( CCookie::EVersion, hVal ) == KErrNone )
+ {
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::EVersion,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+ }
+ else
+ {
+ if ( iSetCookie2 )
+ {
+ // if this is a new-style cookie (it is from a Set-Cookie2 header),
+ // then it must have a Version attribute.
+ // TBD : or should we insert a '$Version=1' string instead?
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+ // We're writing out the NAME attribute - it is a serious error if this
+ // attribute is missing
+ User::LeaveIfError( Attribute( CCookie::EName, hVal ) );
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::ECookieName,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+
+ // We're writing out the VALUE attribute - it is a serious error if this
+ // attribute is missing
+ User::LeaveIfError( Attribute( CCookie::EValue, hVal ) );
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::ECookieValue,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+
+ // Writing out the rest : domain, path and port. These are not mandatory,
+ // thus we do not leave if they are missing.
+ // Writing out Domain attribute
+ if ( Attribute( CCookie::EDomain, hVal ) == KErrNone && hVal.StrF().DesC().Length() > 0 )
+ {
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::EDomain,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+ }
+
+ // Writing out Path attribute
+ if ( Attribute( CCookie::EPath, hVal ) == KErrNone )
+ {
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::EPath,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+ }
+
+ // Writing out Port attribute
+ if ( Attribute( CCookie::EPort, hVal ) == KErrNone )
+ {
+ aRequestHeaders.SetParamL( cookieString,
+ iStringPool.StringF( HTTP::ECookiePort,
+ commonStringTable ),
+ hVal,
+ aPartIndex );
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::Attribute
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CCookie::Attribute
+ ( CCookie::TCookieAttributeName aAttributeName,
+ THTTPHdrVal& aAttributeVal) const
+ {
+ TCookieAttribute attribute;
+ if ( FindAttribute( aAttributeName, attribute ) != KErrNotFound )
+ {
+ aAttributeVal = attribute.Value();
+ return KErrNone;
+ }
+
+ return KErrNotFound;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::SetAttribute
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CCookie::SetAttribute
+ ( CCookie::TCookieAttributeName aAttributeName,
+ const THTTPHdrVal& aAttributeVal )
+ {
+ return SetAttribute( aAttributeName, aAttributeVal, EFalse );
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::Attribute
+// ---------------------------------------------------------
+//
+TInt CCookie::Attribute( TCookieAttributeName aAttributeName,
+ THTTPHdrVal& aAttributeVal,
+ TBool& aDefaulted ) const
+ {
+ TCookieAttribute attribute;
+ if ( FindAttribute( aAttributeName, attribute ) != KErrNotFound )
+ {
+ aAttributeVal = attribute.Value();
+ aDefaulted = attribute.Defaulted();
+ return KErrNone;
+ }
+
+ return KErrNotFound;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::SetAttribute
+// ---------------------------------------------------------
+//
+TInt CCookie::SetAttribute( TCookieAttributeName aAttributeName,
+ const THTTPHdrVal& aAttributeVal,
+ TBool aDefaulted )
+{
+ TInt result( KErrNone );
+
+ TCookieAttribute attribute;
+ TInt index = FindAttribute( aAttributeName, attribute );
+ if ( index != KErrNotFound )
+ {
+ result = KErrAlreadyExists;
+ }
+ else
+ {
+ TCookieAttribute newAttribute( aAttributeName,
+ aAttributeVal, aDefaulted );
+
+ result = iAttributes.Append( newAttribute );
+ if ( result == KErrNone )
+ {
+ iSize += ( KCookieAttributePrefixLength + newAttribute.Size() +
+ KCookieAttributeDefaultedLength +
+ KCookieAttributeFoundLength );
+ }
+ else
+ {
+ newAttribute.Close();
+ }
+ }
+ return result;
+}
+
+// ---------------------------------------------------------
+// CCookie::CopyFromL
+// ---------------------------------------------------------
+//
+void CCookie::CopyFromL( const CCookie& aCopyFrom )
+ {
+ THTTPHdrVal attributevalue;
+ TBool aDefaulted( EFalse );
+
+ if ( aCopyFrom.Attribute( EName, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EName, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EValue, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EValue, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EComment, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EComment, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( ECommentURI, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( ECommentURI, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EDiscard, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EDiscard, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EDomain, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EDomain, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EMaxAge, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EMaxAge, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EPath, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EPath, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EPort, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EPort, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( ESecure, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( ESecure, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EVersion, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EVersion, attributevalue, aDefaulted );
+ }
+
+ if ( aCopyFrom.Attribute( EExpires, attributevalue, aDefaulted ) != KErrNotFound )
+ {
+ SetAttribute( EExpires, attributevalue, aDefaulted );
+ }
+
+ SetCookie2( aCopyFrom.FromCookie2() );
+
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CCookie::StringPool
+// ---------------------------------------------------------
+//
+RStringPool CCookie::StringPool()
+ {
+ return iStringPool;
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::Expired
+// ---------------------------------------------------------
+//
+TBool CCookie::Expired() const
+ {
+ // the cookie has expired if:
+ // 1. it's Age > Max-Age
+ // 2. current_date > expires
+ // Expires is in Netscape cookie only !!!
+
+ TBool retval( EFalse );
+ THTTPHdrVal attrVal;
+ TInt err( KErrNone );
+
+ if ( FromNetscapeVersion() && ( Attribute( CCookie::EExpires, attrVal ) == KErrNone ))
+ {
+ if ( attrVal.Type() == THTTPHdrVal::KDateVal )
+ {
+ TDateTime expires;
+ expires = attrVal.DateTime();
+ TTime Expirytime( expires );
+ TTime NowTime;
+ NowTime.UniversalTime();
+ if ( Expirytime <= NowTime )
+ { // EXPIRED !!!!
+ retval = ETrue;
+ }
+ }
+ else
+ {
+ if ( attrVal.Type() == THTTPHdrVal::KStrFVal )
+ {
+ TRAP_IGNORE( retval = ExpiredNetscapeL( attrVal ) );
+ // The only real error is KErrNoMemory,
+ // so we simply ignore the error here
+ }
+ }
+ }
+ else
+ {
+ if ( Attribute( CCookie::EMaxAge, attrVal ) == KErrNone )
+ {
+ TInt MaxAge(0);
+ if ( attrVal.Type() == THTTPHdrVal::KTIntVal )
+ {
+ MaxAge = attrVal.Int();
+ }
+ else
+ {
+ TPtrC8 MaxAgePtr=CCookie::RemoveQuotes( attrVal.StrF().DesC() );
+ TLex8 lex( MaxAgePtr );
+ err = lex.Val( MaxAge );
+ }
+ if ( err == KErrNone )
+ {
+ // it's Age > Max-Age?
+ // Age = ( now_time - EDate )
+ // TTime.SecondsFrom(TTime)
+ // UniversalTime.SecondsFrom( EDate_time ): real age
+ TTime NowTime;
+ NowTime.UniversalTime();
+ TTimeIntervalSeconds CurrAgeInterval;
+ err = NowTime.SecondsFrom( iReceivedTime, CurrAgeInterval );
+ // now compare to specified Max-Age
+ if ( MaxAge <= CurrAgeInterval.Int() )
+ { // EXPIRED !!!!
+ retval = ETrue;
+ }
+
+
+ }
+ }
+ }
+ return retval;
+ }
+// ---------------------------------------------------------
+// CCookie::RemoveQuotes
+// ---------------------------------------------------------
+//
+ TPtrC8 CCookie::RemoveQuotes( const TDesC8& aDes )
+ {
+
+ TInt firstChar = 0; // position of the first character
+ TInt lastChar = aDes.Length() - 1; // position of the last character
+ TPtrC8 result;
+ if ( lastChar < 0 ) // that is, aDes has a length of zero
+ {
+ result.Set( aDes ); // the result is the same
+ }
+ else
+ {
+ TUint8 quotationMark = '"';
+
+ if ( aDes[ firstChar ] == quotationMark )
+ {
+ firstChar++;
+ }
+
+ if ( aDes[ lastChar ] == quotationMark )
+ {
+ lastChar--;
+ }
+
+ if ( lastChar < firstChar )
+ {
+ result.Set( KNullDesC8() );
+ }
+ else
+ {
+ result.Set( aDes.Mid( firstChar, lastChar - firstChar + 1 ) );
+ }
+ }
+
+ return result;
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::ExpiredNetscapeL
+// ---------------------------------------------------------
+//
+TBool CCookie::ExpiredNetscapeL( THTTPHdrVal aAttrVal) const
+ {
+ TBool retval( EFalse );
+ TPtrC8 datePtr8( aAttrVal.StrF().DesC() );
+ TInt dateLen( datePtr8.Length() );
+ if( dateLen == 0 )
+ {
+ // blank "expires" attribute evaluate as not expired
+ // additional check is done in Persistent() function
+ return EFalse;
+ }
+ HBufC8* temp1 = HBufC8::NewLC( dateLen );
+ TPtr8 temp1Des( temp1->Des() );
+ temp1Des.Copy( datePtr8 );
+ HBufC8* temp2;
+ HBufC8 *desDate;
+
+ // ascii time format
+ // asctime-date = wkday SP date3 SP time SP 4DIGIT
+ // date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
+ TBool asciiTime = EFalse;
+
+ if(KErrNotFound == temp1->Locate( KDayOfWeekSeparator ))
+ {
+ asciiTime=ETrue;
+ }
+
+ if(asciiTime)
+ {
+ temp2 = HBufC8::NewLC( temp1->Length() );
+ temp2 = temp1;
+ }
+ else
+ {
+ temp2 = GetCleanedDateTimeLC( temp1 );
+ }
+
+ TInt cleanupNum( 2 ); // temp1, temp2
+ TPtr8 temp2Des( temp2->Des() );
+ temp2Des.Trim();
+
+ TDateTime tempDate( 1997, EJanuary, 1, 0, 0, 0, 0 );
+ TLex8 lex;
+ TInt error( KErrNone );
+ TInt tempInt;
+ TInt sepPos[4];
+
+ // date string is formatted as: "DD-Mon-YYYY HH:MM:SS"
+ // and must be evaluated as a GMT time
+
+ // parsing Date
+ // find token's position
+ TInt token = FindTokens( temp2Des, KLocalSeparators, asciiTime?KAsciiTokenCount:KDateTokenCount, sepPos );
+
+ if( token < (asciiTime?KAsciiTokenCount:KDateTokenCount -1) )
+ {
+ CleanupStack::PopAndDestroy( cleanupNum ); // temp1, temp2
+ return ETrue;
+ }
+
+ if(!asciiTime)
+ {
+ if( token == KDateTokenCount - 1 ) // if no Time is specified
+ {
+ sepPos[2] = temp2Des.Length();
+ }
+ }
+
+ // initizalize Date
+
+ if(asciiTime)
+ {
+ desDate=temp2Des.AllocLC();
+ }
+ else
+ {
+ desDate = temp2Des.Left( sepPos[2] ).AllocLC();
+ }
+
+ cleanupNum++; // temp1, temp2, desDate
+ desDate->Des().Trim();
+
+ // day
+ if(asciiTime)
+ {
+ lex = desDate->Des().Mid( sepPos[1]+1,sepPos[2]- sepPos[1] - 1);
+ }
+ else
+ {
+ lex = desDate->Des().Left( sepPos[0] );
+ }
+
+ error += lex.Val( tempInt );
+ error += tempDate.SetDay( tempInt - 1 ); // day's offset is 0!
+
+ // year
+ if(asciiTime)
+ {
+ lex = desDate->Des().Right( desDate->Length() - sepPos[3] - 1 );
+ }
+ else
+ {
+ lex = desDate->Des().Right( desDate->Length() - sepPos[1] - 1 );
+ }
+ error += lex.Val( tempInt );
+ if(tempInt < 100) // make sure it has four digit length
+ {
+ tempInt += 2000;
+ }
+ error += tempDate.SetYear( tempInt );
+
+ // month
+ TPtrC8 monthPtr = desDate->Des().Mid( sepPos[0] + 1, sepPos[1] - sepPos[0] - 1 );
+ TPtrC8 monthNamesPtr( KLocalMonthNames );
+ TInt monthNum = monthNamesPtr.Find( monthPtr );
+ if( monthNum == KErrNotFound )
+ {
+ // probably using digits for month rather than its English name
+ lex = monthPtr;
+ error += lex.Val( monthNum );
+ monthNum--; // month's offset is 0!
+ if ( (monthNum < 0) || (monthNum > 11) )
+ // invalid month, cookie must be removed
+ {
+ CleanupStack::PopAndDestroy( cleanupNum ); // temp1, temp2, desDate
+ return ETrue;
+ }
+ }
+ // now we have a position for month's English name
+ else if( (monthNum % 4 ) != 0 )
+ // something strange happened, cookie must be removed
+ {
+ CleanupStack::PopAndDestroy( cleanupNum ); // temp1, temp2, desDate
+ return ETrue;
+ }
+ else
+ {
+ // divide by 4 to convert from index into month's English name to month number, zero relative
+ monthNum >>= 2;
+ }
+ error += tempDate.SetMonth( TMonth( monthNum ) ); // month's offset is 0!
+
+ // parsing Time
+ if( (sepPos[2] != temp2Des.Length()) && // Time is present
+ (error == KErrNone) ) // and no error yet
+ {
+ HBufC8 *desTime;
+ // initialize Time
+ if(asciiTime)
+ {
+ desTime=temp2Des.Mid( sepPos[2] + 1, sepPos[3] - sepPos[2] - 1 ).AllocLC();
+ }
+ else
+ {
+ desTime = temp2Des.Right( temp2Des.Length() - sepPos[2] - 1 ).AllocLC();
+ }
+ cleanupNum++; // 4
+ desTime->Des().Trim();
+
+ token = FindTokens( desTime->Des(), KLocalTimeSeparator, KTimeTokenCount, sepPos );
+ if(token >= KTimeTokenCount - 1) // 2, 3 tokens found
+ {
+ // hour
+ lex = desTime->Des().Left( sepPos[0] );
+ error += lex.Val( tempInt );
+ error += tempDate.SetHour( tempInt );
+
+ // second
+ lex = desTime->Des().Right( desTime->Length() - sepPos[1] - 1 );
+ error += lex.Val( tempInt );
+ error += tempDate.SetSecond( tempInt );
+
+ // minute
+ lex = desTime->Des().Mid( sepPos[0] + 1, sepPos[1] - sepPos[0] - 1 );
+ error += lex.Val( tempInt );
+ error += tempDate.SetMinute( tempInt );
+ }
+ }
+
+ // is parsing OK?
+ if( error == KErrNone )
+ {
+ TTime expiryTime( tempDate );
+ THTTPHdrVal aAttributeVal;
+ TCookieAttribute attribute;
+ TDateTime ResponseDate;
+ if ( FindAttribute( EDate, attribute ) != KErrNotFound )
+ {
+ aAttributeVal = attribute.Value();
+ ResponseDate=aAttributeVal.DateTime();
+ }
+ TTime RespTime(ResponseDate);
+ TTimeIntervalMicroSeconds diffMsec=expiryTime.MicroSecondsFrom(RespTime);
+ TTime nowTime;
+ nowTime.UniversalTime();
+// TDateTime temptime2;
+ TTime newexpiryTime = iReceivedTime + diffMsec;
+// temptime2 = nowTime.DateTime();
+ if( newexpiryTime <= nowTime )
+ { // EXPIRED !!!!
+ retval = ETrue;
+ }
+ }
+ else // invalid Date is expired!
+ {
+ retval = ETrue;
+ }
+ CleanupStack::PopAndDestroy( cleanupNum ); // temp1, temp2, desDate, desTime
+ return retval;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::FindTokens
+// ---------------------------------------------------------
+//
+TInt CCookie::FindTokens( const TDesC8& aString,
+ const TDesC8& aTokenSeparators,
+ const TInt aTokenCount,
+ TInt* aTokens ) const
+ {
+ TLex8 lex = aString;
+ TChar ch;
+ TInt tokenCount( 0 ), ii;
+ for(ii=0; ii<aTokenCount; aTokens[ii++] = KErrNotFound) ;
+
+ while( !( (tokenCount==aTokenCount) || lex.Eos() ) )
+ {
+ ch = lex.Get();
+ if( aTokenSeparators.Locate( ch ) != KErrNotFound )
+ {
+ aTokens[tokenCount++] = lex.Offset()-1;
+ }
+ }
+ return tokenCount;
+ }
+
+// ---------------------------------------------------------
+// CCookie::Persistent
+// ---------------------------------------------------------
+//
+TBool CCookie::Persistent() const
+ {
+ TBool result( EFalse );
+ THTTPHdrVal attrVal;
+
+ if ( FromNetscapeVersion() )
+ {
+ if ( Attribute( CCookie::EExpires, attrVal ) == KErrNone )
+ {
+ // blank "expires" attribute evaluate as expired.
+ // check only for string type attribute
+ if ( attrVal.Type() == THTTPHdrVal::KStrFVal )
+ {
+ if( attrVal.StrF().DesC().Length() > 0 )
+ {
+ result = ETrue;
+ }
+ }
+ else
+ {
+ result = ETrue;
+ }
+ }
+ }
+ else
+ {
+ if ( Attribute( CCookie::EDiscard, attrVal ) == KErrNotFound )
+ {
+ if ( Attribute( CCookie::EMaxAge, attrVal ) == KErrNone )
+ { // has max age, to be stored until it expires...
+ // check if MaxAge is 0, in that case, discard immediatelly.
+ TInt MaxAge(0);
+ if ( attrVal.Type() == THTTPHdrVal::KTIntVal )
+ {
+ MaxAge = attrVal.Int();
+ }
+ else
+ {
+ TPtrC8 MaxAgePtr( attrVal.StrF().DesC() );
+ TLex8 lex( MaxAgePtr );
+ lex.Val( MaxAge );
+ }
+ if ( MaxAge > 0)
+ {
+ result = ETrue;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+// ---------------------------------------------------------
+// CCookie::IsUnknownVersion
+// ---------------------------------------------------------
+//
+TBool CCookie::IsUnknownVersion() const
+ {
+ TBool unknownVersion( EFalse );
+ THTTPHdrVal attrVal;
+ if( Attribute( CCookie::EVersion, attrVal ) != KErrNotFound )
+ {
+ if( attrVal.StrF().DesC().Compare( KCookieKnownVersion() ) != 0 )
+ {
+ unknownVersion = ETrue;
+ }
+ }
+ return unknownVersion;
+ }
+
+// ---------------------------------------------------------
+// CCookie::CCookie
+// ---------------------------------------------------------
+//
+CCookie::CCookie( RStringPool aStringPool )
+: iStringPool( aStringPool ), iSetCookie2( EFalse ), iNetscape( EFalse )
+ {
+ iReceivedTime.UniversalTime();
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::ConstructL
+// ---------------------------------------------------------
+//
+void CCookie::ConstructL( RHTTPHeaders aRequestHeaders, TInt aPartIndex,
+ RStringF aFieldName, const TUriC8& aUri )
+ {
+ const TStringTable& commonStringTable = RHTTPSession::GetTable();
+
+ // Determining if this object is constructed from a Set-Cookie2 HTTP header
+ RStringF setCookie2Name = iStringPool.StringF( HTTP::ESetCookie2,
+ commonStringTable );
+
+ iSetCookie2 = ( aFieldName == setCookie2Name );
+
+ TBool DefaultDiscard( EFalse );
+
+ THTTPHdrVal hVal;
+
+ // Retrieval of NAME attribute
+ // ---------------------------------------------------------
+ // retrieving Name atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::ECookieName,
+ commonStringTable ),
+ hVal,
+ aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EName, hVal ); // ignore the result of this method
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Value atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::ECookieValue,
+ commonStringTable ),
+ hVal,
+ aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EValue, hVal ); // ignore the result of this method
+ }
+
+ // now get the VERSION attribute.
+ // if it is there, then it is either RFC 2109 or RFC 2965
+ // if it is not there, then it is NETSCAPE style cookie
+ // ---------------------------------------------------------
+ // retrieving Version atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EVersion,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ iNetscape = EFalse;
+ SetAttribute( EVersion, hVal ); // ignore the result of this method
+ }
+ else
+ {
+ iNetscape = ETrue;
+ }
+
+ // now get common attributes for all
+ // that is, Path, Domain, Secure
+ // Add Path attribute if it exists + defaulting
+ // ---------------------------------------------------------
+ // retrieving Path atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EPath,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EPath, hVal ); // ignore the result of this method
+ }
+ else
+ {
+ // defaulting
+ AddDefaultPathL( aUri );
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Domain atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EDomain,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone && hVal.StrF().DesC().Length() > 0)
+ {
+ SetAttribute( EDomain, hVal ); // ignore the result of this method
+ }
+ else
+ { // Default handling
+ // in this case the default is the effective request host
+ RStringF defDomain =
+ iStringPool.OpenFStringL( aUri.Extract( EUriHost ) );
+ THTTPHdrVal defdomVal( defDomain );
+ SetAttribute( EDomain, defdomVal, ETrue );// ignore the result
+ defDomain.Close();
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Secure atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::ESecure,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( ESecure, hVal ); // ignore the result of this method
+ }
+ else
+ { // Default handling if applies
+ // if not present, then cookie is not 'secure'
+ // no action here as if attribute is not present,
+ // cookie might be sended by default.
+ }
+
+
+ // now if it is Netscape, get Netscape specific parts
+ if ( iNetscape )
+ {
+ // that is, Expires
+ // ---------------------------------------------------------
+ // retrieving Expires atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EExpires,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EExpires, hVal ); // ignore the result of this method
+ }
+ //-----------------------------------------------------------
+ // Default handling is does not applies.
+ // Reference: error ID:ESAN-6XWHRL
+ // If "version" is not present but "max-age/comment" is present
+ // then we can considere cookie as RFC 2109 or RFC 2965 type
+ else if(( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::EComment,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone ) ||
+ ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::EMaxAge,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone ))
+ {
+ // Not a NETSCAPE style cookie
+ iNetscape = EFalse;
+ }
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Date atribute
+ // ---------------------------------------------------------
+ // get the Date header field name
+ RStringF dateFieldName = iStringPool.StringF( HTTP::EDate,
+ commonStringTable );
+ if ( aRequestHeaders.GetField( dateFieldName, 0, hVal) == KErrNone )
+
+ {
+ SetAttribute( EDate, hVal ); // ignore the result of this method
+ }
+ else
+
+ // as the expiration comparison is based on the UniversalTime,
+ // we use the curreent (arriving time) for the cookie's born time too. :-)
+ { // Add default handling if applies
+ TTime nowTime;
+ nowTime.UniversalTime();
+ // TDateTime dateTime( nowTime.DateTime() );
+ hVal.SetDateTime( nowTime.DateTime() );
+ SetAttribute( EDate, hVal );
+ }
+ if( EFalse == iNetscape )
+ {
+ // now get RFC SetCookie and SetCookie2 common parts
+ // that is, Comment, Max-Age
+ // get EDate to be able to calculate cookie age if needed.
+ // ---------------------------------------------------------
+ // retrieving Comment atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::EComment,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EComment, hVal ); // ignore the result of this method
+ }
+ else
+ { // Add default handling if applies
+ // no defaulting for EComment
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Max-Age atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EMaxAge,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EMaxAge, hVal ); // ignore the result of this method
+ }
+ else
+ { // Add default handling if applies
+ // Defaults to Discard, discard the cookie on agent termination
+ // -> transient cookie
+ // in case of SetCookie2, also set Discard, defaulted
+ if ( iSetCookie2 )
+ {
+ DefaultDiscard = ETrue;
+ }
+ }
+
+ // now if it is SetCookie2, than get SetCookie2 specific parts
+ if ( iSetCookie2 )
+ {
+ // that is, CommentUrl, Discard, Port
+ // ---------------------------------------------------------
+ // retrieving CommentURL atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::ECommentURL,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( ECommentURI, hVal ); // ignore the result of this method
+ }
+ else
+ { // Add default handling if applies
+ // no defaulting for ECommentURL
+ }
+
+ // ---------------------------------------------------------
+ // retrieving Discard atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam(
+ aFieldName,
+ iStringPool.StringF( HTTP::EDiscard,
+ commonStringTable ),
+ hVal, aPartIndex ) == KErrNone )
+ {
+ SetAttribute( EDiscard, hVal ); // ignore the result of this method
+ }
+ else
+ { // Add default handling if applies
+ // no defaulting for EDiscard
+ // only if it is caused by MAx-Age beeing not supplied
+ if ( DefaultDiscard )
+ {
+ RStringF emptyStr = iStringPool.OpenFStringL( KNullDesC8() );
+ THTTPHdrVal emptyVal( emptyStr );
+ SetAttribute( EDiscard, emptyVal, ETrue );
+ emptyStr.Close();
+ }
+ }
+
+ // Add Port attribute if it exists + defaulting
+ // ---------------------------------------------------------
+ // retrieving Port atribute
+ // ---------------------------------------------------------
+ if ( aRequestHeaders.GetParam( aFieldName,
+ iStringPool.StringF( HTTP::ECookiePort,
+ commonStringTable ),
+ hVal,
+ aPartIndex ) == KErrNone )
+ {
+ // if it is a string and contains at least 1 character, then store it
+ if ( ( hVal.Type() == THTTPHdrVal::KStrFVal &&
+ hVal.StrF().DesC().Length() ) ||
+ ( hVal.Type() == THTTPHdrVal::KStrVal &&
+ hVal.Str().DesC().Length() ) )
+ {
+ SetAttribute( EPort, hVal, ETrue ); // ignore the result of this method
+ }
+ else // the Port attrib is either empty or incorrect
+ {
+ RStringF requestPort;
+ if ( aUri.IsPresent( EUriPort ) )
+ {
+ requestPort =
+ iStringPool.OpenFStringL( aUri.Extract( EUriPort ) );
+ }
+ else
+ {
+ requestPort = iStringPool.OpenFStringL
+ ( KCookieDefaultRequestPort() );
+ }
+
+ THTTPHdrVal reqPort( requestPort );
+
+ SetAttribute( EPort, reqPort, ETrue ); // ignore the result
+
+ requestPort.Close();
+ }
+ }
+ else
+ {
+ // if the Port attrib does not exist, leave it blank
+ }
+ }
+ }
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::FindAttribute
+// ---------------------------------------------------------
+//
+TInt CCookie::FindAttribute( TCookieAttributeName aAttributeName,
+ TCookieAttribute& aAttribute ) const
+ {
+ const TInt numAttributes = iAttributes.Count();
+ for ( TInt index = 0; index < numAttributes; ++index )
+ {
+ if ( iAttributes[index].Name() == aAttributeName )
+ {
+ aAttribute = iAttributes[index];
+ return index;
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+// ---------------------------------------------------------
+// CCookie::RemoveAttribute
+// ---------------------------------------------------------
+//
+void CCookie::RemoveAttribute( TInt aIndex )
+ {
+ iSize -= ( KCookieAttributePrefixLength + iAttributes[ aIndex ].Size() +
+ KCookieAttributeDefaultedLength +
+ KCookieAttributeFoundLength );
+ iAttributes[ aIndex ].Close();
+ iAttributes.Remove( aIndex );
+ }
+
+// ---------------------------------------------------------
+// CCookie::RemoveAttribute
+// ---------------------------------------------------------
+//
+void CCookie::RemoveAttribute( TCookieAttributeName aAttributeName )
+ {
+ TCookieAttribute attribute;
+ TInt index( FindAttribute( aAttributeName, attribute ) );
+ if( index != KErrNotFound )
+ {
+ RemoveAttribute( index );
+ }
+ }
+
+// ---------------------------------------------------------
+// CCookie::GetLocalOffset
+// ---------------------------------------------------------
+//
+TInt CCookie::GetLocalOffset( HBufC8* aDate, TInt& aHour,
+ TInt& aMinute, TInt& aLength ) const
+ {
+ TInt retval( 0 );
+ TInt pos(0);
+// TInt fwspos(0);
+// TBool plus( ETrue );
+ TPtrC8 datePtr( aDate->Des() );
+
+
+ TLex8 lex( datePtr );
+ TInt oldoffset( 0 );
+ TInt curroffset( 0 );
+ TInt i( 0 );
+ TInt tokencount( 0 );
+ TInt deltaoffset( 0 );
+ // firstoffset is to store the first token length/endposition
+ TInt firstoffset( 0 );
+ TBool repeat( ETrue );
+ do
+ {
+ lex.SkipCharacters();
+ curroffset = lex.Offset();
+ deltaoffset = curroffset-oldoffset;
+ if ( deltaoffset )
+ {
+ if ( !tokencount )
+ {
+ firstoffset = deltaoffset;
+ }
+ for(i=0; i<deltaoffset; i++)
+ {
+ lex.Get();
+ }
+ tokencount++;
+/*
+ if ( deltaoffset != aDate->Length() )
+ {
+ tokencount++;
+ }
+*/
+ oldoffset = curroffset;
+ }
+ else
+ { // end of string, oldoffset1 holds position
+ repeat = EFalse;
+ }
+ }while (repeat);
+
+
+
+ pos = aDate->LocateReverse( KLocalTimeZoneSeparator1 );
+
+ if ( pos > 0 )
+ { // found at least one "+"
+// plus = ETrue;
+ }
+ else
+ {
+ pos = aDate->LocateReverse( KLocalTimeZoneSeparator2 );
+ if ( pos > 0 )
+ { // found at least one "-"
+ // now check if it is in the date...
+ // if it is in the date part, then we did found only one tokens...
+ // and the position MUST be larger than the end of
+ // the first token (date)...
+ if ( ( tokencount > 1) && ( firstoffset < pos ) )
+ {
+// plus = EFalse;
+ }
+ else
+ {
+ pos = KErrNotFound;
+ retval = KErrNotFound;
+ }
+ }
+ else
+ {
+ retval = KErrNotFound;
+ }
+ }
+ if ( pos > 0 )
+ {
+ // get the length
+ aLength = aDate->Length()-pos;
+ // now get the offset
+ HBufC8* temp = aDate->Right( aLength ).AllocLC();
+ temp->Des().Trim();
+ TLex8 lex(temp->Left(2));
+ lex.Val( aHour );
+ TLex8 lex1(temp->Right(2));
+ lex1.Val( aMinute );
+ CleanupStack::PopAndDestroy( temp ); // temp
+ }
+ return retval;
+ }
+
+
+
+
+// ---------------------------------------------------------
+// CCookie::GetMilitaryOffset
+// ---------------------------------------------------------
+//
+TInt CCookie::GetMilitaryOffset( HBufC8* /*aDate*/, TInt& aHour ) const
+ {
+ // TODO: Add military timezone handling here...
+ TInt retval( KErrNotFound );
+ aHour = 0;
+ return retval;
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::GetTimeZone
+// ---------------------------------------------------------
+//
+TInt CCookie::GetTimeZone( HBufC8* aDate, TInt& aHour,
+ TInt& aLength ) const
+ {
+ TInt retval( 0 );
+ TInt zonepos = aDate->Find( KUT() );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = 0;
+ }
+ else
+ {
+ zonepos = aDate->Find( KGMT );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = 0;
+ }
+ else
+ {
+ zonepos = aDate->Find( KEST );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -5;
+ }
+ else
+ {
+ zonepos = aDate->Find( KEDT );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -4;
+ }
+ else
+ {
+ zonepos = aDate->Find( KCST );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -6;
+ }
+ else
+ {
+ zonepos = aDate->Find( KCDT );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -5;
+ }
+ else
+ {
+ zonepos = aDate->Find( KMST );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -7;
+ }
+ else
+ {
+ zonepos = aDate->Find( KMDT );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -6;
+ }
+ else
+ {
+ zonepos = aDate->Find( KPST );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -8;
+ }
+ else
+ {
+ zonepos = aDate->Find( KPDT );
+ if ( zonepos != KErrNotFound )
+ {
+ aHour = -7;
+ }
+ else
+ {
+ retval = KErrNotFound;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( zonepos != KErrNotFound )
+ {
+ // get the length
+ aLength = aDate->Length() - zonepos;
+ }
+
+ return retval;
+ }
+
+
+
+// ---------------------------------------------------------
+// CCookie::GetCleanedDateTimeLC
+// ---------------------------------------------------------
+//
+HBufC8* CCookie::GetCleanedDateTimeLC( HBufC8* aDate ) const
+ {
+ // as http time might contain a "DayOfWeek," optional part
+ // which is not understood by the parser, we need to
+ // remove it
+ TInt pos = aDate->Locate( KDayOfWeekSeparator );
+ if ( pos < 0 )
+ {
+ pos = 0;
+ }
+ else
+ {
+ if ( pos )
+ {
+ pos++;
+ }
+ }
+
+ HBufC8* result = HBufC8::NewLC( aDate->Length() );
+ HBufC8* temp = aDate->Mid( pos ).AllocLC();
+ // reduce multiple spaces
+ temp->Des().TrimAll();
+
+ // now try to remove time zone values...
+ TInt hour( 0 );
+ TInt minute( 0 );
+ TInt length( 0 );
+
+ // Accordign to RFC 2822, the correct date-time syntax:
+ // [dayofweek","] date FWS time [CFWS]
+ // where:
+ // date : day month year
+ // time : time-of-day FWS zone
+ //
+ // zone : (( "+" / "-" ) 4DIGIT) / obs-zone
+ // obs-zone : "GMT", "UT", "EST", "EDT", "CST", "CDT",
+ // "MST", "MDT", "PST", "PDT"
+ // and the military 1 letter version
+ // so first try to get the +/-hhmm format...
+ // check if time is locale offset in +/- HHMM form
+ if ( GetLocalOffset( temp, hour, minute, length ) == KErrNotFound )
+ {
+ // not a local offset, check if it is one of the
+ // known 2 or three digit ones
+ if ( GetTimeZone( temp, hour, length ) == KErrNotFound )
+ {
+ //Not, check if it is Military,
+ //which is a one digit ALPHA
+ if ( GetMilitaryOffset( temp, hour ) == KErrNotFound )
+ {
+ // not a military one,
+ // error, unknown time zone or none...
+ }
+ else
+ { // Military offset
+ length = 1;
+ }
+ }
+ else
+ {// other know one
+ }
+ }
+ else
+ { // locale offset
+ }
+ *result = temp->Left( temp->Length() - length);
+ // return ( temp->Left( temp->Length() - length).AllocLC() );
+ CleanupStack::PopAndDestroy( temp );
+ return result;
+ }
+
+
+
+
+
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::TCookieAttribute
+// ---------------------------------------------------------
+//
+CCookie::TCookieAttribute::TCookieAttribute( TCookieAttributeName aName,
+ const THTTPHdrVal& aHdrVal,
+ TBool aDefaulted )
+: iName( aName ),
+iDefaulted( aDefaulted )
+ {
+ iValue = aHdrVal.Copy();
+
+
+ switch ( iValue.Type() )
+ {
+ case THTTPHdrVal::KTIntVal :
+ {
+ iSize = sizeof( TInt );
+ break;
+ }
+ case THTTPHdrVal::KStrVal :
+ {
+ iSize = iValue.Str().DesC().Length();
+ break;
+ }
+ case THTTPHdrVal::KDateVal :
+ {
+ iSize = sizeof( TDateTime );
+ break;
+ }
+ case THTTPHdrVal::KStrFVal :
+ {
+ iSize = iValue.StrF().DesC().Length();
+ break;
+ }
+ default : // THTTPHdrVal::KNoType
+ {
+ iSize = 0;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::TCookieAttribute
+// ---------------------------------------------------------
+//
+CCookie::TCookieAttribute::TCookieAttribute()
+ {
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::Close
+// ---------------------------------------------------------
+//
+void CCookie::TCookieAttribute::Close()
+ {
+ THTTPHdrVal::THTTPValType type = iValue.Type();
+ if ( type == THTTPHdrVal::KStrVal )
+ {
+ iValue.Str().Close();
+ }
+ else if ( type == THTTPHdrVal::KStrFVal )
+ {
+ iValue.StrF().Close();
+ }
+
+ // TBD : iValue = THTTPHdrVal();?
+ iSize = 0;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::Name
+// ---------------------------------------------------------
+//
+CCookie::TCookieAttributeName CCookie::TCookieAttribute::Name() const
+ {
+ return iName;
+ }
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::Size
+// ---------------------------------------------------------
+//
+TInt CCookie::TCookieAttribute::Size() const
+ {
+ return iSize;
+ }
+
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::Defaulted
+// ---------------------------------------------------------
+//
+TBool CCookie::TCookieAttribute::Defaulted() const
+ {
+ return iDefaulted;
+ }
+
+// ---------------------------------------------------------
+// CCookie::TCookieAttribute::Value
+// ---------------------------------------------------------
+//
+const THTTPHdrVal& CCookie::TCookieAttribute::Value() const
+ {
+ return iValue;
+ }
+
+
+