fix(libhttp): 请求体大小限制可配置并超限返回 413 (P1-1)
This commit is contained in:
1 parent
b37bf255d9
commit
da4957c52d
4 files changed
+36
-13
No files matched your search
@@ -115,6 +115,10 @@ public:
|
||||
|
||||
void setPrivateKeyPassword(const std::string& password);
|
||||
|
||||
// 请求体大小上限(字节)。默认 10MB,与 WAF 对齐;超限返回 413。
|
||||
void setMaxBodySize(std::size_t bytes) { max_body_size_ = bytes; }
|
||||
std::size_t getMaxBodySize() const { return max_body_size_; }
|
||||
|
||||
class debug {
|
||||
public:
|
||||
static void print_all_header_fields(const http::request<http::string_body>& req);
|
||||
@@ -129,6 +133,8 @@ private:
|
||||
unsigned int threads_;
|
||||
std::atomic<bool> running_{false};
|
||||
|
||||
std::size_t max_body_size_ = 10 * 1024 * 1024; // 默认 10MB,与 WAF 对齐
|
||||
|
||||
bool ssl_enabled_{false};
|
||||
std::string cert_file_;
|
||||
std::string key_file_;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <optional>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <boost/beast/websocket/ssl.hpp>
|
||||
@@ -112,6 +113,7 @@ private:
|
||||
beast::flat_buffer buffer_;
|
||||
beast::flat_buffer ws_buffer_;
|
||||
http::request<http::string_body> request_;
|
||||
std::optional<http::request_parser<http::string_body>> parser_;
|
||||
|
||||
HttpServer* server_;
|
||||
bool ssl_enabled_;
|
||||
|
||||
@@ -169,16 +169,19 @@ void HttpServer::Session::doRead() {
|
||||
request_ = {};
|
||||
buffer_.consume(buffer_.size());
|
||||
|
||||
// 使用 request_parser 并设置可配置的请求体上限(默认 10MB,超限返回 413)
|
||||
parser_.emplace();
|
||||
parser_->body_limit(server_->max_body_size_);
|
||||
|
||||
auto on_read = [self](beast::error_code ec, std::size_t) {
|
||||
if (!ec) self->request_ = self->parser_->release();
|
||||
self->handleRead(ec);
|
||||
};
|
||||
|
||||
if (ssl_enabled_ && ssl_stream_) {
|
||||
http::async_read(*ssl_stream_, buffer_, request_,
|
||||
[self](beast::error_code ec, std::size_t) {
|
||||
self->handleRead(ec);
|
||||
});
|
||||
http::async_read(*ssl_stream_, buffer_, *parser_, on_read);
|
||||
} else {
|
||||
http::async_read(stream_, buffer_, request_,
|
||||
[self](beast::error_code ec, std::size_t) {
|
||||
self->handleRead(ec);
|
||||
});
|
||||
http::async_read(stream_, buffer_, *parser_, on_read);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +253,16 @@ void HttpServer::Session::handleRead(beast::error_code ec) {
|
||||
|
||||
auto req_copy = std::move(request_);
|
||||
processRequest(std::move(req_copy));
|
||||
} else if (ec == http::error::body_limit) {
|
||||
// 请求体超过上限 → 返回 413 并关闭连接
|
||||
auto resp = std::make_shared<http::response<http::string_body>>();
|
||||
resp->version(11); // request_ 在超限时未成功解析,固定 HTTP/1.1
|
||||
resp->result(http::status::payload_too_large);
|
||||
resp->set(http::field::content_type, "text/plain");
|
||||
resp->set(http::field::connection, "close");
|
||||
resp->body() = "413 Payload Too Large\n";
|
||||
resp->prepare_payload();
|
||||
doWrite(resp);
|
||||
} else if (ec != http::error::end_of_stream) {
|
||||
std::cerr << "[Read] Error from " << remote_ip_ << ":" << remote_port_
|
||||
<< ": " << ec.message() << std::endl;
|
||||
|
||||
Reference in new issue
Block a user