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))
@JEIDATxoGvǻ[j.-ZMs^b9&\l}ӗsF2@v,LV7F `kNx+zcRtޫ!9qLAr?]]}ߏ lQo.-T$rA#x `sAŌ A XKt!`!YXH 1-dE5^cr!+G_Bj2(F,p'ͯ8$}a~$!6OQE47Z6ϱ6x(4jRHp^51O;ѴqT/WlU5cN1@ U8@V>0#` 8L=' qjdl>Đ,,A5ߞ q5C|b0$N3WMbsLncd.9rmGt{!R͔rsMs!e䈉Sk͕4B@SE0=cA`%Wpws1jp|s̏6h:P3lJj@s{v]nϣ}af1\j U Ebbv0Y̐R٘Yl39 '9Y+rxX#e^љ3jEenjY80_٫3^wٻ fSLJ{ؐLr[$m=^.9fp)e&IlFpM ܃`E#jn\q0 3܄f@hr%+jxqL0 ][T3fdٓ;pT0+Qس1SGaX۱/l&@NŲ>s5vЎ,*)n)޼f4*^nØ/h݀YR+RM,(CYհk (ފxk`fڗ0X6#2G&G)2aV3GxM-B2/'P '5v8nE4i3;Uw(CAr"Aftg#-x~p2ukT{?#ߘP{^Z|0p`Lz%O~G%4MMi:1*mQG6ԩQ"z4BU]HnhJ#p1mF*(62'Wc%@v"aXbA#ꅄN&^~Ԅr e`#S J!P"HTa&ק ѭiTtTujT>Me#j/kSaWkA@4WWTE򂀫B)FtE;fwi];NS^M'Snssgr@_h< '~y3H&!󗊁L2/SԸ$*'/^hPdGcn_̵ y޽,C?׾. L;c7oO5%ft᭣'][s$ =1=մre8J|&NNN԰χfM+6[zo,E7F"yq2T0Y_̫G 7 f]እǩTw1\{ SyR37G _HU_n.__0j`'թ"yu379 ] Pg/N0'^W,hTN)վ|0Ѩv-+!{u9 0~F%O!bYlD S]^&>Pmfm O;o60y_8p҄x;O NVnOgel:& [: gɀcaC#@ o?oԢ]3O§ ̠{,*5:$zOn~҅Vw//٨#V.߈q#QU8TUyN$_ufA)F[|YS-Tū%q?&&P<Ѱ=2/A%<4]o+HCLךּ "ںlf@XƎV50ϴ^(L7 Kt!yY5Ǻjװ<'fƋ-߬b s+QJA?ۃv!. V}ւXW}~^6`h4Sx}3MǹZ5-n˯ȬP9 CG`QHfᴶ lR?(^5ۂ1FokVc Gb<[+ge8 Z+<նL[K9G^+?pၧ #F+L/%a@~;?59"ͽ;w@{#Q3="U ZM<@Pt7+$w~Y$mgC }Pډ~Az`CoG>>騘Q MEx@BHs}.>zHgN d#R:O26ePڡh2&Wh(%u6#4u'SRsC1"WS|Zl5K>hg3c1oK)Dw]} /ߡȿ>,Yo!@w4W<z1GR~`sl#~DA0&SE5TQqMsé)sK U)B~9!Q׿ZUp vus|C,B+eepET.hN۲/p@4UFNzcۆ<X]߲ѡ98o3cH*ϖ{ 0$hС/} M`ï䇭j𢨶9~Lt? Y۶^^W.~CKg?OBwqz!蝽Ke^Pbٵl8:(@B֖ Dt{H*ң.67%I DA]FEL&CΖXxK&F ފ(!QP,oB3xr\ QU]Yɽ&Jբ4~hueLbpt4/Ï 07iŀeꞣ=@\AU`)cރbm*&ĝ%wtM U/clcX)WYPCR`.چM U%BA'Z+d`Z i'qbݕGͨL%}FՕpF ' 7We٢=Bc [􋾌w6\: MlsqGy2CZ`)>L/a9HBEGO{}!+א {rp5p ȄVt:#.w \1GQ:\yBռ YsWK4`0o!>^$#{ء_{=M:hGXޅģ{\M7r4K E@\E h4DoQ8Hť]Ƞ3ˁOʨcN+tp;kä:OK~'TTpQ~IϾ;pj8=8%10/4IΏSkԴ_ ,>_Ö?r at23P ,Ck4zv܂ˏ%Qk_n<x&E **42[7w{|}J%}L mΖ/6]l[$ꍂƁUF1)c;t!T&5ad/ACAI׆g=^RW_ 0!6)&G]Ҧ bӠ`@J+;#Iv_Tڭֆ֏a+J-}@+1ITX/:l4h B{}G'gSJc9\Ԍsi`pIENDB`