This commit is contained in:
J. Nick Koston 2025-06-29 10:53:29 -05:00
parent c366d555e9
commit 9047b02c92
No known key found for this signature in database
2 changed files with 29 additions and 18 deletions

View File

@ -10,28 +10,34 @@ static const char *const TAG = "multipart_parser";
bool MultipartParser::parse(const uint8_t *data, size_t len) { bool MultipartParser::parse(const uint8_t *data, size_t len) {
// Append new data to buffer // Append new data to buffer
buffer_.insert(buffer_.end(), data, data + len); if (data && len > 0) {
buffer_.insert(buffer_.end(), data, data + len);
}
bool made_progress = true;
while (made_progress && state_ != DONE && state_ != ERROR && !buffer_.empty()) {
made_progress = false;
while (state_ != DONE && state_ != ERROR && !buffer_.empty()) {
switch (state_) { switch (state_) {
case BOUNDARY_SEARCH: case BOUNDARY_SEARCH:
if (!find_boundary()) { if (find_boundary()) {
return false; state_ = HEADERS;
made_progress = true;
} }
state_ = HEADERS;
break; break;
case HEADERS: case HEADERS:
if (!parse_headers()) { if (parse_headers()) {
return false; state_ = CONTENT;
content_start_ = 0; // Content starts at current buffer position
made_progress = true;
} }
state_ = CONTENT;
content_start_ = 0; // Content starts at current buffer position
break; break;
case CONTENT: case CONTENT:
if (!extract_content()) { if (extract_content()) {
return false; // Content is ready, return to caller
return true;
} }
break; break;
@ -51,7 +57,7 @@ bool MultipartParser::get_current_part(Part &part) const {
part.name = current_name_; part.name = current_name_;
part.filename = current_filename_; part.filename = current_filename_;
part.content_type = current_content_type_; part.content_type = current_content_type_;
part.data = buffer_.data() + content_start_; part.data = buffer_.data();
part.length = content_length_; part.length = content_length_;
return true; return true;
@ -63,8 +69,8 @@ void MultipartParser::consume_part() {
} }
// Remove consumed data from buffer // Remove consumed data from buffer
if (content_start_ + content_length_ < buffer_.size()) { if (content_length_ < buffer_.size()) {
buffer_.erase(buffer_.begin(), buffer_.begin() + content_start_ + content_length_); buffer_.erase(buffer_.begin(), buffer_.begin() + content_length_);
} else { } else {
buffer_.clear(); buffer_.clear();
} }
@ -177,7 +183,7 @@ bool MultipartParser::extract_content() {
if (boundary_pos != std::string::npos) { if (boundary_pos != std::string::npos) {
// Found complete part // Found complete part
content_length_ = boundary_pos - content_start_; content_length_ = boundary_pos;
part_ready_ = true; part_ready_ = true;
return true; return true;
} }
@ -187,8 +193,8 @@ bool MultipartParser::extract_content() {
size_t safe_length = buffer_.size(); size_t safe_length = buffer_.size();
if (safe_length > search_boundary.length() + 4) { if (safe_length > search_boundary.length() + 4) {
safe_length -= search_boundary.length() + 4; safe_length -= search_boundary.length() + 4;
if (safe_length > content_start_) { if (safe_length > 0) {
content_length_ = safe_length - content_start_; content_length_ = safe_length;
// We have partial content but not complete yet // We have partial content but not complete yet
return false; return false;
} }

View File

@ -22,7 +22,12 @@ class MultipartParser {
size_t length; size_t length;
}; };
explicit MultipartParser(const std::string &boundary) : boundary_("--" + boundary), state_(BOUNDARY_SEARCH) {} explicit MultipartParser(const std::string &boundary)
: boundary_("--" + boundary),
state_(BOUNDARY_SEARCH),
content_start_(0),
content_length_(0),
part_ready_(false) {}
// Process incoming data chunk // Process incoming data chunk
// Returns true if a complete part is available // Returns true if a complete part is available