1 //
2 // HtCookieJar.cc
3 //
4 // HtCookieJar: This class stores/retrieves cookies.
5 //
6 // by Robert La Ferla. Started 12/9/2000.
7 // Reviewed by G.Bartolini - since 24 Feb 2001
8 //
9 ////////////////////////////////////////////////////////////
10 //
11 // The HtCookieJar class stores/retrieves cookies.
12 // It's an abstract class though, which has to be the interface
13 // for HtHTTP class.
14 //
15 //
16 // See "PERSISTENT CLIENT STATE HTTP COOKIES" Specification
17 // at http://www.netscape.com/newsref/std/cookie_spec.html
18 // Modified according to RFC2109 (max age and version attributes)
19 //
20 ///////
21 //
22 // Part of the ht://Dig package <http://www.htdig.org/>
23 // Part of the ht://Check package <http://htcheck.sourceforge.net/>
24 // Copyright (c) 2001-2004 The ht://Dig Group
25 // For copyright details, see the file COPYING in your distribution
26 // or the GNU Library General Public License (LGPL) version 2 or later
27 // <http://www.gnu.org/copyleft/lgpl.html>
28 //
29 // $Id: HtCookieJar.cc,v 1.6 2004/05/28 13:15:23 lha Exp $
30 //
31
32 #include "HtCookieJar.h"
33
34 ///////
35 // Static variables initialization
36 ///////
37
38 // Debug level
39 int HtCookieJar::debug = 0;
40
41 ///////
42 // Writes the HTTP request line given a cookie
43 // in a flexible way (chooses between the RFC2109
44 // and the specification given by Netscape)
45 ///////
46 //
47 // RFC2109: The syntax for the header is:
48 // cookie = "Cookie:" cookie-version
49 // 1*((";" | ",") cookie-value)
50 // cookie-value = NAME "=" VALUE [";" path] [";" domain]
51 // cookie-version = "$Version" "=" value
52 // NAME = attr
53 // VALUE = value
54 // path = "$Path" "=" value
55 // domain = "$Domain" "=" value
56 //
57
58
WriteCookieHTTPRequest(const HtCookie & Cookie,String & RequestString,const int & NumCookies)59 int HtCookieJar::WriteCookieHTTPRequest(const HtCookie &Cookie,
60 String &RequestString, const int &NumCookies)
61 {
62
63 switch (Cookie.GetVersion())
64 {
65 // RFC2109 Version
66 case 1:
67 // Writes the string to be sent to the web server
68 if (NumCookies == 1)
69 RequestString << "Cookie: $Version=\"1\"; ";
70 else
71 RequestString << "; " ;
72
73 // Print complete debug info
74 if (debug > 6)
75 {
76 cout << "Cookie (RFC2109) info: NAME=" << Cookie.GetName()
77 << " VALUE="<< Cookie.GetValue()
78 << " PATH=" << Cookie.GetPath();
79
80 if (Cookie.GetExpires())
81 cout << " EXPIRES=" << Cookie.GetExpires()->GetRFC850();
82
83 cout << endl;
84 }
85
86 // Prepare cookie line for HTTP protocol
87 RequestString << Cookie.GetName() << "=" << Cookie.GetValue();
88
89 if (Cookie.GetPath().length() > 0)
90 RequestString << " ;$Path=" << Cookie.GetPath();
91
92 if (Cookie.GetDomain().length() > 0)
93 RequestString << " ;$Domain=" << Cookie.GetDomain();
94 break;
95
96 // Netscape specification
97 case 0:
98 // Writes the string to be sent to the web server
99 if (NumCookies == 1)
100 RequestString << "Cookie: ";
101 else
102 RequestString << "; " ;
103
104 // Print complete debug info
105 if (debug > 6)
106 {
107 cout << "Cookie (Netscape spec) info: NAME=" << Cookie.GetName()
108 << " VALUE=" << Cookie.GetValue()
109 << " PATH=" << Cookie.GetPath();
110
111 if (Cookie.GetExpires())
112 cout << " EXPIRES=" << Cookie.GetExpires()->GetRFC850();
113
114 cout << endl;
115 }
116
117 // Prepare cookie line for HTTP protocol
118 RequestString << Cookie.GetName() << "=" << Cookie.GetValue();
119
120 break;
121 }
122
123 return true;
124
125 }
126
127
GetDomainMinNumberOfPeriods(const String & domain) const128 int HtCookieJar::GetDomainMinNumberOfPeriods(const String& domain) const
129 {
130 // Well ... if a domain has been specified, we need some check-ups
131 // as the standard says.
132 static char* TopLevelDomains[] = { "com", "edu", "net", "org",
133 "gov", "mil", "int", 0};
134
135 const char* s = strrchr(domain.get(), '.');
136
137 if (!s) // no 'dot' has been found. Not valid
138 return 0;
139
140 if (! *(++s)) // nothing after the dot. Not Valid
141 return 0;
142
143 for (char** p = TopLevelDomains; *p; ++p)
144 {
145 if (!strncmp(*p, s, strlen(*p)))
146 return 2;
147 }
148
149 return 3; // By default the minimum value
150 }
151