#lang scheme/base
(require scheme/contract
mzlib/trace
(prefix-in ws: web-server/http/cookie-parse)
(prefix-in ws: web-server/http/cookie)
(prefix-in ws: web-server/http/request-structs)
(prefix-in ws: net/cookie)
"request.ss"
)
(define-struct cookie (name value domain path max-age comment secure?))
(define $cookies (make-parameter '()))
(define (ws:client-cookie->cookie c)
(make-cookie (ws:client-cookie-name c)
(ws:client-cookie-value c)
#f
#f
#f
#f
#f
))
(define (init-cookies!)
(map (lambda (c)
(let ((c (ws:client-cookie->cookie c)))
(cons (cookie-name c) c)))
(ws:request-cookies ($request))))
(define (cookie-set! name value
#:domain (domain #f)
#:path (path #f)
#:max-age (max-age #f)
#:comment (comment #f)
#:secure? (secure? #f))
($cookies (cons (cons name (make-cookie name value domain path max-age comment secure?))
($cookies))))
(define (cookie-ref name)
(let ((kv (assoc name ($cookies))))
(if kv (cdr kv) #f)))
(define (cookie-del! name)
(let ((kv (assoc name ($cookies))))
($cookies (if kv
(filter (lambda (c)
(not (equal? kv c)))
($cookies))
($cookies)))))
(define (cookie->header c)
(define (helper c)
(ws:make-header #"Set-Cookie"
(string->bytes/utf-8
(regexp-replace #px"Path=\\\"/\\\""
(ws:print-cookie c)
"Path=/"))))
(helper
(ws:make-cookie (cookie-name c)
(cookie-value c)
#:domain (cookie-domain c)
#:path (cookie-path c)
#:max-age (cookie-max-age c)
#:comment (cookie-comment c)
#:secure? (cookie-secure? c))))
(define ($cookies->headers)
(map (lambda (kv)
(cookie->header (cdr kv)))
($cookies)))
(provide/contract
(struct cookie ((name string?)
(value string?)
(domain (or/c #f string?))
(path (or/c #f string?))
(max-age (or/c #f exact-nonnegative-integer?))
(comment (or/c #f string?))
(secure? boolean?)))
($cookies (parameter/c (listof (cons/c string? cookie?))))
(init-cookies! (-> (listof (cons/c string? cookie?))))
(cookie->header (-> cookie? ws:header?))
($cookies->headers (-> (listof ws:header?)))
(cookie-set! (->* (string? string?)
(#:domain (or/c #f string?)
#:path (or/c #f string?)
#:max-age (or/c #f exact-nonnegative-integer?)
#:comment (or/c #f string?)
#:secure? boolean?)
any))
(cookie-ref (-> string? (or/c #f cookie?)))
(cookie-del! (-> string? any))
)