2017-08-27

(sph web html)

includes a multipart-form-data parser that can do stream/part-by-part reading/parsing and supports unlimited part nesting

status: tested, should work

see below for usage examples

part of sph-lib

module bindings

import name

(sph web html)

exports

html-fold-multipart-form-data

procedure

signature

proc-part proc-multipart result port [boundary] ->

::

procedure:{alist:header procedure:fold-lines:{string:line any:result procedure:next:{any:result ->} ->} result -> any}

procedure:{header port result ->} any port [string]

->

any

----

proc-multipart is only called for multipart/mixed.

a functional parser for multipart-form-data that allows to stop after any cr-lf-terminated line or part and reads content stream-like via a reader procedure

and supports nested multipart/mixed data.

see also html-read-multipart-form-data

html-multipart-form-data-ref

procedure

signature

a name ->

list string -> pair

description

for parsed multipart form data like html-read-multipart-form-data creates.

retrieves (alist:header . string:body) pairs by content-disposition name

html-multipart-form-data?

procedure

signature

headers [header-key] ->

(string ...) [string] -> boolean

html-parse-urlencoded-form-data

procedure

signature

request-body ->

string -> alist

description

parse an application/x-www-form-urlencoded string and result in an alist

html-read-multipart-form-data

procedure

signature

port [normalise-header-keys?] ->

port [procedure:{string -> string/any}] -> list

description

parses all multipart form data available on port into a list.

for stream-like and conditional parsing see html-fold-multipart-form-data

html-uri-decode

procedure

signature

str ->

string -> string

html-uri-encode

procedure

signature

r ->

string -> string

usage examples

"html-fold-multipart-form-data" is relatively complex as it takes custom procedures for several nested actions. below is an example that reads all data and saves it in a list. this is what the much simpler to use "html-read-multipart-form-data" does internally

(import (sph common) (sph web html))

(define-as example-data open-input-string
  "-----------------------------19737173311706079401624261242\r\nContent-Disposition: form-data; name=\"content\"\r\n\r\naeu\r\n-----------------------------19737173311706079401624261242\r\nContent-Disposition: form-data; name=\"names\"\r\n\r\n[\"a\",\"b\"]\r\n-----------------------------19737173311706079401624261242\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\ndocl\r\n-----------------------------19737173311706079401624261242--\r\n")

(html-fold-multipart-form-data
  (l (header fold-lines result)
    (fold-lines
      (l (line result next) (next (pair line result)))
      (list)
      (l (result-fold-lines result next-part)
        (next-part
          (pair
            (pair header
              (if (null? result-fold-lines) result-fold-lines
                (string-join
                  (reverse
                    (pair (string-drop-right (first result-fold-lines) 2)
                      (tail result-fold-lines)))
                  "")))
            result)))))
  (l (header port result) (pair (pair header (html-read-multipart-form-data port)) result)) (list)
  example-data)

the result

(((("Content-Disposition"
  ("form-data" . #t)
    ("name" . "type")))
  .
  "docl")
  ((("Content-Disposition"
    ("form-data" . #t)
    ("name" . "names")))
  .
  "[\"a\",\"b\"]")
  ((("Content-Disposition"
    ("form-data" . #t)
    ("name" . "content")))
  .
  "aeu"))

in this special case is in the same format that "html-read-multipart-form-data" gives and can be used with "html-multipart-form-data-ref"

(html-multipart-form-data-ref result "submit-name")
((("Content-Disposition"
  ("form-data" . #t)
  ("name" . "submit-name")))
  .
  "Larry")

tags: programming guile documentation library scheme sph-lib sph-web-html