aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorW. Kosior <koszko@koszko.org>2025-03-27 12:51:39 +0100
committerW. Kosior <koszko@koszko.org>2025-03-27 13:08:42 +0100
commitcbc9d31f3eb2d1cf16bfd95598961af0740ef266 (patch)
tree01cc9a4378c584ab8ab6cfa6a317d1d0d041d8e2
parentbff3233287e0615e1aa4ce2be810c1a3a73f1d80 (diff)
downloadcantius-cbc9d31f3eb2d1cf16bfd95598961af0740ef266.tar.gz
cantius-cbc9d31f3eb2d1cf16bfd95598961af0740ef266.zip
(BREAKING!) Make monadic versions of helper procedures.
This, among others, removes `parse-request-multipart/form-data' and its asterisked variant. It insteads adds the monadic `multipart/form-data' procedure with an asterisked variant.
-rw-r--r--src/guile/cantius.scm71
-rw-r--r--tests/guile/cantius-test.scm74
2 files changed, 92 insertions, 53 deletions
diff --git a/src/guile/cantius.scm b/src/guile/cantius.scm
index d6d64a3..d7413fe 100644
--- a/src/guile/cantius.scm
+++ b/src/guile/cantius.scm
@@ -66,6 +66,29 @@
;;;
+;;; Cantius syntactic monad.
+;;;
+
+(eval-when (compile load eval)
+ (define-public $-args
+ '(cant$resource-roots
+ cant$redirect/normalize-path?
+ cant$redirect/remove-query?
+ cant$default-headers
+ cant$http-code-handlers
+ cant$other-http-codes-handler
+ cant$request
+ cant$body
+ cant$current-path
+ cant$current-endpoint
+ cant$endpoint-matched-path))
+
+ (export $)
+ (eval `(define-syntactic-monad $ . ,$-args) (current-module)))
+
+
+
+;;;
;;; Multipart form parser.
;;;
@@ -207,14 +230,13 @@
(utf8->string data-binary)))))))
parts))
-(define-public (parse-request-multipart/form-data request body)
- (match-let* ((content-type (assq-ref (req:request-headers request)
- 'content-type))
- (('multipart/form-data
- . (= (cut assq-ref <> 'boundary)
- (? identity boundary)))
- content-type))
- (parse-multipart/form-data boundary body)))
+(export multipart/form-data)
+($ define (multipart/form-data)
+ (match-let ((('multipart/form-data
+ . (= (cut assq-ref <> 'boundary) (? identity boundary)))
+ (req:request-content-type cant$request)))
+
+ (parse-multipart/form-data boundary cant$body)))
(define (parts->alist parts)
;; This shouldn't be strongly relevant but we make later parts appear
@@ -227,8 +249,8 @@
(define-public parse-multipart/form-data*
(compose parts->alist parse-multipart/form-data))
-(define-public parse-request-multipart/form-data*
- (compose parts->alist parse-request-multipart/form-data))
+(define-public multipart/form-data*
+ (compose parts->alist multipart/form-data))
@@ -320,6 +342,12 @@
(= match:end idx*))
(loop idx* `((,name . ,value) . ,cookies-alist))))))
+(export cookies)
+($ define (cookies)
+ (or (and=> (assq-ref (req:request-headers cant$request) 'cookie)
+ parse-cookies)
+ '()))
+
;; Sugar over `build-response', with support for easy redirects.
(export build-response*)
@@ -348,29 +376,16 @@
((keyword keyword-arg . rest)
(loop rest (cons* keyword-arg keyword filtered))))))
+(export response)
+($ define (response . rest)
+ (apply build-response* cant$default-headers rest))
+
;;;
-;;; Cantius syntactic monad and default values to use as its arguments.
+;;; Default values to use as monadic arguments.
;;;
-(eval-when (compile load eval)
- (define-public $-args
- '(cant$resource-roots
- cant$redirect/normalize-path?
- cant$redirect/remove-query?
- cant$default-headers
- cant$http-code-handlers
- cant$other-http-codes-handler
- cant$request
- cant$body
- cant$current-path
- cant$current-endpoint
- cant$endpoint-matched-path))
-
- (export $)
- (eval `(define-syntactic-monad $ . ,$-args) (current-module)))
-
(define %default-headers
'((content-type . (text/plain (charset . "utf-8")))))
diff --git a/tests/guile/cantius-test.scm b/tests/guile/cantius-test.scm
index 1e11586..4d9a6d6 100644
--- a/tests/guile/cantius-test.scm
+++ b/tests/guile/cantius-test.scm
@@ -13,7 +13,7 @@
((srfi srfi-45) #:select (delay force))
((ice-9 safe-r5rs) #:select (null-environment))
((ice-9 format) #:select (format))
- ((ice-9 match) #:select (match-let*))
+ ((ice-9 match) #:select (match-lambda))
((ice-9 regex) #:select (regexp-substitute/global))
((web client) #:select (open-socket-for-uri http-get))
((web request) #:prefix req:)
@@ -74,26 +74,29 @@ value
(tu:test-group "parse-multipart/form-data"
(for-each
(lambda (boundary)
- (match-let* ((form-data (form-data-good boundary))
- (data-bytevector (string->utf8 form-data))
- (data-length (bytevector-length data-bytevector))
- (request-text (format #f "\
+ (let* ((form-data (form-data-good boundary))
+ (data-bytevector (string->utf8 form-data))
+ (data-length (bytevector-length data-bytevector))
+ (request-text (format #f "\
GET /dummy HTTP/1.0
Host: example.com
Content-Type: multipart/form-data; boundary=~a
Content-Length: ~d
~a"
- boundary data-length form-data))
- ((request body) (call-with-input-string request-text
- (lambda (port)
- (let* ((request (req:read-request port))
- (body (req:read-request-body
- request)))
- (list request body)))))
- (parsed-alist (delay (cant:parse-request-multipart/form-data*
- request body)))
- (parsed (delay (reverse (map cdr (force parsed-alist))))))
+ boundary data-length form-data))
+
+ (parsed-alist
+ (delay (call-with-input-string request-text
+ (lambda (port)
+ (let* ((request (req:read-request port))
+ (body (req:read-request-body request)))
+ (cant:$ let*-values ((() (apply values cant:$-args)))
+ (cant:$ cant:multipart/form-data*
+ ((cant$request request)
+ (cant$body body)))))))))
+
+ (parsed (delay (reverse (map cdr (force parsed-alist))))))
(tu:test-eqv 3 (length (force parsed)))
(tu:test-equal (force parsed-alist)
@@ -142,15 +145,36 @@ Content-Length: ~d
(tu:test-equal '(("name" . "val"))
(cant:parse-cookies "name=val;"))
- (tu:test-equal '(("ses sion" . "fargtrg34")
- ("s" . "f")
- ("forms-session2" . "")
- ("forms-sessio n3" . "f4 3433=g = 4"))
- (cant:parse-cookies
- (string-append "\t\tses sion =fargtrg34;"
- " s = f;"
- "forms-session2=\n;"
- " forms-sessio n3=f4 3433=g = 4")))
+ (for-each (match-lambda
+ ((alist request-text)
+ (tu:test-equal alist
+ (cant:$ let*-values ((() (apply values
+ cant:$-args)))
+ (let ((request (call-with-input-string
+ request-text
+ req:read-request)))
+ (cant:$ cant:cookies
+ ((cant$request request))))))))
+ `(((("ses sion" . "fargtrg34")
+ ("s" . "f")
+ ("forms-session2" . "")
+ ("forms-sessio n3" . "f4 3433=g = 4"))
+ ,(format #f "\
+GET /dummy HTTP/1.0
+Host: example.com
+Cookie: ~
+~/~/ses sion =fargtrg34;~
+ s = f ;~
+forms-session2=~/;~
+ forms-sessio n3=f4 3433=g = 4
+
+"))
+ (()
+ "\
+GET /dummy HTTP/1.0
+Host: example.com
+
+")))
(tu:test-equal '() (cant:parse-cookies ""))
@@ -232,7 +256,7 @@ Content-Length: ~d
(cant:$ values ((cant$redirect/normalize-path? #f)
(cant$redirect/remove-query? #f))))
- (values (cant:build-response* cant$default-headers)
+ (values (cant:$ cant:response)
"Google provides the best services in the world..."))
(cant:define-endpoint %my-endset