【问题标题】:HTTP post request parserHTTP post 请求解析器
【发布时间】:2020-05-03 09:49:36
【问题描述】:

我打算在我的服务器代码中解析从客户端收到的 http POST 请求。我正在使用 Postman 应用程序使用 POST 方法将文件发送到服务器。我的问题是如何解析服务器端的 POST 请求。我的服务器代码是 C++ 客户端将使用 POST 请求发送一个 ~80MB 的文件。 我引用了示例代码,但没有一个显示如何使用传入文件解析 POST 请求。

https://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/example/http/server/

有人可以帮忙指出一个示例代码吗?

问候

【问题讨论】:

  • 您链接了 Boost 1.36.0?你用这个版本吗?您可以使用 Boost.Beast 吗?它有一个请求类,可让您访问正文。 boost::beastboost::beast::http::request
  • 代码与Makefile中的-lboost_system链接。
  • boost_system与网络或http有什么关系? Boost 1.36.0 已经 12 岁了。你应该更新它。
  • 我认为 @ThomasSablik 的意思是您链接了文档(使用 markdown hyperlink,而不是链接任何特定库。

标签: c++ rest http boost boost-asio


【解决方案1】:

让我们开始接受端口 8081 上的单个连接:

net::io_context io;
tcp::acceptor a(io, {{}, 8081});

tcp::socket s(io);
a.accept(s);

现在,让我们读取一个 HTTP 请求:

http::request<http::string_body> req;
net::streambuf buf;
http::read(s, buf, req);

就是这样。我们可以打印一些详细信息,并发送响应。假设我们要保存上传的文件:

std::cout << "Writing " << req.body().size() << " bytes to " << fname << "\n";
std::ofstream(fname) << req.body();

让我们也将整个有效负载作为响应内容发回:

    http::response<http::string_body> response;
    response.reason("File was accepted");
    response.body() = std::move(req.body());
    response.keep_alive(false);
    response.set("XXX-Filename", fname);

    http::write(s, response);

完整演示

Live On Coliru

#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/beast/http.hpp>
#include <boost/optional/optional_io.hpp>
#include <iostream>
#include <fstream>

namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using net::ip::tcp;
using namespace std::string_literals;

static std::string const fname = "upload.txt";

int main() {
    net::io_context io;
    tcp::acceptor a(io, {{}, 8081});

    tcp::socket s(io);
    a.accept(s);

    std::cout << "Receiving request from " << s.remote_endpoint() << "\n";

    http::request<http::string_body> req;
    net::streambuf buf;
    http::read(s, buf, req);

    std::cout << "Method: " << req.method() << "\n";
    std::cout << "URL: " << req.target() << "\n";
    std::cout << "Content-Length: "
        << (req.has_content_length()? "explicit ":"implicit ")
        << req.payload_size() << "\n";

    std::cout << "Writing " << req.body().size() << " bytes to " << fname << "\n";
    std::ofstream(fname) << req.body();

    {
        http::response<http::string_body> response;
        response.reason("File was accepted");
        response.body() = std::move(req.body());
        response.keep_alive(false);
        response.set("XXX-Filename", fname);

        http::write(s, response);
    }
}

使用 CLI POST 实用程序(例如 Ubuntu 上的 apt install libwww-perl)进行测试时:

POST http://localhost:8081/this/url?id=$RANDOM -H 'Host: demo.site' -H 'CustomHeader' -E -C 'user:password' < test.cpp

它将打印如下内容:

POST http://localhost:8081/this/url?id=31912
Host: demo.site
User-Agent: lwp-request/6.31 libwww-perl/6.31
Content-Length: 1300
Content-Type: application/x-www-form-urlencoded
CustomHeader: 

200 File was accepted
Connection: close
Client-Date: Sun, 03 May 2020 20:58:58 GMT
Client-Peer: 127.0.0.1:8081
Client-Response-Num: 1
XXX-Filename: upload.txt

#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/beast/http.hpp>
#include <boost/optional/optional_io.hpp>
...

随后是 test.cpp 文件的其余部分

您可以在没有 POST 的情况下执行类似的请求,例如使用curl:

curl http://127.0.0.1:8081/this/url?id=$RANDOM -H 'Host: demo.site' -d @test.cpp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多