summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2005-07-19 13:08:58 (UTC)
committer Michael Krelin <hacker@klever.net>2005-07-19 13:08:58 (UTC)
commitdb69589bdc32c60b1fce6700a35d4126058bf7bc (patch) (unidiff)
tree34727675eaeb4210436a9b61119c7484dbc0cd97
parent9cc67ea5af191d5bc1f26506c35d8387a05361c2 (diff)
downloadkingate-db69589bdc32c60b1fce6700a35d4126058bf7bc.zip
kingate-db69589bdc32c60b1fce6700a35d4126058bf7bc.tar.gz
kingate-db69589bdc32c60b1fce6700a35d4126058bf7bc.tar.bz2
turned cookies into multimap
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/kingate/cgi_gateway.h1
-rw-r--r--include/kingate/cookies.h4
-rw-r--r--src/cookies.cc7
3 files changed, 7 insertions, 5 deletions
diff --git a/include/kingate/cgi_gateway.h b/include/kingate/cgi_gateway.h
index a26b0ae..087f7d0 100644
--- a/include/kingate/cgi_gateway.h
+++ b/include/kingate/cgi_gateway.h
@@ -118,208 +118,207 @@ namespace kingate {
118 */ 118 */
119 istream& in() { return iface.in(); } 119 istream& in() { return iface.in(); }
120 /** 120 /**
121 * fetch reference to the 'stdout' stream. 121 * fetch reference to the 'stdout' stream.
122 * @return the reference to the corresponding ostream object. 122 * @return the reference to the corresponding ostream object.
123 * @see cgi_interface::out() 123 * @see cgi_interface::out()
124 */ 124 */
125 ostream& out() { return iface.out(); } 125 ostream& out() { return iface.out(); }
126 /** 126 /**
127 * fetch reference to the 'stderr' stream. 127 * fetch reference to the 'stderr' stream.
128 * @return the reference to the corresponding ostream object. 128 * @return the reference to the corresponding ostream object.
129 * @see cgi_interface::err() 129 * @see cgi_interface::err()
130 */ 130 */
131 ostream& err() { return iface.err(); } 131 ostream& err() { return iface.err(); }
132 /** 132 /**
133 * cast to the ostream -- fetches the reference to the 'stdout' 133 * cast to the ostream -- fetches the reference to the 'stdout'
134 * stream. 134 * stream.
135 * @see out() 135 * @see out()
136 */ 136 */
137 operator ostream& (void) { return out(); } 137 operator ostream& (void) { return out(); }
138 138
139 /** 139 /**
140 * Check to see whether the parameter was passed via GET. 140 * Check to see whether the parameter was passed via GET.
141 * @param n the parameter name. 141 * @param n the parameter name.
142 * @return true if yes. 142 * @return true if yes.
143 */ 143 */
144 bool has_GET(const string& n) const; 144 bool has_GET(const string& n) const;
145 /** 145 /**
146 * Retrieve the parameter passed via GET. 146 * Retrieve the parameter passed via GET.
147 * @param n the parameter name. 147 * @param n the parameter name.
148 * @return the parameter contents. 148 * @return the parameter contents.
149 * @see exception_notfound 149 * @see exception_notfound
150 */ 150 */
151 const string& get_GET(const string& n) const; 151 const string& get_GET(const string& n) const;
152 /** 152 /**
153 * Check to see whether the parameter was passed via POST. 153 * Check to see whether the parameter was passed via POST.
154 * @param n the parameter name. 154 * @param n the parameter name.
155 * @return true if yes. 155 * @return true if yes.
156 */ 156 */
157 bool has_POST(const string& n) const; 157 bool has_POST(const string& n) const;
158 /** 158 /**
159 * Retrieve the POST-parameter. 159 * Retrieve the POST-parameter.
160 * @param n the parameter name. 160 * @param n the parameter name.
161 * @return the parameter contents. 161 * @return the parameter contents.
162 * @see exception_notfound 162 * @see exception_notfound
163 */ 163 */
164 const string& get_POST(const string& n) const; 164 const string& get_POST(const string& n) const;
165 /** 165 /**
166 * Check to see whether the parameter was passed either via POST or 166 * Check to see whether the parameter was passed either via POST or
167 * GET. 167 * GET.
168 * @param n the parameter name. 168 * @param n the parameter name.
169 * @return true if yes. 169 * @return true if yes.
170 */ 170 */
171 bool has_param(const string& n) const; 171 bool has_param(const string& n) const;
172 /** 172 /**
173 * Retrieve the parameter passed either via POST or GET 173 * Retrieve the parameter passed either via POST or GET
174 * (GET-parameter takes precedence). 174 * (GET-parameter takes precedence).
175 * @param n the parameter name. 175 * @param n the parameter name.
176 * @return the parameter contents. 176 * @return the parameter contents.
177 * @see exception_notfound. 177 * @see exception_notfound.
178 */ 178 */
179 const string& get_param(const string& n) const; 179 const string& get_param(const string& n) const;
180 /** 180 /**
181 * Check to see whether the file was uploaded in the request body. 181 * Check to see whether the file was uploaded in the request body.
182 * @param n the parameter name. 182 * @param n the parameter name.
183 * @return true if yes. 183 * @return true if yes.
184 */ 184 */
185 bool has_file(const string& n) const; 185 bool has_file(const string& n) const;
186 /** 186 /**
187 * Retrieve the file uploaded in the request body. 187 * Retrieve the file uploaded in the request body.
188 * @param n the parameter name. 188 * @param n the parameter name.
189 * @return the file. 189 * @return the file.
190 * @see exception_notfound. 190 * @see exception_notfound.
191 */ 191 */
192 const file_t get_file(const string& n) const; 192 const file_t get_file(const string& n) const;
193 file_t get_file(const string& n); 193 file_t get_file(const string& n);
194 194
195 /** 195 /**
196 * Retrieve the POST content-type (as passed via CONTENT_TYPE 196 * Retrieve the POST content-type (as passed via CONTENT_TYPE
197 * environment variable). 197 * environment variable).
198 * @return the content type. 198 * @return the content type.
199 */ 199 */
200 const string& __deprecated get_content_type() const; 200 const string& __deprecated get_content_type() const;
201 /** 201 /**
202 * Retrieve the POST content length (as passed via the 202 * Retrieve the POST content length (as passed via the
203 * CONTENT_LENGTH environment variable). 203 * CONTENT_LENGTH environment variable).
204 * @return the content length. 204 * @return the content length.
205 */ 205 */
206 unsigned long __deprecated get_content_length() const; 206 unsigned long __deprecated get_content_length() const;
207 207
208 /** 208 /**
209 * Check to see whether the content from stdin stream was parsed. 209 * Check to see whether the content from stdin stream was parsed.
210 * @return true if yes. 210 * @return true if yes.
211 */ 211 */
212 bool is_content_parsed() const { return b_parsed_content; } 212 bool is_content_parsed() const { return b_parsed_content; }
213 213
214 /** 214 /**
215 * Retrieve the HTTP header value from the HTTP_ meta-variable. 215 * Retrieve the HTTP header value from the HTTP_ meta-variable.
216 * (see RFC3875) 216 * (see RFC3875)
217 * @param hn header field name. 217 * @param hn header field name.
218 * @return the HTTP header value. 218 * @return the HTTP header value.
219 */ 219 */
220 const string& http_request_header(const string& hn) const; 220 const string& http_request_header(const string& hn) const;
221 221
222 /** 222 /**
223 * Retrieve the AUTH_TYPE meta-variable (see RFC3875) 223 * Retrieve the AUTH_TYPE meta-variable (see RFC3875)
224 * @return authentication type. 224 * @return authentication type.
225 */ 225 */
226 const string& auth_type() const; 226 const string& auth_type() const;
227 /** 227 /**
228 * Retrieve the CONTENT_LENGTH meta-variable (see RFC3875) 228 * Retrieve the CONTENT_LENGTH meta-variable (see RFC3875)
229 * @return size of the request message body. 229 * @return size of the request message body.
230 */ 230 */
231 unsigned long content_length() const; 231 unsigned long content_length() const;
232 /** 232 /**
233 * Retrieve the CONTENT_TYPE meta-variable (see RFC3875) 233 * Retrieve the CONTENT_TYPE meta-variable (see RFC3875)
234 * @return media type of the request message body. 234 * @return media type of the request message body.
235 */ 235 */
236 const string& content_type() const; 236 const string& content_type() const;
237 /** 237 /**
238 * Retrieve the GATEWAY_INTERFACE meta-variable (see RFC3875) 238 * Retrieve the GATEWAY_INTERFACE meta-variable (see RFC3875)
239 * @return the gateway interface dialect. 239 * @return the gateway interface dialect.
240 */ 240 */
241 const string& gateway_interface() const; 241 const string& gateway_interface() const;
242 /** 242 /**
243 * Retrieve the PATH_INFO meta-variable (see RFC3875) 243 * Retrieve the PATH_INFO meta-variable (see RFC3875)
244 * @return path to be interpreted by the script. 244 * @return path to be interpreted by the script.
245 */ 245 */
246 const string& path_info() const; 246 const string& path_info() const;
247 /** 247 /**
248 * Retrieve the PATH_TRANSLATED meta-variable (see RFC3875) 248 * Retrieve the PATH_TRANSLATED meta-variable (see RFC3875)
249 * @return the translated path to the document. 249 * @return the translated path to the document.
250 */ 250 */
251 const string& path_translated() const; 251 const string& path_translated() const;
252 /** 252 /**
253 * Retrieve the QUERY_STRING meta-variable (see RFC3875) 253 * Retrieve the QUERY_STRING meta-variable (see RFC3875)
254 * @return the query string. 254 * @return the query string.
255 */ 255 */
256 const string& query_string() const; 256 const string& query_string() const;
257 /** 257 /**
258 * Retrieve the REMOTE_ADDR meta-variable (see RFC3875) 258 * Retrieve the REMOTE_ADDR meta-variable (see RFC3875)
259 * @return the network address of the remote host. 259 * @return the network address of the remote host.
260 */ 260 */
261 const string& remote_addr() const; 261 const string& remote_addr() const;
262 /** 262 /**
263 * Retrieve the REMOTE_HOST meta-variable (see RFC3875) 263 * Retrieve the REMOTE_HOST meta-variable (see RFC3875)
264 * @return the fully qualified domain name of the client if 264 * @return the fully qualified domain name of the client if
265 * available. REMOTE_ADDR otherwise. 265 * available. REMOTE_ADDR otherwise.
266 * @see remote_addr() 266 * @see remote_addr()
267 */ 267 */
268 const string& remote_host() const; 268 const string& remote_host() const;
269 /** 269 /**
270 * Retrieve the REMOTE_IDENT meta-variable (see RFC3875) 270 * Retrieve the REMOTE_IDENT meta-variable (see RFC3875)
271 * @return remote user identity (see RFC1413). 271 * @return remote user identity (see RFC1413).
272 */ 272 */
273 const string& remote_ident() const; 273 const string& remote_ident() const;
274 /** 274 /**
275 * Retrieve the REMOTE_USER meta-variable (see RFC3875) 275 * Retrieve the REMOTE_USER meta-variable (see RFC3875)
276 * @return the authenticated user name. 276 * @return the authenticated user name.
277 */ 277 */
278 const string& remote_user() const; 278 const string& remote_user() const;
279 /** 279 /**
280 * Retrieve the REQUEST_METHOD meta-variable (see RFC3875) 280 * Retrieve the REQUEST_METHOD meta-variable (see RFC3875)
281 * @return the http request method. 281 * @return the http request method.
282 */ 282 */
283 const string& request_method() const; 283 const string& request_method() const;
284 /** 284 /**
285 * Retrieve the SCRIPT_NAME meta-variable (see RFC3875) 285 * Retrieve the SCRIPT_NAME meta-variable (see RFC3875)
286 * @return the uri path identifying the script. 286 * @return the uri path identifying the script.
287 */ 287 */
288 const string& script_name() const; 288 const string& script_name() const;
289 /** 289 /**
290 * Retrieve the SERVER_NAME meta-variable (see RFC3875) 290 * Retrieve the SERVER_NAME meta-variable (see RFC3875)
291 * @return the server name of the script. 291 * @return the server name of the script.
292 */ 292 */
293 const string& server_name() const; 293 const string& server_name() const;
294 /** 294 /**
295 * Retrieve the SERVER_PORT meta-variable (see RFC3875) 295 * Retrieve the SERVER_PORT meta-variable (see RFC3875)
296 * @return the port on which request was received. 296 * @return the port on which request was received.
297 */ 297 */
298 unsigned int server_port() const; 298 unsigned int server_port() const;
299 /** 299 /**
300 * Retrieve the SERVER_PROTOCOL meta-variable (see RFC3875) 300 * Retrieve the SERVER_PROTOCOL meta-variable (see RFC3875)
301 * @return the protocol used for the request. 301 * @return the protocol used for the request.
302 */ 302 */
303 const string& server_protocol() const; 303 const string& server_protocol() const;
304 /** 304 /**
305 * Retrieve the SERVER_SOFTWARE meta-variable (see RFC3875) 305 * Retrieve the SERVER_SOFTWARE meta-variable (see RFC3875)
306 * @return the name and version of server software. 306 * @return the name and version of server software.
307 */ 307 */
308 const string& server_software() const; 308 const string& server_software() const;
309 309
310 private:
311 /** 310 /**
312 * Parse the query string, putting the parameters into the map 311 * Parse the query string, putting the parameters into the map
313 * specified. 312 * specified.
314 * @param q the query string. 313 * @param q the query string.
315 * @param p destination parameters map. 314 * @param p destination parameters map.
316 */ 315 */
317 static void parse_query(string& q,params_t& p); 316 static void parse_query(string& q,params_t& p);
318 }; 317 };
319 318
320} 319}
321 320
322#endif /* __KINGATE_CGI_GATEWAY_H */ 321#endif /* __KINGATE_CGI_GATEWAY_H */
323/* 322/*
324 * vim:set ft=cpp: 323 * vim:set ft=cpp:
325 */ 324 */
diff --git a/include/kingate/cookies.h b/include/kingate/cookies.h
index 83ef0c6..a1e813c 100644
--- a/include/kingate/cookies.h
+++ b/include/kingate/cookies.h
@@ -66,235 +66,235 @@ namespace kingate {
66 * @see has_domain() 66 * @see has_domain()
67 * @see unset_domain() 67 * @see unset_domain()
68 */ 68 */
69 void set_domain(const string& d); 69 void set_domain(const string& d);
70 /** 70 /**
71 * @param ma max-age. 71 * @param ma max-age.
72 * @see get_max_age() 72 * @see get_max_age()
73 * @see has_max_age() 73 * @see has_max_age()
74 * @see unset_max_age() 74 * @see unset_max_age()
75 */ 75 */
76 void set_max_age(const string& ma); 76 void set_max_age(const string& ma);
77 /** 77 /**
78 * @param p path. 78 * @param p path.
79 * @see get_path() 79 * @see get_path()
80 * @see has_path() 80 * @see has_path()
81 * @see unset_path() 81 * @see unset_path()
82 */ 82 */
83 void set_path(const string& p); 83 void set_path(const string& p);
84 /** 84 /**
85 * set cookie security. 85 * set cookie security.
86 * @param s true if secure. 86 * @param s true if secure.
87 * @see get_secure() 87 * @see get_secure()
88 * @see is_secure() 88 * @see is_secure()
89 */ 89 */
90 void set_secure(bool s); 90 void set_secure(bool s);
91 91
92 /** 92 /**
93 * @param e expiration time. 93 * @param e expiration time.
94 * @see get_expires() 94 * @see get_expires()
95 * @see has_expires() 95 * @see has_expires()
96 * @see unset_expires() 96 * @see unset_expires()
97 */ 97 */
98 void set_expires(const string& e); 98 void set_expires(const string& e);
99 99
100 /** 100 /**
101 * get cookie parameter. 101 * get cookie parameter.
102 * @param p parameter name. 102 * @param p parameter name.
103 * @return parameter value. 103 * @return parameter value.
104 * @see _set_string() 104 * @see _set_string()
105 */ 105 */
106 const string& _get_string(const string& p) const; 106 const string& _get_string(const string& p) const;
107 107
108 /** 108 /**
109 * @return cookie name. 109 * @return cookie name.
110 * @see set_name() 110 * @see set_name()
111 */ 111 */
112 const string& get_name() const { return name; } 112 const string& get_name() const { return name; }
113 /** 113 /**
114 * @return cookie value. 114 * @return cookie value.
115 * @see set_value() 115 * @see set_value()
116 */ 116 */
117 const string& get_value() const { return value; } 117 const string& get_value() const { return value; }
118 /** 118 /**
119 * @return cookie comment. 119 * @return cookie comment.
120 * @see set_comment() 120 * @see set_comment()
121 * @see has_comment() 121 * @see has_comment()
122 * @see unset_comment() 122 * @see unset_comment()
123 */ 123 */
124 const string& get_comment() const; 124 const string& get_comment() const;
125 /** 125 /**
126 * @return cookie domain. 126 * @return cookie domain.
127 * @see set_domain() 127 * @see set_domain()
128 * @see has_domain() 128 * @see has_domain()
129 * @see unset_domain() 129 * @see unset_domain()
130 */ 130 */
131 const string& get_domain() const; 131 const string& get_domain() const;
132 /** 132 /**
133 * @return cookie max-age. 133 * @return cookie max-age.
134 * @see set_max_age() 134 * @see set_max_age()
135 * @see has_max_age() 135 * @see has_max_age()
136 * @see unset_max_age() 136 * @see unset_max_age()
137 */ 137 */
138 const string& get_max_age() const; 138 const string& get_max_age() const;
139 /** 139 /**
140 * @return cookie path. 140 * @return cookie path.
141 * @see set_path() 141 * @see set_path()
142 * @see has_path() 142 * @see has_path()
143 * @see unset_path() 143 * @see unset_path()
144 */ 144 */
145 const string& get_path() const; 145 const string& get_path() const;
146 /** 146 /**
147 * @return cookie security. 147 * @return cookie security.
148 * @see is_secure() 148 * @see is_secure()
149 * @see set_secure() 149 * @see set_secure()
150 */ 150 */
151 bool get_secure() const; 151 bool get_secure() const;
152 /** 152 /**
153 * @return cookie security. 153 * @return cookie security.
154 * @see get_secure() 154 * @see get_secure()
155 * @see set_secure() 155 * @see set_secure()
156 */ 156 */
157 bool is_secure() const { return get_secure(); } 157 bool is_secure() const { return get_secure(); }
158 158
159 /** 159 /**
160 * @return cookie expiration time. 160 * @return cookie expiration time.
161 * @see set_expires() 161 * @see set_expires()
162 * @see has_expires() 162 * @see has_expires()
163 * @see unset_expires() 163 * @see unset_expires()
164 */ 164 */
165 const string& get_expires() const; 165 const string& get_expires() const;
166 166
167 /** 167 /**
168 * @return true if cookie has comment. 168 * @return true if cookie has comment.
169 * @see set_comment() 169 * @see set_comment()
170 * @see get_comment() 170 * @see get_comment()
171 * @see unset_comment() 171 * @see unset_comment()
172 */ 172 */
173 bool has_comment() const; 173 bool has_comment() const;
174 /** 174 /**
175 * @return true if cookie has domain. 175 * @return true if cookie has domain.
176 * @see set_domain() 176 * @see set_domain()
177 * @see get_domain() 177 * @see get_domain()
178 * @see unset_domain() 178 * @see unset_domain()
179 */ 179 */
180 bool has_domain() const; 180 bool has_domain() const;
181 /** 181 /**
182 * @return true if cookie has max-age. 182 * @return true if cookie has max-age.
183 * @see set_max_age() 183 * @see set_max_age()
184 * @see get_max_age() 184 * @see get_max_age()
185 * @see unset_max_age() 185 * @see unset_max_age()
186 */ 186 */
187 bool has_max_age() const; 187 bool has_max_age() const;
188 /** 188 /**
189 * @return true if cookie has path. 189 * @return true if cookie has path.
190 * @see set_path() 190 * @see set_path()
191 * @see get_path() 191 * @see get_path()
192 * @see unset_path() 192 * @see unset_path()
193 */ 193 */
194 bool has_path() const; 194 bool has_path() const;
195 195
196 /** 196 /**
197 * @return true if cookie has expiration time. 197 * @return true if cookie has expiration time.
198 * @see set_expires() 198 * @see set_expires()
199 * @see get_expires() 199 * @see get_expires()
200 * @see unset_expires() 200 * @see unset_expires()
201 */ 201 */
202 bool has_expires() const; 202 bool has_expires() const;
203 203
204 /** 204 /**
205 * rid cookie of comment. 205 * rid cookie of comment.
206 * @see set_comment() 206 * @see set_comment()
207 * @see get_comment() 207 * @see get_comment()
208 * @see has_comment() 208 * @see has_comment()
209 */ 209 */
210 void unset_comment(); 210 void unset_comment();
211 /** 211 /**
212 * rid cookie of domain. 212 * rid cookie of domain.
213 * @see set_domain() 213 * @see set_domain()
214 * @see get_domain() 214 * @see get_domain()
215 * @see has_domain() 215 * @see has_domain()
216 */ 216 */
217 void unset_domain(); 217 void unset_domain();
218 /** 218 /**
219 * rid cookie of max-age. 219 * rid cookie of max-age.
220 * @see set_max_age() 220 * @see set_max_age()
221 * @see get_max_age() 221 * @see get_max_age()
222 * @see has_max_age() 222 * @see has_max_age()
223 */ 223 */
224 void unset_max_age(); 224 void unset_max_age();
225 /** 225 /**
226 * rid cookie of path. 226 * rid cookie of path.
227 * @see set_path() 227 * @see set_path()
228 * @see get_path() 228 * @see get_path()
229 * @see has_path() 229 * @see has_path()
230 */ 230 */
231 void unset_path(); 231 void unset_path();
232 232
233 /** 233 /**
234 * rid cookie of expiration time. 234 * rid cookie of expiration time.
235 * @see set_expires() 235 * @see set_expires()
236 * @see get_expires() 236 * @see get_expires()
237 * @see has_expires() 237 * @see has_expires()
238 */ 238 */
239 void unset_expires(); 239 void unset_expires();
240 240
241 /** 241 /**
242 * render the 'Set-Cookie' HTTP header according to RFC2109. 242 * render the 'Set-Cookie' HTTP header according to RFC2109.
243 * Absolutely useless, only works with lynx. 243 * Absolutely useless, only works with lynx.
244 * @return the rendered header content. 244 * @return the rendered header content.
245 */ 245 */
246 string set_cookie_header_rfc2109() const; 246 string set_cookie_header_rfc2109() const;
247 /** 247 /**
248 * render the 'Set-Cookie' header according to the early vague 248 * render the 'Set-Cookie' header according to the early vague
249 * netscape specs and common practice. 249 * netscape specs and common practice.
250 * @return the rendered header content. 250 * @return the rendered header content.
251 */ 251 */
252 string set_cookie_header() const; 252 string set_cookie_header() const;
253 }; 253 };
254 254
255 /** 255 /**
256 * Cookies container class. 256 * Cookies container class.
257 */ 257 */
258 class cookies_t : public map<string,cookie> { 258 class cookies_t : public multimap<string,cookie> {
259 public: 259 public:
260 260
261 cookies_t() { } 261 cookies_t() { }
262 /** 262 /**
263 * @param s 'Cookie:' HTTP header contents to parse. 263 * @param s 'Cookie:' HTTP header contents to parse.
264 */ 264 */
265 cookies_t(const string& s) { parse_cookies(s); } 265 cookies_t(const string& s) { parse_cookies(s); }
266 266
267 /** 267 /**
268 * @param c cookie to set. 268 * @param c cookie to set.
269 */ 269 */
270 void set_cookie(const cookie& c) { (*this)[c.get_name()]=c; } 270 void set_cookie(const cookie& c);
271 /** 271 /**
272 * @param n cookie name to remove. 272 * @param n cookie name to remove.
273 */ 273 */
274 void unset_cookie(const key_type& n) { erase(n); } 274 void unset_cookie(const key_type& n) { erase(n); }
275 /** 275 /**
276 * @param n cookie name. 276 * @param n cookie name.
277 * @return true if exists. 277 * @return true if exists.
278 */ 278 */
279 bool has_cookie(const key_type& n) const; 279 bool has_cookie(const key_type& n) const;
280 /** 280 /**
281 * Return the named cookie if one exists. 281 * Return the named cookie if one exists.
282 * @param n cookie name. 282 * @param n cookie name.
283 * @return const reference to cookie object. 283 * @return const reference to cookie object.
284 */ 284 */
285 const cookie& get_cookie(const key_type& n) const; 285 const cookie& get_cookie(const key_type& n) const;
286 /** 286 /**
287 * Return the named cookie if one exists. 287 * Return the named cookie if one exists.
288 * @param n cookie name. 288 * @param n cookie name.
289 * @return reference to cookie object. 289 * @return reference to cookie object.
290 */ 290 */
291 cookie& get_cookie(const key_type& n); 291 cookie& get_cookie(const key_type& n);
292 292
293 /** 293 /**
294 * @param s HTTP 'Cookie' header content. 294 * @param s HTTP 'Cookie' header content.
295 */ 295 */
296 void parse_cookies(const string& s); 296 void parse_cookies(const string& s);
297 }; 297 };
298} 298}
299 299
300#endif /* __KINGATE_COOKIES_H */ 300#endif /* __KINGATE_COOKIES_H */
diff --git a/src/cookies.cc b/src/cookies.cc
index 40a0c8b..1ee4f7c 100644
--- a/src/cookies.cc
+++ b/src/cookies.cc
@@ -1,242 +1,245 @@
1#include "kingate/cookies.h" 1#include "kingate/cookies.h"
2#include "kingate/util.h" 2#include "kingate/util.h"
3#include "kingate/exception.h" 3#include "kingate/exception.h"
4 4
5namespace kingate { 5namespace kingate {
6 6
7 /* 7 /*
8 * RFC 2109: 8 * RFC 2109:
9 * av-pairs = av-pair *(";" av-pair) 9 * av-pairs = av-pair *(";" av-pair)
10 * av-pair = attr ["=" value] ; optional value 10 * av-pair = attr ["=" value] ; optional value
11 * attr = token 11 * attr = token
12 * value = word 12 * value = word
13 * word = token | quoted-string 13 * word = token | quoted-string
14 */ 14 */
15 15
16 /* RFC 2109: 16 /* RFC 2109:
17 * 17 *
18 * The origin server effectively ends a session by sending the client a 18 * The origin server effectively ends a session by sending the client a
19 * Set-Cookie header with Max-Age=0. 19 * Set-Cookie header with Max-Age=0.
20 * 20 *
21 * An origin server may include multiple Set-Cookie headers in a response. 21 * An origin server may include multiple Set-Cookie headers in a response.
22 * Note that an intervening gateway could fold multiple such headers into a 22 * Note that an intervening gateway could fold multiple such headers into a
23 * single header. 23 * single header.
24 * 24 *
25 * 25 *
26 * set-cookie = "Set-Cookie:" cookies 26 * set-cookie = "Set-Cookie:" cookies
27 * cookies = 1#cookie 27 * cookies = 1#cookie
28 * cookie = NAME "=" VALUE *(";" cookie-av) 28 * cookie = NAME "=" VALUE *(";" cookie-av)
29 * NAME = attr 29 * NAME = attr
30 * VALUE = value 30 * VALUE = value
31 * cookie-av = "Comment" "=" value 31 * cookie-av = "Comment" "=" value
32 * | "Domain" "=" value 32 * | "Domain" "=" value
33 * | "Max-Age" "=" value 33 * | "Max-Age" "=" value
34 * | "Path" "=" value 34 * | "Path" "=" value
35 * | "Secure" 35 * | "Secure"
36 * | "Version" "=" 1*DIGIT 36 * | "Version" "=" 1*DIGIT
37 * 37 *
38 * 38 *
39 * The origin server should send the following additional HTTP/1.1 39 * The origin server should send the following additional HTTP/1.1
40 * response headers, depending on circumstances: 40 * response headers, depending on circumstances:
41 * 41 *
42 * * To suppress caching of the Set-Cookie header: Cache-control: no- 42 * * To suppress caching of the Set-Cookie header: Cache-control: no-
43 * cache="set-cookie". 43 * cache="set-cookie".
44 * 44 *
45 * and one of the following: 45 * and one of the following:
46 * 46 *
47 * * To suppress caching of a private document in shared caches: Cache- 47 * * To suppress caching of a private document in shared caches: Cache-
48 * control: private. 48 * control: private.
49 * 49 *
50 * * To allow caching of a document and require that it be validated 50 * * To allow caching of a document and require that it be validated
51 * before returning it to the client: Cache-control: must-revalidate. 51 * before returning it to the client: Cache-control: must-revalidate.
52 * 52 *
53 * * To allow caching of a document, but to require that proxy caches 53 * * To allow caching of a document, but to require that proxy caches
54 * (not user agent caches) validate it before returning it to the 54 * (not user agent caches) validate it before returning it to the
55 * client: Cache-control: proxy-revalidate. 55 * client: Cache-control: proxy-revalidate.
56 * 56 *
57 * * To allow caching of a document and request that it be validated 57 * * To allow caching of a document and request that it be validated
58 * before returning it to the client (by "pre-expiring" it): 58 * before returning it to the client (by "pre-expiring" it):
59 * Cache-control: max-age=0. Not all caches will revalidate the 59 * Cache-control: max-age=0. Not all caches will revalidate the
60 * document in every case. 60 * document in every case.
61 * 61 *
62 * HTTP/1.1 servers must send Expires: old-date (where old-date is a 62 * HTTP/1.1 servers must send Expires: old-date (where old-date is a
63 * date long in the past) on responses containing Set-Cookie response 63 * date long in the past) on responses containing Set-Cookie response
64 * headers unless they know for certain (by out of band means) that 64 * headers unless they know for certain (by out of band means) that
65 * there are no downsteam HTTP/1.0 proxies. HTTP/1.1 servers may send 65 * there are no downsteam HTTP/1.0 proxies. HTTP/1.1 servers may send
66 * other Cache-Control directives that permit caching by HTTP/1.1 66 * other Cache-Control directives that permit caching by HTTP/1.1
67 * proxies in addition to the Expires: old-date directive; the Cache- 67 * proxies in addition to the Expires: old-date directive; the Cache-
68 * Control directive will override the Expires: old-date for HTTP/1.1 68 * Control directive will override the Expires: old-date for HTTP/1.1
69 * proxies. 69 * proxies.
70 * 70 *
71 */ 71 */
72 72
73 void cookie::_set_string(const string& p,const string& v) { 73 void cookie::_set_string(const string& p,const string& v) {
74 (*this)[p]=v; 74 (*this)[p]=v;
75 } 75 }
76 76
77 void cookie::set_comment(const string& c) { 77 void cookie::set_comment(const string& c) {
78 _set_string("comment",c); 78 _set_string("comment",c);
79 } 79 }
80 void cookie::set_domain(const string& d) { 80 void cookie::set_domain(const string& d) {
81 _set_string("domain",d); 81 _set_string("domain",d);
82 } 82 }
83 void cookie::set_max_age(const string& ma) { 83 void cookie::set_max_age(const string& ma) {
84 _set_string("max-age",ma); 84 _set_string("max-age",ma);
85 } 85 }
86 void cookie::set_path(const string& p) { 86 void cookie::set_path(const string& p) {
87 _set_string("path",p); 87 _set_string("path",p);
88 } 88 }
89 void cookie::set_secure(bool s) { 89 void cookie::set_secure(bool s) {
90 if(s) 90 if(s)
91 _set_string("secure",""); 91 _set_string("secure","");
92 else 92 else
93 erase("secure"); 93 erase("secure");
94 } 94 }
95 95
96 void cookie::set_expires(const string& e) { 96 void cookie::set_expires(const string& e) {
97 (*this)["expires"] = e; 97 (*this)["expires"] = e;
98 } 98 }
99 99
100 const string& cookie::_get_string(const string& s) const { 100 const string& cookie::_get_string(const string& s) const {
101 const_iterator i = find(s); 101 const_iterator i = find(s);
102 if(i==end()) 102 if(i==end())
103 throw exception_notfound(CODEPOINT,"No parameter set"); 103 throw exception_notfound(CODEPOINT,"No parameter set");
104 return i->second; 104 return i->second;
105 } 105 }
106 106
107 const string& cookie::get_comment() const { 107 const string& cookie::get_comment() const {
108 return _get_string("comment"); 108 return _get_string("comment");
109 } 109 }
110 const string& cookie::get_domain() const { 110 const string& cookie::get_domain() const {
111 return _get_string("domain"); 111 return _get_string("domain");
112 } 112 }
113 const string& cookie::get_max_age() const { 113 const string& cookie::get_max_age() const {
114 return _get_string("max-age"); 114 return _get_string("max-age");
115 } 115 }
116 const string& cookie::get_path() const { 116 const string& cookie::get_path() const {
117 return _get_string("path"); 117 return _get_string("path");
118 } 118 }
119 bool cookie::get_secure() const { 119 bool cookie::get_secure() const {
120 return find("secure")!=end(); 120 return find("secure")!=end();
121 } 121 }
122 122
123 const string& cookie::get_expires() const { 123 const string& cookie::get_expires() const {
124 return _get_string("expires"); 124 return _get_string("expires");
125 } 125 }
126 126
127 bool cookie::has_comment() const { 127 bool cookie::has_comment() const {
128 return find("comment")!=end(); 128 return find("comment")!=end();
129 } 129 }
130 bool cookie::has_domain() const { 130 bool cookie::has_domain() const {
131 return find("domain")!=end(); 131 return find("domain")!=end();
132 } 132 }
133 bool cookie::has_max_age() const { 133 bool cookie::has_max_age() const {
134 return find("max-age")!=end(); 134 return find("max-age")!=end();
135 } 135 }
136 bool cookie::has_path() const { 136 bool cookie::has_path() const {
137 return find("path")!=end(); 137 return find("path")!=end();
138 } 138 }
139 139
140 bool cookie::has_expires() const { 140 bool cookie::has_expires() const {
141 return find("expires")!=end(); 141 return find("expires")!=end();
142 } 142 }
143 143
144 void cookie::unset_comment() { 144 void cookie::unset_comment() {
145 erase("comment"); 145 erase("comment");
146 } 146 }
147 void cookie::unset_domain() { 147 void cookie::unset_domain() {
148 erase("domain"); 148 erase("domain");
149 } 149 }
150 void cookie::unset_max_age() { 150 void cookie::unset_max_age() {
151 erase("max-age"); 151 erase("max-age");
152 } 152 }
153 void cookie::unset_path() { 153 void cookie::unset_path() {
154 erase("path"); 154 erase("path");
155 } 155 }
156 156
157 void cookie::unset_expires() { 157 void cookie::unset_expires() {
158 erase("expires"); 158 erase("expires");
159 } 159 }
160 160
161 string cookie::set_cookie_header_rfc2109() const { 161 string cookie::set_cookie_header_rfc2109() const {
162 string rv = name + "=" + http_quoted_string(value); 162 string rv = name + "=" + http_quoted_string(value);
163 for(const_iterator i=begin();i!=end();++i) { 163 for(const_iterator i=begin();i!=end();++i) {
164 if(i->first=="secure") { 164 if(i->first=="secure") {
165 rv += "; secure"; 165 rv += "; secure";
166 }else{ 166 }else{
167 rv += "; "+i->first+"="+http_quote(i->second); 167 rv += "; "+i->first+"="+http_quote(i->second);
168 } 168 }
169 } 169 }
170 rv += "; Version=1"; 170 rv += "; Version=1";
171 return rv; 171 return rv;
172 } 172 }
173 173
174 string cookie::set_cookie_header() const { 174 string cookie::set_cookie_header() const {
175 string rv = name + "=" + value; 175 string rv = name + "=" + value;
176 for(const_iterator i=begin();i!=end();++i) { 176 for(const_iterator i=begin();i!=end();++i) {
177 if(i->first=="secure") { 177 if(i->first=="secure") {
178 rv += "; secure"; 178 rv += "; secure";
179 }else{ 179 }else{
180 rv += "; "+i->first+"="+i->second; 180 rv += "; "+i->first+"="+i->second;
181 } 181 }
182 } 182 }
183 return rv; 183 return rv;
184 } 184 }
185 185
186 void cookies_t::set_cookie(const cookie& c) {
187 insert(value_type(c.get_name(),c));
188 }
189
186 bool cookies_t::has_cookie(const key_type& n) const { 190 bool cookies_t::has_cookie(const key_type& n) const {
187 return find(n)!=end(); 191 return find(n)!=end();
188 } 192 }
189 193
190 const cookie& cookies_t::get_cookie(const key_type& n) const { 194 const cookie& cookies_t::get_cookie(const key_type& n) const {
191 const_iterator i=find(n); 195 const_iterator i=find(n);
192 if(i==end()) 196 if(i==end())
193 throw exception_notfound(CODEPOINT,"No cookie with such name found"); 197 throw exception_notfound(CODEPOINT,"No cookie with such name found");
194 return i->second; 198 return i->second;
195 } 199 }
196 200
197 cookie& cookies_t::get_cookie(const key_type& n) { 201 cookie& cookies_t::get_cookie(const key_type& n) {
198 iterator i=find(n); 202 iterator i=find(n);
199 if(i==end()) 203 if(i==end())
200 throw exception_notfound(CODEPOINT,"No cookie with such name found"); 204 throw exception_notfound(CODEPOINT,"No cookie with such name found");
201 return i->second; 205 return i->second;
202 } 206 }
203 207
204 void cookies_t::parse_cookies(const string& s) { 208 void cookies_t::parse_cookies(const string& s) {
205 string str = s; 209 string str = s;
206 while(!str.empty()) { 210 while(!str.empty()) {
207 string::size_type sc = str.find(';'); 211 string::size_type sc = str.find(';');
208 string s; 212 string s;
209 if(sc==string::npos) { 213 if(sc==string::npos) {
210 s = str; 214 s = str;
211 str.erase(); 215 str.erase();
212 }else{ 216 }else{
213 s = str.substr(0,sc); 217 s = str.substr(0,sc);
214 str.erase(0,sc+1); 218 str.erase(0,sc+1);
215 } 219 }
216 string::size_type nsp=s.find_first_not_of(" \t"); 220 string::size_type nsp=s.find_first_not_of(" \t");
217 if((nsp!=string::npos) && nsp) 221 if((nsp!=string::npos) && nsp)
218 s.erase(0,nsp); 222 s.erase(0,nsp);
219 string::size_type eq=s.find('='); 223 string::size_type eq=s.find('=');
220 if(eq==string::npos) 224 if(eq==string::npos)
221 continue; 225 continue;
222 string n = s.substr(0,eq); 226 string n = s.substr(0,eq);
223 s.erase(0,eq+1); 227 s.erase(0,eq+1);
224 nsp = n.find_last_not_of(" \t"); 228 nsp = n.find_last_not_of(" \t");
225 n.erase(nsp+1); 229 n.erase(nsp+1);
226 nsp = s.find_first_not_of(" \t"); 230 nsp = s.find_first_not_of(" \t");
227 string v; 231 string v;
228 if(nsp!=string::npos) 232 if(nsp!=string::npos)
229 v = s.substr(nsp); 233 v = s.substr(nsp);
230 else 234 else
231 v = s; 235 v = s;
232 nsp = v.find_last_not_of(" \t"); 236 nsp = v.find_last_not_of(" \t");
233 if(nsp==string::npos) 237 if(nsp==string::npos)
234 v.erase(); 238 v.erase();
235 else 239 else
236 v.erase(nsp+1); 240 v.erase(nsp+1);
237 cookie& c = (*this)[n]; 241 set_cookie(cookie(n,v));
238 c.set_name(n); c.set_value(v);
239 } 242 }
240 } 243 }
241 244
242} 245}