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

如何在Guile web服务器中读取POST数据,guile,Guile,在Guile的web服务器中,我似乎找不到任何关于读取POST数据的文档。它似乎作为“body”和“request”一起发送到我的入口点函数。它看起来像是一个字节向量,我可以把它解码成一个字符串: (use-modules (rnrs bytevectors)) (utf8->string body) 因此,我可以从这里开始解析字符串,但这似乎相当繁琐且容易出错。没有办法将POST数据作为某种列表读取吗?这里是解码过程的代码,它将正文转换为列表的关联列表,其中键是表单字段的名称,值是与该

在Guile的web服务器中,我似乎找不到任何关于读取POST数据的文档。它似乎作为“body”和“request”一起发送到我的入口点函数。它看起来像是一个字节向量,我可以把它解码成一个字符串:

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

因此,我可以从这里开始解析字符串,但这似乎相当繁琐且容易出错。没有办法将POST数据作为某种列表读取吗?

这里是
解码
过程的代码,它将
正文
转换为列表的关联列表,其中键是表单字段的名称,值是与该键关联的值列表。请注意,
decode
返回的与assoc中给定键相关联的“值”始终是一个列表

(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)))
(定义模块(web解码))
(使用模块(ice-9匹配))
(使用模块(rnrs字节向量))
(使用模块(srfi srfi-1))
(使用模块(srfi srfi-26))
(使用模块(web uri))
;;;
;;; 解码
;;;
(定义(ACON列表)
“将V添加到列表中的K作为列表”
(let((值(关联参考列表k)))
(如果值为
(让((alist(alist删除k alist)))
(acons k(cons v值)列表)
(acons k(列表五)
(定义(列表->列表lst)
“基于键和值列表构建列表列表。
多个值可以与同一个键关联“
(让我们下一个((lst-lst)
(出"())
(如果(空?lst)
出来
(下一个(cdr lst)(ACON列表(caar lst)(cdar lst)输出()()))
(定义公共(解码bv)
“将BV查询字符串或表单数据转换为列表”
(定义字符串(utf8->字符串bv))
(定义对(映射(切割字符串拆分#\=)
分号和amp可以用作对分隔符
(附加映射(剪切字符串拆分)
(字符串拆分字符串#\&)))
(列表->列表(匹配lambda)
((键值)
(cons(uri解码键)(uri解码值)))对)

以下是
解码
程序的代码,该程序将
正文
转换为列表关联列表,其中键是表单字段的名称,值是与该键关联的值列表。请注意,
decode
返回的与assoc中给定键相关联的“值”始终是一个列表

(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)))
(定义模块(web解码))
(使用模块(ice-9匹配))
(使用模块(rnrs字节向量))
(使用模块(srfi srfi-1))
(使用模块(srfi srfi-26))
(使用模块(web uri))
;;;
;;; 解码
;;;
(定义(ACON列表)
“将V添加到列表中的K作为列表”
(let((值(关联参考列表k)))
(如果值为
(让((alist(alist删除k alist)))
(acons k(cons v值)列表)
(acons k(列表五)
(定义(列表->列表lst)
“基于键和值列表构建列表列表。
多个值可以与同一个键关联“
(让我们下一个((lst-lst)
(出"())
(如果(空?lst)
出来
(下一个(cdr lst)(ACON列表(caar lst)(cdar lst)输出()()))
(定义公共(解码bv)
“将BV查询字符串或表单数据转换为列表”
(定义字符串(utf8->字符串bv))
(定义对(映射(切割字符串拆分#\=)
分号和amp可以用作对分隔符
(附加映射(剪切字符串拆分)
(字符串拆分字符串#\&)))
(列表->列表(匹配lambda)
((键值)
(cons(uri解码键)(uri解码值)))对)

事实上,POST数据是正文,但它是使用一些RFC编码的,这在Guile中还不受支持。要解决这一问题,您可以做的是基于表单发送json,而不是执行原始HTTP POST…感谢您的回复,鉴于我在四处搜索替代信息并找到“Artanis”这是Guile的GNUWebServer框架,看起来它支持POST,并且更好地处理静态文件,这听起来更符合我的需要。所以我想我会研究一下。我不知道如何在artanis中支持POST表单?你能给你的问题贴个回复吗?这样我就可以投票了?德克萨斯州!很抱歉,我最后也没能在阿塔尼斯成功。但它的工作方式在这里有几个例子:我仍然期待着在未来能够用guile做到这一点,但我想它首先需要更多的开发(或者它已经在artanis中工作了,但我做得不对)事实上,POST数据是正文,但它是使用一些RFC编码的,这在Guile中还不受支持。要解决这一问题,您可以做的是基于表单发送json,而不是执行原始HTTP POST…感谢您的回复,鉴于我在搜索其他信息时发现的“Artanis”这是Guile的GNUWebServer框架,看起来它支持POST,并且更好地处理静态文件,这听起来更符合我的需要。所以我想我会研究一下。我不知道如何在artanis中支持POST表单?你能给你的问题贴个回复吗?这样我就可以投票了?德克萨斯州!很抱歉,我最后也没能在阿塔尼斯成功。但它的工作方式在这里有几个例子:我仍然期待着在未来能够用guile做到这一点,但我想它首先需要更多的开发(或者它已经在artanis中工作了,但我做得不对)我在github上有一个项目,我试图从guile stdlib收集所有缺失的片段我在github上有一个项目,我试图从guile stdlib收集所有缺失的片段