ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
multipart.h
Go to the documentation of this file.
1#pragma once
3#if defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
4
5#include <cctype>
6#include <cstring>
7#include <esp_http_server.h>
8#include <functional>
9#include <multipart_parser.h>
10#include <string>
11#include <utility>
12
14
15// Wrapper around zorxx/multipart-parser for ESP-IDF OTA uploads
17 public:
18 struct Part {
19 std::string name;
20 std::string filename;
21 std::string content_type;
22 };
23
24 // IMPORTANT: The data pointer in DataCallback is only valid during the callback!
25 // The multipart parser passes pointers to its internal buffer which will be
26 // overwritten after the callback returns. Callbacks MUST process or copy the
27 // data immediately - storing the pointer for deferred processing will result
28 // in use-after-free bugs.
29 using DataCallback = std::function<void(const uint8_t *data, size_t len)>;
30 using PartCompleteCallback = std::function<void()>;
31
32 explicit MultipartReader(const std::string &boundary);
34
35 // Set callbacks for handling data
36 void set_data_callback(DataCallback &&callback) { data_callback_ = std::move(callback); }
37 void set_part_complete_callback(PartCompleteCallback &&callback) { part_complete_callback_ = std::move(callback); }
38
39 // Parse incoming data
40 size_t parse(const char *data, size_t len);
41
42 // Get current part info
43 const Part &get_current_part() const { return current_part_; }
44
45 // Check if we found a file upload
46 bool has_file() const { return !current_part_.filename.empty(); }
47
48 private:
49 static int on_header_field(multipart_parser *parser, const char *at, size_t length);
50 static int on_header_value(multipart_parser *parser, const char *at, size_t length);
51 static int on_part_data(multipart_parser *parser, const char *at, size_t length);
52 static int on_part_data_end(multipart_parser *parser);
53
54 multipart_parser *parser_{nullptr};
55 multipart_parser_settings settings_{};
56
57 Part current_part_;
58 std::string current_header_field_;
59
60 DataCallback data_callback_;
61 PartCompleteCallback part_complete_callback_;
62
63 void process_header_(const char *value, size_t length);
64};
65
66// ========== Utility Functions ==========
67
68// Case-insensitive string prefix check
69bool str_startswith_case_insensitive(const char *str, size_t str_len, const char *prefix);
70
71// Extract a parameter value from a header line
72// Handles both quoted and unquoted values
73// Assigns to out if found, clears out otherwise
74void extract_header_param(const char *header, size_t header_len, const char *param, std::string &out);
75
76// Parse boundary from Content-Type header
77// Returns true if boundary found, false otherwise
78// boundary_start and boundary_len will point to the boundary value
79bool parse_multipart_boundary(const char *content_type, const char **boundary_start, size_t *boundary_len);
80
81// Trim whitespace from both ends, assign result to out
82void str_trim(const char *str, size_t len, std::string &out);
83
84} // namespace esphome::web_server_idf
85#endif // defined(USE_ESP32) && defined(USE_WEBSERVER_OTA)
void set_part_complete_callback(PartCompleteCallback &&callback)
Definition multipart.h:37
std::function< void()> PartCompleteCallback
Definition multipart.h:30
std::function< void(const uint8_t *data, size_t len)> DataCallback
Definition multipart.h:29
const Part & get_current_part() const
Definition multipart.h:43
MultipartReader(const std::string &boundary)
Definition multipart.cpp:15
void set_data_callback(DataCallback &&callback)
Definition multipart.h:36
size_t parse(const char *data, size_t len)
Definition multipart.cpp:40
void extract_header_param(const char *header, size_t header_len, const char *param, std::string &out)
bool parse_multipart_boundary(const char *content_type, const char **boundary_start, size_t *boundary_len)
void str_trim(const char *str, size_t len, std::string &out)
bool str_startswith_case_insensitive(const char *str, size_t str_len, const char *prefix)
std::string size_t len
Definition helpers.h:817
uint16_t length
Definition tt21100.cpp:0