qq_45686724 2024-04-10 11:41 采纳率: 25%
浏览 14
已结题

boost搭建的http服务端接收文件失败

请问C++ 使用boost实现http服务端时,在接收form-data中的文件时,
文件超过1mb就会
报错:ec: beast.http:9
message: body limit exceeded
在网上找了几个设置请求体大小的方法没有作用

代码如下:

class http_connection : public std::enable_shared_from_this<http_connection>
{
public:
    http_connection(tcp::socket socket)
        : socket_(std::move(socket))
    {
    
    }

    // Initiate the asynchronous operations associated with the connection.
    void
        start()
    {
    
        read_request();
        check_deadline();
    }

private:
    // The socket for the currently connected client.
    tcp::socket socket_;

    // The buffer for performing reads.
    beast::flat_buffer buffer_;

    // The request message.
    http::request<http::dynamic_body> request_;
    

    // The response message.
    http::response<http::dynamic_body> response_;

    // The timer for putting a deadline on connection processing.
    net::steady_timer deadline_{
        socket_.get_executor(), std::chrono::seconds(60 * 20) };

    // Asynchronously receive a complete request message.
    void read_request()
    {
        auto self = shared_from_this();        
        http::async_read(
            socket_,
            buffer_,
            request_,        
            [self](beast::error_code ec,
                std::size_t bytes_transferred)
            {
                std::cout << "开始读取http接口数据 " << std::endl;
                boost::ignore_unused(bytes_transferred);
                std::cout << "1 " << std::endl;
                if (!ec) {
                    self->process_request();
                    std::cout << "2 " << std::endl;                
                }
                std::cout<< "ec: " << ec << std::endl;
                std::cout<< "message: " << ec.message() << std::endl;
                    
            });
        std::cout << "3 " << std::endl;
    }

    // Determine what needs to be done with the request message.
    void process_request()
    {
        std::cout << "选择接口请求方式 "<< request_.method() << std::endl;
        response_.version(request_.version());
        response_.keep_alive(false);

        switch (request_.method())
        {
        case http::verb::get:
            response_.result(http::status::ok);
            response_.set(http::field::server, "Beast");
            create_response();
            break;
        case http::verb::post:
            response_.result(http::status::ok);
            response_.set(http::field::server, "Beast");
            create_post_response();
            break;
        default:
            // We return responses indicating an error if
            // we do not recognize the request method.
            response_.result(http::status::bad_request);
            response_.set(http::field::content_type, "text/plain");
            beast::ostream(response_.body())
                << "Invalid request-method '"
                << std::string(request_.method_string())
                << "'";
            break;
        }

        write_response();
    }

  • 写回答

2条回答 默认 最新

  • 关注

    上午好☀️☀️☀️️
    本答案参考ChatGPT-3.5

    针对此问题,你可以参考以下方案以解决问题:

    1. 使用beast库中的body_limit(std::uint64_t limit)方法设置请求体的大小限制,而非手动读取和检查请求体大小。

    2. 检查是否有其它处理程序导致文件上传失败或卡顿,例如IO线程池是否处理缓慢或陷入死循环。

    3. 如果以上两个方案均无效,则可以尝试将文档类型设置为multipart/form-data或multipart/mixed,以确保正确地解析请求体。

    修改后的代码如下:

    注意:在 process_request() 方法中添加了 request_.body_limit(1024*1024),限制请求体大小为1MB。

    class http_connection : public std::enable_shared_from_this<http_connection> { public: http_connection(tcp::socket socket) : socket_(std::move(socket)) {

    }
    
    // Initiate the asynchronous operations associated with the connection.
    void start()
    {
    
        read_request();
        check_deadline();
    }
    

    private: // The socket for the currently connected client. tcp::socket socket_;

    // The buffer for performing reads.
    beast::flat_buffer buffer_;
    
    // The request message.
    http::request<http::dynamic_body> request_;
    
    
    // The response message.
    http::response<http::dynamic_body> response_;
    
    // The timer for putting a deadline on connection processing.
    net::steady_timer deadline_{
        socket_.get_executor(), std::chrono::seconds(60 * 20) };
    
    // Asynchronously receive a complete request message.
    void read_request()
    {
        auto self = shared_from_this();        
        http::async_read(
            socket_,
            buffer_,
            request_,        
            [self](beast::error_code ec,
                std::size_t bytes_transferred)
            {
                std::cout << "开始读取http接口数据 " << std::endl;
                boost::ignore_unused(bytes_transferred);
                std::cout << "1 " << std::endl;
                if (!ec) {
                    self->process_request();
                    std::cout << "2 " << std::endl;                
                }
                std::cout<< "ec: " << ec << std::endl;
                std::cout<< "message: " << ec.message() << std::endl;
                    
            });
        std::cout << "3 " << std::endl;
    }
    
    // Determine what needs to be done with the request message.
    void process_request()
    {
        request_.body_limit(1024*1024);  // 设置请求体大小限制为1MB
        std::cout << "选择接口请求方式 "<< request_.method() << std::endl;
        response_.version(request_.version());
        response_.keep_alive(false);
    
        switch (request_.method())
        {
        case http::verb::get:
            response_.result(http::status::ok);
            response_.set(http::field::server, "Beast");
            create_response();
            break;
        case http::verb::post:
            response_.result(http::status::ok);
            response_.set(http::field::server, "Beast");
            create_post_response();
            break;
        default:
            // We return responses indicating an error if
            // we do not recognize the request method.
            response_.result(http::status::bad_request);
            response_.set(http::field::content_type, "text/plain");
            beast::ostream(response_.body())
                << "Invalid request-method '"
                << std::string(request_.method_string())
                << "'";
            break;
        }
    
        write_response();
    }
    

    // ... };

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月16日
  • 创建了问题 4月10日

悬赏问题

  • ¥15 CCF-CSP 2023 第三题 解压缩(50%)
  • ¥30 comfyui openpose报错
  • ¥20 Wpf Datarid单元格闪烁效果的实现
  • ¥15 图像分割、图像边缘提取
  • ¥15 sqlserver执行存储过程报错
  • ¥100 nuxt、uniapp、ruoyi-vue 相关发布问题
  • ¥15 浮窗和全屏应用同时存在,全屏应用输入法无法弹出
  • ¥100 matlab2009 32位一直初始化
  • ¥15 Expected type 'str | PathLike[str]…… bytes' instead
  • ¥15 三极管电路求解,已知电阻电压和三级关放大倍数