package http-multipart-formdata

  1. Overview
  2. Docs

Http_multipart_formdata is a non-blocking, streaming HTTP multipart/formdata parser. Its design is based on two main ideas:

  • The parser should stream the results as soon as possible in a non-buffered, non-backtracking manner; and
  • The parser input must be non-blocking and incremental in nature.

The parser implements HTTP multipart/form-data standard as defined in RFC 7578.

Types

type reader

reader represents a HTTP multipart formdata reader.

and read = [
  1. | `End
    (*

    The reader has completed reading.

    *)
  2. | `Header of part_header
    (*

    Multipart part header data.

    *)
  3. | `Body of Cstruct.t
    (*

    Multipart part body data.

    *)
  4. | `Body_end
    (*

    reader has completed reading the Multipart body data.

    *)
  5. | `Awaiting_input of [ `Cstruct of Cstruct.t | `Eof ] -> read
    (*

    The reader is waiting for it to be provided with input data. This is only returned when `Incremental is chosen as input.

    *)
  6. | `Error of string
    (*

    Represents an error in input data.

    *)
]

read represents both the current state and data read by a reader.

and input = [
  1. | `Cstruct of Cstruct.t
    (*

    A bigstring input.

    *)
  2. | `Incremental
    (*

    The caller of the library periodically provides input to the parser.

    *)
]
and part_header

Represents a parsed multipart part header data.

and boundary

Represents the multipart boundary value.

and field_name = string

A form field name

and part_body = string

A Multipart body

Mulipart Boundary parser

val boundary : string -> (boundary, string) Stdlib.result

boundary content_type parses content_type to extract boundary value. content_type is the HTTP request Content-Type header value.

let content_type =
  "multipart/form-data; \
   boundary=---------------------------735323031399963166993862150"
in
Http_multipart_formdata.boundary content_type

Streaming Multipart

API to stream multipart parts. Use these functions when you have to handle HTTP form submissions which has large file uploads and at the same time be memory efficient.

val reader : ?read_buffer_size:int -> boundary -> input -> reader

reader ?read_buffer_size boundary input creates reader. The default value for read_buffer_size is 1KB.

val read : reader -> read

read reader returns data read by reader.

val unconsumed : reader -> Cstruct.t

unconsumed reader returns any leftover data still remaining after reader returns `End.

Non-Streaming Multipart

Use these functions if the HTTP form submission is of a relatively small size.

val parts : boundary -> string -> ((field_name * (part_header * part_body)) list, string) Stdlib.result

parts boundary http_body returns a list of HTTP multipart parts parsed in http_body.

The returned parts list is keyed to a form field name so that one can do:

let parts_kv = parts boundary http_body in
match List.assoc_opt "field1" parts_vk with
| Some v -> ...
| None -> ..

Part header

val name : part_header -> string

name t returns the form field name.

val content_type : part_header -> string

content_type t returns the part content-type.

val filename : part_header -> string option

filename t returns the uploaded filename if the multipart is a file.

val find : string -> part_header -> string option

find name t returns the multipart parameter value associated with name.

Pretty Printers

val pp_part_header : Stdlib.Format.formatter -> part_header -> unit
val pp_read_result : Stdlib.Format.formatter -> read -> unit
val pp_boundary : Stdlib.Format.formatter -> boundary -> unit