c++ - Boost asio 自定义 HTTP 服务器读取 HTTP post 请求

标签 c++ boost httpserver

我的 C++ 应用程序需要一个 HTTP 服务器,我决定自己做一个,它在发送 HTTP Get 请求时可以正常工作,但在读取 HTTP Post 请求时会出现一些问题。

问题是在发送 HTTP Posts 请求时,没有正确读取最后一个 header ,所以我无法获取 post 请求。

这是我的代码:

void HttpSession::readHeaders(std::shared_ptr<HttpSession> pThis) {
    boost::asio::async_read_until(pThis->socket_, pThis->buff_, '\r\n\r\n',
                              [pThis](const boost::system::error_code &e, std::size_t s) {
        std::istream headersStream(&pThis->buff_);
        std::string header;
        while(std::getline(headersStream, header, '\n')) {
            if(header != "\r") {
                if(header.back() == '\r') header = header.substr(0, header.length() - 1);
                qDebug() << QString::fromStdString(header);
                //Some stuff to get content-length to contentLength_
        }
    }

    if(contentLength_ > 0) {
        qDebug() << "Reading:";
        readBody(pThis);
    }

    std::shared_ptr<std::string> str = std::make_shared<std::string>(pThis->headers_.getResponse());
    boost::asio::async_write(pThis->socket_, boost::asio::buffer(str->c_str(), str->length()),
                             [pThis, str](const boost::system::error_code &e, std::size_t s) {
        qDebug() << "Written";
    });
}

void HttpSession::readBody(std::shared_ptr<HttpSession> pThis) {
    boost::asio::async_read(pThis->socket_, pThis->data_, boost::asio::transfer_at_least(1),
                              [pThis](const boost::system::error_code &e, std::size_t s) {
        std::istream body(&pThis->data_);
        std::string line;
        body >> line;
        qDebug() << QString::fromStdString(line);
    });
}

buff_data_ 变量声明为:boost::asio::streambufHttpSession 类是存储 header 并处理所有网页服务的类。我没有包含该类的代码,因为这不是问题所在。

对/url 的 HTTP Post 请求的输出是这样的:

"POST /url HTTP/1.1" 
"Host: 192.168.1.41:8080" 
"Connection: keep-alive" 
"Content-Length: 10" 
"Cache-Control: max-age=0" 
"Origin: http://192.168.1.41:8080" 
"Upgrade-Insecure-Requests: 1" 
"User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" 
"Content-Type: application/x-www-form-urlencoded" 
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" 
"Referer: http://192.168.1.41:8080/" 
"Accept-Encoding: gzip, deflate" 
"Accept-Langua" 
Reading:  
"ge:"

因此,如您所见,尽管在此图中您可以看到 POST 请求已正确发出,但 Accept-Language header 未正确读取。 this

请注意,发送 GET 请求时一切正常。所以我的猜测是它与异步读取有关,因为 async_read_until 不会阻塞,所以 readBody 函数的 async_read,在它应该之前阅读。那我应该同步阅读吗?如果我为每个客户端创建一个 HttpSession 类,我是否能够以任何一种方式处理多个客户端? (我真的不需要支持一个以上的用户,但仍然很好)。

对于客户端处理,我是这样做的:

void HttpServer::run() {
    using namespace boost::asio;
    io_service io_service;
    ip::tcp::endpoint endpoint{ip::tcp::v4(), 8080};
    ip::tcp::acceptor acceptor{io_service, endpoint};
    acceptor.listen();
    runServer(acceptor, io_service);

    io_service.run();

    while(true) QThread::msleep(5000);
}

void HttpServer::runServer(boost::asio::ip::tcp::acceptor& acceptor, boost::asio::io_service& io_service) {
    std::shared_ptr<HttpSession> ses = std::make_shared<HttpSession>(io_service);
    acceptor.async_accept(ses->socket_,
    [ses, &acceptor, &io_service](const boost::system::error_code& accept_error) {
       runServer(acceptor, io_service);
       if(!accept_error) HttpSession::interact(ses);
    });
}

所有类型的帮助将不胜感激!如果您有任何代码改进,请告诉我。谢谢!

最佳答案

我认为问题出在 '\r\n\r\n' 上。这不是字符串,而是 char

编译器通常会就此警告您,例如:

warning: implicit conversion from 'int' to 'char' changes value from 218762506 to 10 [-Wconstant-conversion]

尝试将其替换为 "\r\n\r\n"

关于c++ - Boost asio 自定义 HTTP 服务器读取 HTTP post 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39190756/

相关文章:

c++ - 制作索引序列元组

docker - 即使容器在 docker 中映射了端口,也从服务器获取空响应

Java httpServer 不同请求方式的基本认证

c++ - 使用#define 声明一个函数

c++ - 链接我的库的错误的多重定义

visual-studio-2010 - 使用 Visual Studio 2005 Boost Building

c++ - 为什么在 C++ 中使用 Boost 文件系统会出现链接器错误?

c++ - boost .Python : expose class member which is a pointer

javascript - node.js 使 HTTP 服务器的请求和响应全局化?

c++ - 如何使用 boost spirit 将字符串解析为元组 vector ?