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