如何在Guile Web服务器中读取POST数据

时间:2017-10-09 22:44:04

标签: guile

在Guile的Web服务器上,我似乎无法找到有关读取POST数据的任何文档。它似乎与“请求”一起作为“正文”发送到我的入口点函数。看起来body被编码为bytevector,我可以将其解码为字符串:

(use-modules (rnrs bytevectors))
(utf8->string body)

所以从这里我可以继续解析字符串,但这似乎相当乏味且容易出错。有没有办法将POST数据作为某种列表读取?

1 个答案:

答案 0 :(得分:0)

以下是decode过程的代码,它将BODY转换为列表的关联列表,其中键是表单字段的名称,值是与之关联的值列表键。请注意"价值"与decode返回的关联中的给定键关联的列表始终是列表。

(define-module (web decode))

(use-modules (ice-9 match))
(use-modules (rnrs bytevectors))
(use-modules (srfi srfi-1))
(use-modules (srfi srfi-26))
(use-modules (web uri))

;;;
;;; decode
;;;

(define (acons-list k v alist)
  "Add V to K to alist as list"
  (let ((value (assoc-ref alist k)))
    (if value
        (let ((alist (alist-delete k alist)))
          (acons k (cons v value) alist))
        (acons k (list v) alist))))

(define (list->alist lst)
  "Build a alist of list based on a list of key and values.

   Multiple values can be associated with the same key"
  (let next ((lst lst)
             (out '()))
    (if (null? lst)
        out
        (next (cdr lst) (acons-list (caar lst) (cdar lst) out)))))

(define-public (decode bv)
  "Convert BV querystring or form data to an alist"
  (define string (utf8->string bv))
  (define pairs (map (cut string-split <> #\=)
                     ;; semi-colon and amp can be used as pair separator
                     (append-map (cut string-split <> #\;)
                                 (string-split string #\&))))
  (list->alist (map (match-lambda
                      ((key value)
                       (cons (uri-decode key) (uri-decode value)))) pairs)))