// ---------------------------------------------------------------------------
// - Cookie.cpp -
// - afnix:nwg module - http cookie class implementation -
// ---------------------------------------------------------------------------
// - This program is free software; you can redistribute it and/or modify -
// - it provided that this copyright notice is kept intact. -
// - -
// - This program is distributed in the hope that it will be useful, but -
// - without any warranty; without even the implied warranty of -
// - merchantability or fitness for a particular purpose. In no event shall -
// - the copyright holder be liable for any direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software. -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2007 amaury darsch -
// ---------------------------------------------------------------------------
#include "Date.hpp"
#include "Vector.hpp"
#include "Cookie.hpp"
#include "Integer.hpp"
#include "Boolean.hpp"
#include "QuarkZone.hpp"
#include "Exception.hpp"
namespace afnix {
// -------------------------------------------------------------------------
// - private section -
// -------------------------------------------------------------------------
/// the default cookie version
static const long DEF_COOKIE_VERS = 1;
// get the maximum age from the expiration time
static t_long get_mage (const t_long expt) {
// get the current time
t_long ctim = Time::gettclk ();
t_long mage = expt - ctim;
if (mage < 0) mage = -1LL;
return mage;
}
// format the date for a cookie expire time
static String get_cookie_date (const t_long expt, const t_long mage) {
// prepare for the time object
Date date;
if (expt == 0LL) {
date.add (mage);
} else {
date.settime (expt);
}
// get the day of week
String result = date.mapwday ();
result = result + ", ";
// get the day in month
long mday = date.getmday ();
if (mday < 10) {
result = result + '0' + mday + '-';
} else {
result = result + mday + '-';
}
// get the year month
result = result + date.mapymon () + '-';
// get the year
long year = date.getyear ();
result = result + year + ' ';
// get the time
result = result + date.Time::format (true) + " GMT";
return result;
}
// -------------------------------------------------------------------------
// - class section -
// -------------------------------------------------------------------------
// create a cookie with a name/value pair
Cookie::Cookie (const String& name, const String& value) {
d_vers = DEF_COOKIE_VERS;
d_name = name;
d_cval = value;
d_mage = -1LL;
d_expt = 0LL;
d_port = -1;
d_disf = false;
d_secf = false;
}
// create a cookie with a name/value pair
Cookie::Cookie (const String& name, const String& value, const t_long mage) {
d_vers = DEF_COOKIE_VERS;
d_name = name;
d_cval = value;
d_mage = (mage < 0LL) ? -1LL : mage;
d_expt = 0LL;
d_port = -1;
d_disf = false;
d_secf = false;
}
// return the class name
String Cookie::repr (void) const {
return "Cookie";
}
// return a http cookie string representation
String Cookie::tostring (void) const {
rdlock ();
try {
// set cookie name/value pair
if ((d_name.isnil () == true) || (d_cval.isnil () == true)) {
unlock ();
throw Exception ("cookie-error", "invalid cookie name or value");
}
String result = d_name.tostring () + '=' + d_cval.toliteral ();
// set the cookie version
if (d_vers == 1) {
result += "; Version=\"1\"";
}
// set the cookie expiration time (version 0)
if (((d_mage > 0) || (d_expt > 0)) && (d_vers == 0)) {
result = result + "; Expires=" + get_cookie_date (d_expt, d_mage);
}
// set cookie maximum age (version 1)
if (d_vers == 1) {
t_long mage = (d_expt == 0LL) ? d_mage : get_mage (d_expt);
if (mage >= 0) result = result + "; Max-Age=" + mage;
}
// set cookie path
if (d_path.isnil () == false) {
result = result + "; Path=" + d_path.toliteral ();
}
// set cookie domain
if (d_domain.isnil () == false) {
result = result + "; Domain=" + d_domain.toliteral ();
}
// set cookie port (version 1)
if ((d_port >= 0) && (d_vers == 1)) {
result = result + "; Port=" + '"' + d_port + '"';
}
// set the cookie comment
if (d_comt.isnil () == false) {
result = result + "; Comment=" + d_comt.toliteral ();
}
// set the cookie url comment
if (d_curl.isnil () == false) {
result = result + "; CommentURL=" + d_curl.toliteral ();
}
// set the cookie discard flag (version 1)
if ((d_disf == true) &&(d_vers == 1)) {
result += "; Discard";
}
// set the cookie secure flag
if (d_secf == true) {
result += "; Secure";
}
unlock ();
return result;
} catch (...) {
unlock ();
throw;
}
}
// set the cookie version
void Cookie::setvers (const long vers) {
wrlock ();
try {
// check version
if ((vers != 0) && (vers != 1)) {
throw Exception ("cookie-error", "illegal cookie version");
}
d_vers = vers;
unlock ();
} catch (...) {
unlock ();
throw;
}
}
// get the cookie version
long Cookie::getvers (void) const {
rdlock ();
long result = d_vers;
unlock ();
return result;
}
// set the cookie name
void Cookie::setname (const String& name) {
wrlock ();
d_name = name;
unlock ();
}
// get the cookie name
String Cookie::getname (void) const {
rdlock ();
String result = d_name;
unlock ();
return result;
}
// set the cookie value
void Cookie::setvalue (const String& value) {
wrlock ();
d_cval = value;
unlock ();
}
// get the cookie value
String Cookie::getvalue (void) const {
rdlock ();
String result = d_cval;
unlock ();
return result;
}
// set the cookie maximum age
void Cookie::setmage (const t_long mage) {
wrlock ();
d_mage = (mage < 0LL) ? -1LL : mage;
d_expt = 0LL;
unlock ();
}
// get the cookie maximum age
t_long Cookie::getmage (void) const {
rdlock ();
t_long result = d_mage;
unlock ();
return result;
}
// set the cookie expire time
void Cookie::setexpt (const t_long expt) {
wrlock ();
d_mage = -1LL;
d_expt = expt;
unlock ();
}
// get the cookie expiration time
t_long Cookie::getexpt (void) const {
rdlock ();
t_long result = d_expt;
unlock ();
return result;
}
// set the cookie path
void Cookie::setpath (const String& path) {
wrlock ();
d_path = path;
unlock ();
}
// get the cookie path
String Cookie::getpath (void) const {
rdlock ();
String result = d_path;
unlock ();
return result;
}
// set the cookie domain
void Cookie::setdomain (const String& domain) {
wrlock ();
d_domain = domain;
unlock ();
}
// get the cookie domain
String Cookie::getdomain (void) const {
rdlock ();
String result = d_domain;
unlock ();
return result;
}
// set the cookie port
void Cookie::setport (const long port) {
wrlock ();
d_port = (port < 0) ? -1 : port;
unlock ();
}
// get the cookie port
long Cookie::getport (void) const {
rdlock ();
long result = d_port;
unlock ();
return result;
}
// set the cookie comment
void Cookie::setcomt (const String& comt) {
wrlock ();
d_comt = comt;
unlock ();
}
// get the cookie comment
String Cookie::getcomt (void) const {
rdlock ();
String result = d_comt;
unlock ();
return result;
}
// set the cookie comment url
void Cookie::setcurl (const String& curl) {
wrlock ();
d_curl = curl;
unlock ();
}
// get the cookie comment url
String Cookie::getcurl (void) const {
rdlock ();
String result = d_curl;
unlock ();
return result;
}
// set the cookie discard flag
void Cookie::setdisf (const bool flag) {
wrlock ();
d_disf = flag;
unlock ();
}
// get the cookie discard flag
bool Cookie::getdisf (void) const {
rdlock ();
bool result = d_disf;
unlock ();
return result;
}
// set the cookie secure flag
void Cookie::setsecf (const bool flag) {
wrlock ();
d_secf = flag;
unlock ();
}
// get the cookie secure flag
bool Cookie::getsecf (void) const {
rdlock ();
bool result = d_secf;
unlock ();
return result;
}
// -------------------------------------------------------------------------
// - object section -
// -------------------------------------------------------------------------
// the quark zone
static const long QUARK_ZONE_LENGTH = 25;
static QuarkZone zone (QUARK_ZONE_LENGTH);
// the object supported quarks
static const long QUARK_GETVERS = zone.intern ("get-version");
static const long QUARK_SETVERS = zone.intern ("set-version");
static const long QUARK_GETNAME = zone.intern ("get-name");
static const long QUARK_SETNAME = zone.intern ("set-name");
static const long QUARK_GETMAGE = zone.intern ("get-max-age");
static const long QUARK_SETMAGE = zone.intern ("set-max-age");
static const long QUARK_GETEXPT = zone.intern ("get-expire-time");
static const long QUARK_SETEXPT = zone.intern ("set-expire-time");
static const long QUARK_GETPATH = zone.intern ("get-path");
static const long QUARK_SETPATH = zone.intern ("set-path");
static const long QUARK_GETPORT = zone.intern ("get-port");
static const long QUARK_SETPORT = zone.intern ("set-port");
static const long QUARK_GETCOMT = zone.intern ("get-comment");
static const long QUARK_SETCOMT = zone.intern ("set-comment");
static const long QUARK_GETCURL = zone.intern ("get-comment-url");
static const long QUARK_SETCURL = zone.intern ("set-comment-url");
static const long QUARK_GETDISF = zone.intern ("get-discard");
static const long QUARK_SETDISF = zone.intern ("set-discard");
static const long QUARK_GETSECF = zone.intern ("get-secure");
static const long QUARK_SETSECF = zone.intern ("set-secure");
static const long QUARK_TOSTRING = zone.intern ("to-string");
static const long QUARK_GETVALUE = zone.intern ("get-value");
static const long QUARK_SETVALUE = zone.intern ("set-value");
static const long QUARK_GETDOMAIN = zone.intern ("get-domain");
static const long QUARK_SETDOMAIN = zone.intern ("set-domain");
// create a new object in a generic way
Object* Cookie::mknew (Vector* argv) {
long argc = (argv == nilp) ? 0 : argv->length ();
// check for 2 arguments
if (argc == 2) {
String name = argv->getstring (0);
String value = argv->getstring (1);
return new Cookie (name, value);
}
// check for 3 arguments
if (argc == 3) {
String name = argv->getstring (0);
String value = argv->getstring (1);
long mage = argv->getint (2);
return new Cookie (name, value, mage);
}
// invalid arguments
throw Exception ("argument-error", "invalid arguments with cookie");
}
// return true if the given quark is defined
bool Cookie::isquark (const long quark, const bool hflg) const {
rdlock ();
if (zone.exists (quark) == true) {
unlock ();
return true;
}
bool result = hflg ? Object::isquark (quark, hflg) : false;
unlock ();
return result;
}
// apply this object with a set of arguments and a quark
Object* Cookie::apply (Runnable* robj, Nameset* nset, const long quark,
Vector* argv) {
// get the number of arguments
long argc = (argv == nilp) ? 0 : argv->length ();
// dispatch 0 argument
if (argc == 0) {
if (quark == QUARK_GETVERS) return new Integer (getvers ());
if (quark == QUARK_GETNAME) return new String (getname ());
if (quark == QUARK_GETMAGE) return new Integer (getmage ());
if (quark == QUARK_GETEXPT) return new Integer (getexpt ());
if (quark == QUARK_GETPATH) return new String (getpath ());
if (quark == QUARK_GETPORT) return new Integer (getport ());
if (quark == QUARK_GETCOMT) return new String (getcomt ());
if (quark == QUARK_GETCURL) return new String (getcurl ());
if (quark == QUARK_GETDISF) return new Boolean (getdisf ());
if (quark == QUARK_GETSECF) return new Boolean (getsecf ());
if (quark == QUARK_GETVALUE) return new String (getvalue ());
if (quark == QUARK_TOSTRING) return new String (tostring ());
if (quark == QUARK_GETDOMAIN) return new String (getdomain ());
}
// dispatch 1 argument
if (argc == 1) {
if (quark == QUARK_SETVERS) {
long vers = argv->getint (0);
setvers (vers);
return nilp;
}
if (quark == QUARK_SETNAME) {
String name = argv->getstring (0);
setname (name);
return nilp;
}
if (quark == QUARK_SETVALUE) {
String value = argv->getstring (0);
setvalue (value);
return nilp;
}
if (quark == QUARK_SETMAGE) {
t_long mage = argv->getint (0);
setmage (mage);
return nilp;
}
if (quark == QUARK_SETEXPT) {
t_long expt = argv->getint (0);
setexpt (expt);
return nilp;
}
if (quark == QUARK_SETPATH) {
String path = argv->getstring (0);
setpath (path);
return nilp;
}
if (quark == QUARK_SETDOMAIN) {
String domain = argv->getstring (0);
setdomain (domain);
return nilp;
}
if (quark == QUARK_SETPORT) {
long port = argv->getint (0);
setport (port);
return nilp;
}
if (quark == QUARK_SETCOMT) {
String comt = argv->getstring (0);
setcomt (comt);
return nilp;
}
if (quark == QUARK_SETCURL) {
String curl = argv->getstring (0);
setcurl (curl);
return nilp;
}
if (quark == QUARK_SETDISF) {
bool flag = argv->getbool (0);
setdisf (flag);
return nilp;
}
if (quark == QUARK_SETSECF) {
bool flag = argv->getbool (0);
setsecf (flag);
return nilp;
}
}
// call the object method
return Object::apply (robj, nset, quark, argv);
}
}
syntax highlighted by Code2HTML, v. 0.9.1