为啥 Boost.Asio SSL 请求返回 405 Not Allowed?
Posted
技术标签:
【中文标题】为啥 Boost.Asio SSL 请求返回 405 Not Allowed?【英文标题】:Why Boost.Asio SSL request returns 405 Not Allowed?为什么 Boost.Asio SSL 请求返回 405 Not Allowed? 【发布时间】:2021-05-30 18:34:39 【问题描述】:我正在尝试通过these code 仅使用 Boost.Asio(不是 Network.Ts 或 Beast 或其他)向服务器发送 HTTPS 请求并接收页面内容:
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
int main()
boost::system::error_code ec;
using namespace boost::asio;
// what we need
io_service svc;
ssl::context ctx(ssl::context::method::tlsv1);
ssl::stream<ip::tcp::socket> ssock(svc, ctx);
ip::tcp::endpoint endpoint(boost::asio::ip::make_address("157.90.94.153",ec),443);
ssock.lowest_layer().connect(endpoint);
ssock.handshake(ssl::stream_base::handshake_type::client);
// send request
std::string request("GET /index.html HTTP/1.1\r\n\r\n");
boost::asio::write(ssock, buffer(request));
// read response
std::string response;
do
char buf[1024];
size_t bytes_transferred = ssock.read_some(buffer(buf), ec);
if (!ec) response.append(buf, buf + bytes_transferred);
while (!ec);
// print and exit
std::cout << "Response received: '" << response << "'\n";
但我在本地 PC 上不断收到 405 Not Allowed,在 Coliru 上不断收到 400 Bad Request。
我做错了什么?
【问题讨论】:
可能是tls版本试试ssl::context ctx(ssl::context::method::tlsv13_client); @pabolo12:如果是 TLS 问题,那么一开始就没有 HTTP 响应,即既不是 405 也不是 400。问题出在 HTTP 部分,而不是 TLS 部分。跨度> 【参考方案1】:... "GET /index.html HTTP/1.1\r\n\r\n"
这不是一个有效的 HTTP/1.1 请求。它至少还必须包含一个Host
字段,并且该字段的值必须符合服务器的期望,即
"GET /index.html HTTP/1.1\r\nHost: example.com\r\n\r\n"
一般来说,HTTP 可能看起来很简单,但实际上很复杂并且有几个陷阱。如果您确实需要自己做 HTTP,请研究标准。
【讨论】:
答案是正确的,但是你知道为什么和网络浏览器相比,为什么要花这么长时间才能得到请求的结果吗? @malloc:同样,这是关于理解 HTTP。简而言之:不要期望服务器在发送响应后立即关闭连接,因为 HTTP/1.1 默认启用了 HTTP keep-alive,即它正在等待同一 TCP 连接上的更多请求。与其等待连接关闭,不如只读取 HTTP 标头中指定的响应数据。有关这方面的更多信息,请参阅 HTTP 标准。以上是关于为啥 Boost.Asio SSL 请求返回 405 Not Allowed?的主要内容,如果未能解决你的问题,请参考以下文章
在 Boost.Asio 中同时使用 SSL 套接字和非 SSL 套接字?
boost::asio::ssl::context 可以在多个 SSL 流之间共享吗?
如何接受boost :: asio :: ssl :: stream 作为boost :: asio :: ip :: tcp :: socket类型的参数