ESPHome 2025.7.1
Loading...
Searching...
No Matches
multipart.h
Go to the documentation of this file.
1#pragma once
3#if defined(USE_ESP_IDF) && 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
13namespace esphome {
14namespace web_server_idf {
15
16// Wrapper around zorxx/multipart-parser for ESP-IDF OTA uploads
18 public:
19 struct Part {
20 std::string name;
21 std::string filename;
22 std::string content_type;
23 };
24
25 // IMPORTANT: The data pointer in DataCallback is only valid during the callback!
26 // The multipart parser passes pointers to its internal buffer which will be
27 // overwritten after the callback returns. Callbacks MUST process or copy the
28 // data immediately - storing the pointer for deferred processing will result
29 // in use-after-free bugs.
30 using DataCallback = std::function<void(const uint8_t *data, size_t len)>;
31 using PartCompleteCallback = std::function<void()>;
32
33 explicit MultipartReader(const std::string &boundary);
35
36 // Set callbacks for handling data
37 void set_data_callback(DataCallback callback) { data_callback_ = std::move(callback); }
38 void set_part_complete_callback(PartCompleteCallback callback) { part_complete_callback_ = std::move(callback); }
39
40 // Parse incoming data
41 size_t parse(const char *data, size_t len);
42
43 // Get current part info
44 const Part &get_current_part() const { return current_part_; }
45
46 // Check if we found a file upload
47 bool has_file() const { return !current_part_.filename.empty(); }
48
49 private:
50 static int on_header_field(multipart_parser *parser, const char *at, size_t length);
51 static int on_header_value(multipart_parser *parser, const char *at, size_t length);
52 static int on_part_data(multipart_parser *parser, const char *at, size_t length);
53 static int on_part_data_end(multipart_parser *parser);
54
55 multipart_parser *parser_{nullptr};
56 multipart_parser_settings settings_{};
57
58 Part current_part_;
59 std::string current_header_field_;
60
61 DataCallback data_callback_;
62 PartCompleteCallback part_complete_callback_;
63
64 void process_header_(const char *value, size_t length);
65};
66
67// ========== Utility Functions ==========
68
69// Case-insensitive string prefix check
70bool str_startswith_case_insensitive(const std::string &str, const std::string &prefix);
71
72// Extract a parameter value from a header line
73// Handles both quoted and unquoted values
74std::string extract_header_param(const std::string &header, const std::string &param);
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 of a string
82std::string str_trim(const std::string &str);
83
84} // namespace web_server_idf
85} // namespace esphome
86#endif // defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
void set_part_complete_callback(PartCompleteCallback callback)
Definition multipart.h:38
std::function< void()> PartCompleteCallback
Definition multipart.h:31
std::function< void(const uint8_t *data, size_t len)> DataCallback
Definition multipart.h:30
void set_data_callback(DataCallback callback)
Definition multipart.h:37
const Part & get_current_part() const
Definition multipart.h:44
MultipartReader(const std::string &boundary)
Definition multipart.cpp:16
size_t parse(const char *data, size_t len)
Definition multipart.cpp:41
bool str_startswith_case_insensitive(const std::string &str, const std::string &prefix)
bool parse_multipart_boundary(const char *content_type, const char **boundary_start, size_t *boundary_len)
std::string extract_header_param(const std::string &header, const std::string &param)
std::string str_trim(const std::string &str)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:229
uint16_t length
Definition tt21100.cpp:0