// --------------------------------------------------------------------------- // - 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); } }