//
// HtCookieJar.cc
//
// HtCookieJar: This class stores/retrieves cookies.
//
// by Robert La Ferla. Started 12/9/2000.
// Reviewed by G.Bartolini - since 24 Feb 2001
//
////////////////////////////////////////////////////////////
//
// The HtCookieJar class stores/retrieves cookies.
// It's an abstract class though, which has to be the interface
// for HtHTTP class.
//
//
// See "PERSISTENT CLIENT STATE HTTP COOKIES" Specification
// at http://www.netscape.com/newsref/std/cookie_spec.html
// Modified according to RFC2109 (max age and version attributes)
//
///////
//
// Part of the ht://Dig package
// Part of the ht://Check package
// Copyright (c) 2001-2004 The ht://Dig Group
// For copyright details, see the file COPYING in your distribution
// or the GNU Library General Public License (LGPL) version 2 or later
//
//
// $Id: HtCookieJar.cc,v 1.6 2004/05/28 13:15:23 lha Exp $
//
#include "HtCookieJar.h"
///////
// Static variables initialization
///////
// Debug level
int HtCookieJar::debug = 0;
///////
// Writes the HTTP request line given a cookie
// in a flexible way (chooses between the RFC2109
// and the specification given by Netscape)
///////
//
// RFC2109: The syntax for the header is:
// cookie = "Cookie:" cookie-version
// 1*((";" | ",") cookie-value)
// cookie-value = NAME "=" VALUE [";" path] [";" domain]
// cookie-version = "$Version" "=" value
// NAME = attr
// VALUE = value
// path = "$Path" "=" value
// domain = "$Domain" "=" value
//
int HtCookieJar::WriteCookieHTTPRequest(const HtCookie &Cookie,
String &RequestString, const int &NumCookies)
{
switch (Cookie.GetVersion())
{
// RFC2109 Version
case 1:
// Writes the string to be sent to the web server
if (NumCookies == 1)
RequestString << "Cookie: $Version=\"1\"; ";
else
RequestString << "; " ;
// Print complete debug info
if (debug > 6)
{
cout << "Cookie (RFC2109) info: NAME=" << Cookie.GetName()
<< " VALUE="<< Cookie.GetValue()
<< " PATH=" << Cookie.GetPath();
if (Cookie.GetExpires())
cout << " EXPIRES=" << Cookie.GetExpires()->GetRFC850();
cout << endl;
}
// Prepare cookie line for HTTP protocol
RequestString << Cookie.GetName() << "=" << Cookie.GetValue();
if (Cookie.GetPath().length() > 0)
RequestString << " ;$Path=" << Cookie.GetPath();
if (Cookie.GetDomain().length() > 0)
RequestString << " ;$Domain=" << Cookie.GetDomain();
break;
// Netscape specification
case 0:
// Writes the string to be sent to the web server
if (NumCookies == 1)
RequestString << "Cookie: ";
else
RequestString << "; " ;
// Print complete debug info
if (debug > 6)
{
cout << "Cookie (Netscape spec) info: NAME=" << Cookie.GetName()
<< " VALUE=" << Cookie.GetValue()
<< " PATH=" << Cookie.GetPath();
if (Cookie.GetExpires())
cout << " EXPIRES=" << Cookie.GetExpires()->GetRFC850();
cout << endl;
}
// Prepare cookie line for HTTP protocol
RequestString << Cookie.GetName() << "=" << Cookie.GetValue();
break;
}
return true;
}
int HtCookieJar::GetDomainMinNumberOfPeriods(const String& domain) const
{
// Well ... if a domain has been specified, we need some check-ups
// as the standard says.
static char* TopLevelDomains[] = { "com", "edu", "net", "org",
"gov", "mil", "int", 0};
const char* s = strrchr(domain.get(), '.');
if (!s) // no 'dot' has been found. Not valid
return 0;
if (! *(++s)) // nothing after the dot. Not Valid
return 0;
for (char** p = TopLevelDomains; *p; ++p)
{
if (!strncmp(*p, s, strlen(*p)))
return 2;
}
return 3; // By default the minimum value
}