如何在beast::websocket中读取错误请求的标头
How to read the header of a bad request in beast::websocket?
我有一个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);
}
});
WebSocket Upgrade请求的请求目标必须为原始形式。"localhost:2019/some_location"是绝对形式的,因此是非法的。在我看来,你想要的是能够专门处理不是WebSocket升级的HTTP请求,而对于实际的WebSocket更新,让WebSocket流通过执行握手来处理它。
文档中包含了这一点:https://www.boost.org/doc/libs/1_69_0/libs/beast/doc/html/beast/using_websocket/handshaking_servers.html#beast.using_websocket.handshaking_servers.passing_http_requests
此外,在示例中:https://github.com/boostorg/beast/blob/06efddd8b851610b5b3a5832ac87f1c52b838d9b/example/advanced/server/advanced_server.cpp#L665
tl;dr:使用beast::http::async_read
自己读取请求,看看它是否是使用beast::websocket::is_upgrade
的websocket升级。如果是升级,请构造beast::websocket::stream
并使用请求调用async_accept
,否则,请按照您想要的方式处理HTTP请求,并使用beast::http::async_write
自己发回响应。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 错误:请求非类类型为"MULTIMEDIA_FILME [500]"的成员|
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 为什么我收到来自谷歌的错误请求?
- 获取"rw_ssid"中成员"长度"的错误请求,该成员属于非类类型"char*"
- 构造函数请求错误的参数数
- 从谷歌日历API获取错误请求
- 错误:请求成员 .. 是非类类型"char"
- C++ Schannel POST 400 错误代码错误请求
- 错误:请求"数据"中的成员"大小",其非类类型为"int [5]"
- 如何制作一个根据拉取请求关闭和打开功能的构建系统?
- 错误:请求从"Mstream"转换为非标量类型"std::string {aka std::basic_string<char>}"
- NVDA屏幕阅读器请求错误的QAccessible::InterfaceType
- Winsock 400 错误请求,开放性
- 错误:请求从 std::chrono::time_point 浮点数转换为非标量类型长整型
- 错误:请求 中的成员属于非类类型
- Luci 无法启动请求的 CGI 程序:/www/cgi-bin/sample.cgi:执行错误
- X失败请求的错误:BadValue(整数参数超出操作范围)
- c++ Http 请求 SSL 错误
- "The requested URL /announce was not found on this server" bittorrent HTTP 请求的错误