C++ 如何在beast::websocket中读取错误请求的标头?

C++ 如何在beast::websocket中读取错误请求的标头?,c++,boost,boost-beast,beast-websockets,C++,Boost,Boost Beast,Beast Websockets,我有一个websocket服务器(侦听环回接口),它应该响应GET请求。我是这样做的 ws_.async_accept_ex( [self = shared_from_this()](websocket::response_type& res) // { if (res.result_int() == 400) { // bad request, assume HTTP GET osstream response;

我有一个websocket服务器(侦听环回接口),它应该响应GET请求。我是这样做的

ws_.async_accept_ex(
    [self = shared_from_this()](websocket::response_type& res) //
    {
        if (res.result_int() == 400) { // bad request, assume HTTP GET
            osstream response;
            /* invoke request handlers */
            for (auto& do_handle : self->handlers) {
                do_handle({ "GET" }, response);
                /* if responded, assing response to the body*/
                if (response.tellp()) {
                    res.content_length(response.str().size());
                    res.body() = std::move(response.str());
                    break;
                }
            }
        }
    },
    net::bind_executor(strand_,
        [self = shared_from_this()](beast::error_code ec) {
            self->on_accept(ec);
}));
但我还需要能够处理位置(比如
localhost:2019/some_location

有办法吗

解决方案:手动读取标题,检查是否为升级

beast::flat_buffer buffer_;
websocket::request_type req_;

/*
  ...
  ...
*/
        http::async_read(ws_.next_layer(), buffer_, req_,
        [self=shared_from_this()](beast::error_code ec, size_t)
        {
            if(ec){
                fail(ec, "[http] read");
                return;
            }
            if(websocket::is_upgrade(self->req_)){
                self->ws_.accept(self->req_,ec);
                self->on_accept(ec);
            }
            else{
                osstream response;
                websocket::response_type res;
                vector<string_view> req_args
                    { "GET", self->req_.base().target().begin() };
                /* invoke request handlers */ 
                for(auto &do_handle : self->handlers){
                    do_handle(req_args, response);
                    /* if responded, assing response to the body*/
                    if(response.tellp()){
                        res.content_length(response.str().size());
                        res.body() = std::move(response.str());
                        break;
                }}
                http::write(self->ws_.next_layer(), res);
            }
        });
beast::扁平缓冲区;
websocket::请求类型请求;
/*
...
...
*/
http::async_read(ws_uu.next_layer(),buffer_u,req_u,
[self=shared_from_this()](beast::error_code ec,size_t)
{
国际单项体育联合会(欧共体){
失败(ec,“[http]读取”);
返回;
}
if(websocket::is_升级(self->req_)){
self->ws.accept(self->req,ec);
自我->开启接受(ec);
}
否则{
骨流反应;
websocket::响应类型res;
矢量请求参数
{“GET”,self->req_u2;.base().target().begin()};
/*调用请求处理程序*/
用于(自动处理:自->处理程序){
do_句柄(请求参数、响应);
/*如果有响应,则为身体的assing响应*/
if(response.tellp()){
res.content_length(response.str().size());
res.body()=std::move(response.str());
打破
}}
http::write(self->ws_u.next_layer(),res);
}
});

WebSocket升级请求的请求目标必须为原始格式。“localhost:2019/some_location”是绝对形式,因此是非法的。在我看来,您想要的是能够专门处理非WebSocket升级的HTTP请求,对于实际的WebSocket升级,让WebSocket流通过执行握手来处理它

文件中包括了这一点:

并且在示例中:

tl;dr:使用
beast::http::async\u Read
自己读取请求,使用
beast::websocket::is\u upgrade
查看它是否是websocket升级。如果是升级,则构造
beast::websocket::stream
并在请求中调用
async\u accept
,否则以您想要的方式处理HTTP请求,并使用
beast::HTTP::async\u write
自己发送回响应