std1.0.0-beta-7 SafeC docs

Source http/multipart.h

View in the repository

// SafeC Standard Library — multipart/form-data (RFC 7578): parsing an
// HTML form upload on the server, building one for a client request.
//
//   int ok = 0;
//   struct MultipartForm form = std::MultipartForm::from_request(req, &ok);
//   match (form.get("avatar")) {
//       case some(p): { /* p.filename, p.content_type, p.data (binary-safe String) */ }
//       case null: { }
//   }
//   form.free();
#pragma once
#include <std/http/http.h>
#include <std/http/headers.h>
#include <std/collections/string.h>
#include <std/collections/vec.h>

namespace std {

struct MultipartPart {
    struct String      name;          // Content-Disposition name=
    struct String      filename;      // filename= (empty for a plain field)
    int                has_filename;  // 1 if filename= was present (even empty)
    struct String      content_type;  // the part's Content-Type ("text/plain" if absent)
    struct HttpHeaders headers;       // all of the part's headers
    struct String      data;          // the body, binary-safe (use .length())
};

struct MultipartForm {
    struct Vec<struct MultipartPart> parts;

    // Parses a body given its Content-Type header value (which carries the
    // boundary). *ok = 0 on a missing boundary, a missing closing
    // delimiter or a part without headers.
    static struct MultipartForm parse(const &char content_type, const &unsigned char body,
                                      unsigned long len, ?&int ok);
    // parse() on a request's Content-Type and body.
    static struct MultipartForm from_request(const &HttpRequest req, ?&int ok);

    unsigned long length() const;
    // The first part named 'name', or null; aliases this form's storage.
    ?&MultipartPart get(const &char name);
    ?&MultipartPart part_at(unsigned long i);
    // A plain field's text (its data), or null.
    const ?&char    value(const &char name) const;
    void            drop();
    void            free() consume;   // = drop()
};

// Builds a multipart/form-data body.
struct MultipartBuilder {
    struct String boundary;
    struct String body;

    // A random boundary.
    static struct MultipartBuilder new();
    void add_field(const &char name, const &char value);
    void add_file(const &char name, const &char filename, const &char content_type, []const unsigned char data);
    // internal: the (reference, length) core of add_file()
    void add_file_n_(const &char name, const &char filename, const &char content_type,
                  const &unsigned char data, unsigned long len);
    // "multipart/form-data; boundary=..." for the Content-Type header.
    struct String content_type() const;
    // Appends the closing delimiter; 'body' is then complete.
    void finish();
    void drop();
    void free() consume;   // = drop()
};

} // namespace std