rivet/rivet-tcl/cookie.tcl (105 lines of code) (raw):

## ## cookie [set|get] and supporting functions ## ## $Id$ ## namespace eval ::rivet { ## clock_to_rfc850_gmt seconds -- Convert an integer-seconds-since-1970 ## click value to RFC850 format, with the additional requirement that it ## be GMT only. ## proc clock_to_rfc850_gmt {seconds} { return [clock format $seconds -format "%a, %d-%b-%y %T GMT" -gmt 1] } ## make_cookie_attributes paramsArray -- Build up cookie parameters. ## ## If an expires element appears in the array, it's appended to the ## result as "; expires=value" ## ## If an element is present named "days", "hours", or "minutes", the ## corresponding value is converted to seconds, added to the current ## time, converted to RFC850 time format, and appended to the result ## as, for example, "; expires=Sun, 25-Sep-05 23:09:52 GMT" ## ## If any other elements named "path", "domain", or "secure" are present, ## they too are appended to the result. ## ## The resut is returned. ## proc make_cookie_attributes {paramsArray} { upvar 1 $paramsArray params set cookieParams "" set expiresIn 0 if { [info exists params(expires)] } { append cookieParams "; expires=$params(expires)" } else { foreach {time num} [list days 86400 hours 3600 minutes 60] { if {[info exists params($time)]} { incr expiresIn [expr {$params($time) * $num}] } } if {$expiresIn != 0} { set secs [expr [clock seconds] + $expiresIn] append cookieParams "; expires=[clock_to_rfc850_gmt $secs]" } } if { [info exists params(path)] } { append cookieParams "; path=$params(path)" } if { [info exists params(domain)] } { append cookieParams "; domain=$params(domain)" } if { [info exists params(secure)] && $params(secure) == 1} { append cookieParams "; secure" } if { [info exists params(HttpOnly)] && $params(HttpOnly)} { append cookieParams "; HttpOnly" } return $cookieParams } ## cookie [set|get] cookieName ?cookieValue? [-days expireInDays] ## [-hours expireInHours] [-minutes expireInMinutes] ## [-expires Wdy, DD-Mon-YYYY HH:MM:SS GMT] ## [-path uriPathCookieAppliesTo] ## [-secure 1|0] ## proc cookie {cmd name args} { set badchars "\[ \t;\]" switch -- $cmd { "set" { set value [lindex $args 0] set args [lrange $args 1 end] import_keyvalue_pairs params $args if {[regexp $badchars $name]} { return -code error \ "name may not contain semicolons, spaces, or tabs" } if {[regexp $badchars $value]} { return -code error \ "value may not contain semicolons, spaces, or tabs" } set cookieKey "Set-Cookie" set cookieValue "$name=$value" append cookieValue [make_cookie_attributes params] headers add $cookieKey $cookieValue } "get" { ::request::global RivetCookies if {![array exists RivetCookies]} { load_cookies RivetCookies } if {![info exists RivetCookies($name)]} { return } return $RivetCookies($name) } "delete" { ## In order to delete a cookie, we just need to set a cookie ## with a time that has already expired. cookie set $name "" -minutes -1 } "unset" { ::request::global RivetCookies if {![array exists RivetCookies]} { load_cookies RivetCookies } if {![info exists RivetCookies($name)]} { return } unset RivetCookies($name) } } } }