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))
@JIDATx[oW~itQƛ貽da{HzЙǬ@6`M(.z05}Hglm5K[xn6@bo7&qfH)RCMI{GEOyoєlZ)4htL#a:ةFphT6m>U 0\ RLcCE]& 3LG 0|-*4dh14 11#6E ?/ߪD;.d͖/8n~ybe `B?; |7 A K@0!TDeBPxd~ANP DENp"?`xIF܋& d&ř~ڢ8A4!Im&#:َUYc?j$FH܇sM @"~`ɛq'[ miZO|`H5Z>#. .DV6%el?2E\BWuklܪު7oؐ{R|@nTcq29 #ywUnVv* '1]uն@Y t[]-|׎H/5i2^%EcR;ޏh 6^B3П|0fBkPO4y $4'X6 X w/f_ӛۙ@1Hkzso ,}zO'(zܑ 6UPȁZ{zEd14h2&6#~yуőI ڀU02@9fTq!v함{7F 6i4#Gގ,\"#Y|BEq ,SRGlXXLm4h&,ttר7, ?y:Zb1, |ɢe꣸M"?ņ=m+("(Vm?7j;ALrjCX *?T+4Zu7*ZoV/)?(NM߸ ִRk8IQM 8m6IJʰ&3vgؒoʤXXF0qV"`4SUzaCLXK"&7 קglϳҔ;l6|ʟ">-$w_4feO,-u6qE"fLRhҪZk% 4yNঅW7g7l;dMKgDd&"gvN; ,j "Cs:PB@M@&=!gaLf2_*ou|w0 PoGʕ"Ods\T|dWsEuz 0lc 5E +x'ǮxT;pCaD?T)/g??+GChx 6.=>YOv*_?Dn"rӖyj.ˎK;6v[#^tH3Ƞ w0}O ;8%G8%Fy4sJB3YRβFnbhBc}g$an`,< 0؅L7h? P̶F9\d_GA?5YC '> ٰ&2ܯQȍHJ pRLxHE|-2Re=`AUKGJR qhqںe8C*4 T;&40TkCl;6ʳ\PC B0 Yq+@EjlCo3)ֽ1];!nbjc6 ]oPXs`]قp R_ DKbh:cDV1d;BkmkP$E3'f' r/)%|{@25Hባ8B >wW)!xGON}| HA:ĿGpK\eN8|G|h4O:=RIjʳhUO0D{гNV+ O2mSU{hCҙǥ'A 7 F0^TP 3TV@=YCjQٹZ}w|[v_\vqgC,N߽vV?@bf k: 7=brb@iZY]<t ՖD̝ |gvjԷL 'FER 6w|:Av;oД@~GގE|h*rGM,4uA@ߑێ?Ź@ P N>.UdNzs=n@"]1k|_it ^!0;6:ѵ>Nc7Ɨ!ODom`^1>`($):F{J޼K&5sB6Z`!x{_>hJ|] @XD6aoJoZ^M¢ԓXSТ }=@n+.R v#̭ ŵ.Q>>Ժ~p#y5zXT!OΌ]4w !d> \L4r-a4`D 7uBdU.ZqI(C44%@:/}ڊ[:J\E2́@}&@~֯.*xNpM)FA**Hs3[Epkشdʋ2<_ iꆢGnhagʾB Zk(B?h.ӂkR_qq<&֦7[-e٠E6H-=dN2vHV4=%@bD*LswuYÝ a` 2̈/ѺVk=j nmD# #zU #45 p V^Ǻ}ܣI~9fk5$40@*Kxe*Yj4}b9q-`ڛOZ,(B<ylV-Rj6'wkN>Z۱ ME-_OP? (P4N[447 IqqqC'(&`vLxĈr$7EJ½)h"@J휿FOWFIV{!{;#)v1ٓyW*Sso6Tn BJ&'!5|HV%A_jߖ/o hAb:?I_"EYA J餬LԚsP$:x\A 2&1M'#*l> r\TȪ-,;jH!R\[e->AD 0 D%:Aza/a^#1R>}TޟrTjU$"rVhS$#7S nn5 N/'}BI:rfUpL~ZL ޽A'HQڶPm{!@n3ӑtG4BP K^2\9pH.;lپC/ d##\/pDip%l?k#/9@nS tk=PObwxїLc6ҁ"-\w/{mN|[䊉z4m\DyjYzhd8'PWUhmq2:W1*YsTDm~ې[rd%t3zV`}/Kp{\C~Cil{=', G>C&M;B!:ϜL^,[4bm0lm_Pa={b еe-5tHܵ/P:4XE;UIOMCX!yiPC ,p>Ʋnel~/&wf&bSn CZ`9Bᔪ3Т3cLK4kBdCtrc9~<u5jɒC=rJb2䀟\D1Pحܓ؝A qGUDF;A, &>W $0BSK=_{tR)qxP{6aP/FJaJQrhy "5@#&UfF+laոQ|]tl؎Jחۣ62/❯IZ^Wt92ɏ? KF@~xF<9:rė܈1R*.&jG1XfX/hע!4)g3{hEΠմhH yr@2wSx_l7"j X]!@v *C}`ƶ!HVQp.1  jlIENDB`