为啥 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 抛出“未定义的引用”错误

如何接受boost :: asio :: ssl :: stream 作为boost :: asio :: ip :: tcp :: socket类型的参数

boost asio ssl async_shutdown 总是以错误结束?

多线程应用程序上的 boost::asio::ssl 访问冲突