DeterministicESPAsyncWebServer 1.2.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
multipart.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file multipart.h
6 * @brief In-place multipart/form-data parser (RFC 7578).
7 *
8 * Parses the body already stored in `HttpReq::body[]`. The parser modifies
9 * the body buffer in-place by inserting null terminators, so `part->data`
10 * pointers are valid only while the `HttpReq` lives (before `http_reset()`).
11 *
12 * **Limitations**
13 * - Maximum parts: `MAX_MULTIPART_PARTS` (default 4).
14 * - Maximum total body size: `BODY_BUF_SIZE` bytes.
15 * - Binary payloads containing the boundary string will be truncated.
16 * - Only `name` and `filename` are extracted from Content-Disposition;
17 * other parameters are ignored.
18 * - Boundary value must be ≤ `MAX_BOUNDARY_LEN` bytes (RFC 2046 cap: 70).
19 *
20 * @author Douglas Quigg (dstroy0)
21 * @date 2026
22 */
23
24#ifndef DETERMINISTICESPASYNCWEBSERVER_MULTIPART_H
25#define DETERMINISTICESPASYNCWEBSERVER_MULTIPART_H
26
27#include "DetWebServerConfig.h"
28#include "presentation.h" // for HttpReq, http_get_header
29
30// ---------------------------------------------------------------------------
31// Data types
32// ---------------------------------------------------------------------------
33
34/**
35 * @brief One parsed part from a multipart body.
36 *
37 * All char* fields point into the (modified) `HttpReq::body[]` buffer.
38 * They are null-terminated and valid until `http_reset()` is called.
39 */
41{
42 const char *name; ///< Form field name from Content-Disposition, or nullptr.
43 const char *filename; ///< Upload filename from Content-Disposition, or nullptr.
44 const char *type; ///< Content-Type of this part, or nullptr.
45 const char *data; ///< Part body (null-terminated in-place).
46 size_t data_len; ///< Part body length in bytes (not counting the null).
47};
48
49/**
50 * @brief Container for all parsed parts of a multipart body.
51 */
53{
55 int part_count; ///< Number of valid entries in parts[].
56};
57
58// ---------------------------------------------------------------------------
59// Public API
60// ---------------------------------------------------------------------------
61
62/**
63 * @brief Parse the body of @p req as multipart/form-data.
64 *
65 * Reads the boundary from the `Content-Type` header, then scans
66 * `req->body` in-place, null-terminating each part's headers and data.
67 *
68 * @param req Fully-parsed HTTP request (must be in PARSE_COMPLETE state).
69 * @param mp Output structure; filled on success.
70 * @return true if at least one part was found, false on parse error.
71 */
72bool multipart_parse(HttpReq *req, Multipart *mp);
73
74/**
75 * @brief Look up a field value across all parsed parts by name.
76 *
77 * Returns the data pointer of the first part whose `name` matches @p field.
78 * Useful for simple form submissions where each field has a unique name.
79 *
80 * @param mp Parsed multipart result.
81 * @param field Form field name to search for.
82 * @return Part data (null-terminated), or nullptr if not found.
83 */
84const char *multipart_get_field(const Multipart *mp, const char *field);
85
86#endif
User-facing configuration for DeterministicESPAsyncWebServer.
#define MAX_MULTIPART_PARTS
Maximum simultaneously parsed multipart parts per request.
const char * multipart_get_field(const Multipart *mp, const char *field)
Look up a field value across all parsed parts by name.
bool multipart_parse(HttpReq *req, Multipart *mp)
Parse the body of req as multipart/form-data.
Definition multipart.cpp:39
Layer 6 (Presentation) — wires the transport ring buffer to the HTTP parser.
Fully-parsed HTTP/1.1 request.
One parsed part from a multipart body.
Definition multipart.h:41
const char * data
Part body (null-terminated in-place).
Definition multipart.h:45
const char * type
Content-Type of this part, or nullptr.
Definition multipart.h:44
size_t data_len
Part body length in bytes (not counting the null).
Definition multipart.h:46
const char * name
Form field name from Content-Disposition, or nullptr.
Definition multipart.h:42
const char * filename
Upload filename from Content-Disposition, or nullptr.
Definition multipart.h:43
Container for all parsed parts of a multipart body.
Definition multipart.h:53
MultipartPart parts[MAX_MULTIPART_PARTS]
Parsed parts.
Definition multipart.h:54
int part_count
Number of valid entries in parts[].
Definition multipart.h:55