PNG  IHDR!@ PLTE>O`jqv 7'tEXtPage
cookie.scm - metalympiada
git clone git://metalympiada.org/
Log | Files | README | LICENSE

cookie.scm (3693B)


   1 ;;; guile-webutils -- Web application utilities for Guile
   2 ;;; Copyright © 2016  Christopher Allan Webber <cwebber@dustycloud.org>
   3 (define-module (cookie)
   4   #:export (set-cookie delete-cookie))
   5 (use-modules (srfi srfi-1)
   6              (srfi srfi-19)
   7              (srfi srfi-26)
   8              (ice-9 control)
   9              (ice-9 match)
  10              (web http))
  11 
  12 (define cookie-val-char-set
  13   (char-set-difference (char-set-delete char-set:ascii #\, #\;)
  14                        char-set:iso-control))
  15 
  16 (define cookie-name-char-set
  17   (char-set-delete cookie-val-char-set #\=))
  18 
  19 (define (parse-cookie cookie-text)
  20   (let ((parts (string-split cookie-text #\;)))
  21     (define (split-cookie-pair cookie-pair)
  22       (let* ((trimmed (string-trim cookie-pair))
  23              (delim (string-index trimmed #\=))
  24              (attrib (if delim
  25                          (substring trimmed 0 delim)
  26                          trimmed))
  27              (val (if delim
  28                       (substring trimmed (+ delim 1))
  29                       #t)))
  30         (cons attrib val)))
  31     (map split-cookie-pair parts)))
  32 
  33 (define (date->http-date-string date)
  34   (call-with-output-string (cut (@@ (web http) write-date) date <>)))
  35 
  36 (define (write-cookie cookie-alist port)
  37   (let ((cookie-str
  38          (string-join 
  39           (map (match-lambda
  40                  ((name . (? string? val))
  41                   (string-append name "=" val))
  42                  ((name . (? date? val))
  43                   (string-append name "=" (date->http-date-string val)))
  44                  ((name . #t)
  45                   name))
  46                cookie-alist)
  47           "; ")))
  48     (display cookie-str port)))
  49 
  50 (define (valid-cookie-name? str)
  51   (and (string? str)
  52        (string-every cookie-name-char-set str)))
  53 
  54 (define (valid-cookie-val? str)
  55   (or (eq? str #t)
  56       (and (string? str)
  57            (string-every cookie-val-char-set str))
  58       (date? str)))
  59 
  60 (define (validate-cookie cookie-alist)
  61   (match cookie-alist
  62     ((((? valid-cookie-name? name) . (or #t (? valid-cookie-val? _))) ...)
  63      #t)
  64     (_ #f)))
  65 
  66 (declare-header! "Cookie"
  67                  parse-cookie validate-cookie write-cookie)
  68 
  69 (define (parse-set-cookie str)
  70   (match (parse-cookie str)
  71     (((name . val) attrs ...)
  72      (list name val attrs))))
  73 
  74 (define (validate-set-cookie obj)
  75   (match obj
  76     ((name val (attrs ...))
  77      (validate-cookie
  78       (cons (cons name val)
  79             attrs)))
  80     (_ #f)))
  81 
  82 (define (write-set-cookie obj port)
  83   (match obj
  84     ((name val (attrs ...))
  85      (write-cookie
  86       (cons (cons name val)
  87             attrs)
  88       port))))
  89 
  90 (declare-header! "Set-Cookie"
  91                  parse-set-cookie validate-set-cookie write-set-cookie
  92                  #:multiple? #t)
  93 
  94 (define* (set-cookie name #:optional (val "")
  95                      #:key expires max-age domain
  96                      path secure http-only
  97                      (extensions '())) 
  98   (define (maybe-append name val)
  99     (lambda (prev)
 100       (if val
 101           (cons (cons name val)
 102                 prev)
 103           prev)))
 104   (define basic-prop-alist
 105     ((compose
 106       (maybe-append "Expires" expires)
 107       (maybe-append "Max-Age" max-age)
 108       (maybe-append "Domain" domain)
 109       (maybe-append "Path" path)
 110       (maybe-append "Secure" secure)
 111       (maybe-append "HttpOnly" http-only))
 112      '()))
 113   (define prop-alist
 114     (append basic-prop-alist
 115             extensions))
 116   (cons 'set-cookie (list name val prop-alist)))
 117 
 118 (define %the-epoch
 119   (time-monotonic->date (make-time 'time-monotonic 0 0) 0))
 120 
 121 (define (delete-cookie name)
 122   (set-cookie name
 123               #:expires %the-epoch
 124               #:path "/"
 125               #:secure #t
 126               #:http-only #t))
@JIDATxogzgF,Vrntɩ-kzP&@]H9A{/UR900{033.Xѻ=$@aV[lڭBM3$)ǡ$[|<1$_^1Wm cxMu#x(cG  @`L-wJ81%7㈁87k聠ad?_3_?8R0r &蕑STRj dJ--ݑDM#H 7"ha+ )∁@tė"@4qҜ܏18Lslxa~\;;p h.WuVh{0x W뼝BiE˕E#B >q;sH00x)^ .w e [?i=cvQ .:A Vu&٫!VRRp rKRbD[O)I ɀ5r[^T*CpJk +5(9)8u0R/XxIB#nؿX{TD/;J c"q8i'68 QXݠeJ߿؆Q'BÃIU/m9\KM\31̨(j0C?bd"{;dra+V!*kS-})|P$/M]Zm9U LUjeתV=eِx-ClK!nkJJcuq x9Ҟ~33=tr"m O͎>ԃ;'wѣo]S<~]q]ǜ_ P@ c5[#&XWC@^aS7Xz>l{0 WxY I=\c6;ߏPϋ^|zaգF\?KgEmqcF/_5w?}ԣR/7X .)Be?W=@z\_=f]0?H_d_`plq1` m H[_bs6쿡Ŀ3$i{ 74ftB7$/x\`~~ C@ ?mYoC u6|~UL+K)^b[Yy(Fy?bԀ*%$ېPz۰φlD{/a5G}jN t}酔iqIo10>6)],^&t'W+zG*1Ds$,u:!kg k>ӏ8tO?F1 ^ 4" Ir$fUހ<5\XIIO1x3ѳr#EFAcC+nX]R/7U|;'cX6L׵hfY+*-D@yAaJX2jZ!Pjfz^wB']X>PKg7e! O0vmUh4k*Td>dG7^$kM&fV}~F9cDݜ5!gª5V> `%5 sgJr6|V= jIO;i yCIogWw)oIbfN8m dwј^nD Awrlv̹ڂ.PO 3XhWRu s(bظB|hnIZA44^O3ʟA9H[g *g0VM:s J V=I`v@G t͏S懩6; +a*0 `(+N6Wd.D5nrO5FR>_կv;a+.-k.eGVسLNj& fSM9Zz%xG pg6e\锛߅ZWmS@n92Iӭ ]} Utߠf/42N`WP`Y DVJ&?rpїԀ kh[@)mhe+_>\:?S*ɑjtr8 qqK%&Rإ;V9@GԣBcW<-[IFɉT<\#‽0MG?٪cK%4pծ,,x7%:cG]) 6{oՒԫfRexZ9bhHЖ%DJk&Kt؎. ;Fsݻڐ5dZby;~lcvOaGEn'( LN g779xqq.Jdžs*_r@=yCA,e;bv?"{b?HcXhenܛ-v@cK' L!"xh 3z%pT̴HNHrcb^D.{\WhJfY]gJN8 d)MLO2g^ ..G`2JD Céӳ|̊ڤF' TlV:pY}1Ssc+=-OJԎG aJw65_9{d_!`V=\W't'J~v M*_~ ̲$.,Q7Uk*'aZ"0M6hG j]bpus6$o͵ZG =5]W~Te/ޠOZ4c*4kqaӀ\vA ʤ-]O89>9{9K~ȕR:϶[n)ӵ!*p:S~djϠtE#(-ax:ZVEQP=_@GakI!{w :٤"ъ3"jly|n7 / oq'ԥvjabG\=g\+>,_6R Q':4 +8@OH f+ۆZE:д**kأo 5M:-Y '.yōLL70$CId/YhkTz#@ƷǻJ$g + ƌ cL1rȖ%pUU&hl>LJ/> 9b :ޙol|~Ӓ̤4iRrx ( Uu RKX! MU+e| m yik "yLEˇOnL7J -)hz{ e=t$>9:W ݖLuOoUuadM ,%r~H_T*KP=5] zb"U"XEž e^2[3כ_{ u.5;jxَ5׿͠4ߦ9`,B'n?`ͪ9bgx;K~0btA`iU#h`M -`'~MTbsi*Y-@Sg%HvSdG`6 ԰:t@]kHQM*(`ZXڀi8 9Qr2_ҪU=4V")?R)'Ѧx 5BDl{U_ZN!a!'e-un˕"}x+GZ5KCP)hMAD~ך8'c-'TKK6°H w-Kn>b%sgP?St|IEq64UIϩ61n\4nŎo{t" @t2C[V8%^G͎+E(S<#}hdJfɉE)CM8+