使用Boost.Beast解析已接收POST请求的头部与请求体的技术咨询
Hey there! Let's work through your Boost.Beast HTTP parsing questions— I’ve spent plenty of time with Beast, so I’ll share practical, tested code examples to solve both of your issues.
First, let’s start with the foundational step: parsing your std::string buffer into a proper Boost.Beast request object. Once that’s done, extracting headers and the body becomes straightforward.
The key mistake many folks make is trying to iterate headers before fully parsing the request. Let’s start by parsing your buffer, then show two ways to iterate through headers.
Full Example Code
#include <boost/beast.hpp> #include <iostream> #include <string> namespace beast = boost::beast; namespace http = beast::http; int main() { // Your existing buffer with received POST data std::string buffer = "POST /api/endpoint HTTP/1.1\r\n" "Host: example.com\r\n" "Content-Type: application/json\r\n" "Content-Length: 18\r\n" "\r\n" "{\"key\": \"value\"}"; beast::error_code ec; http::request_parser<http::string_body> parser; // Parse the buffer content into the parser parser.put(beast::buffer(buffer.data(), buffer.size()), ec); if(ec) { std::cerr << "Parse error: " << ec.message() << "\n"; return 1; } // Signal end of input (critical for completing parsing) parser.put_eof(ec); if(ec) { std::cerr << "EOF parse error: " << ec.message() << "\n"; return 1; } // Get the fully parsed request auto req = parser.release(); // --- Iterate through headers --- std::cout << "=== HTTP Headers ===\n"; // Method 1: Range-based for loop (simplest and most readable) for(const auto& field : req.headers()) { std::cout << "* " << field.name_string() << ": " << field.value() << "\n"; } // Method 2: Explicit iterator approach (if you need fine-grained control) std::cout << "\n=== Headers via Iterators ===\n"; const auto& headers = req.headers(); for(auto it = headers.begin(); it != headers.end(); ++it) { std::cout << "* " << it->name_string() << ": " << it->value() << "\n"; } return 0; }
Why Your Iterator Attempt Might Have Failed
- You tried iterating before calling
put_eof(): Beast needs to know the input is complete to finalize the header structure. - You used the wrong iterator type:
req.headers()returns ahttp::headersobject, whose iterators point tohttp::field_valueinstances (not raw strings).
Since we’re using http::string_body for the request parser, the body is already stored as a std::string—extracting it is as simple as calling req.body().
Adding Body Extraction to the Example
Right after parsing the request, add this code:
// --- Extract Request Body --- std::cout << "\n=== Request Body ===\n"; std::string request_body = req.body(); std::cout << request_body << "\n";
Notes for Edge Cases
- If you’re dealing with large request bodies, consider using
http::file_bodyinstead ofstring_bodyto avoid loading the entire body into memory. - Ensure your buffer contains the full HTTP request (including the body). If you’re receiving data incrementally via Asio, using
http::readwith a socket directly is often easier than managing a manual buffer.
内容的提问来源于stack exchange,提问作者Jimmy

