有没有办法解析字符串中的HTTP请求并使用POCO获取其正文?

时间:2016-09-01 18:27:43

标签: c++ http-headers poco-libraries

我有一个用C ++编写的相当旧的服务器应用程序,我必须支持和开发。它的代码历史包含超过15年的开发历史。大多数代码都是手动编写的,包括网络部分。还有许多其他部件可以重新发明轮子,例如: Unicode支持等

我的主要目标是逐步用一些设计良好且支持的开源替代方案替换容易出错的轮式代码部分作为后台重构过程。网络代码是优先事项。但我不能一步到位。

目前我需要的是能够从字符串解析HTTP请求。我不需要发送或接收数据,旧代码执行它,我需要与它集成 - 至少现在。我需要阅读各种标题,获取URI并解析它 - 包括查询参数。

我遇到问题的部分是获取请求正文。使用HTTPRequest类无法实现这一目标。我在stream()类中看到了一个名为HTTPServerRequestImpl的方法,但该类似乎是HTTPServer的一些内部内容 - 如果没有会话,套接字,则无法构造它一些参数。

问题是 - 至少目前我不需要用POCO发出网络请求。还有其他一些库可以解决我当前的任务(httpxx,cpp-netlib),每个库都有自己缺少的功能,但从早期阶段集成POCO真的很棒,因为它看起来非常通用,强大且可以替代(我想)所有手动编写的旧代码在不久的将来。当然有一种方法可以用新行分隔请求,但如果存在,我真的更喜欢POCO标准工具。

这是我的POCO的测试项目代码(包含一些测试HTTP数据),也许它可以帮助某人或更好地了解我想如何使用该库:

#include <sstream>
#include <iostream>

#include <Poco/Net/HTTPRequest.h>
#include <Poco/URI.h>

int main()
{
    std::stringstream str;
    str <<
        "POST http://www.example.com/ajax/gw-light.php?api_version=1.0&api_token=1111&input=3&cid=23232 HTTP/1.1\n"
        "Host: www.example.com\n"
        "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0\n"
        "Accept: */*\n"
        "Accept-Language: en-US,en;q=0.7,uk;q=0.3\n"
        "Accept-Encoding: gzip, deflate\n"
        "Content-Type: text/plain;charset=UTF-8\n"
        "Origin: http://www.example.com\n"
        "Referer: http://www.example.com/album/10658860\n"
        "Content-Length: 331\n"
        "Cookie: __qca=dsgsfdgds; __utma=1234534543.5654604.1452342360.14123253.146543.84\n"
        "Connection: keep-alive\n"
        "\n"
        "[{\"method\":\"log.listen\",\"params\":{\"params\":{\"media\":{\"id\":\"72192840\",\"type\":\"song\"},\"type\":0,\"stat\":{\"seek\":0,\"pause\":0},\"lt\":235,\"ctxt\":{\"t\":\"artist_discography\",\"id\":7094080},\"payload\":{},\"dev\":{\"v\":\"00350497\",\"t\":0},\"ls\":[],\"ts_listen\":1472135022,\"timestamp\":1472747105},\"next_media\":{\"media\":{\"id\":\"72192841\",\"type\":\"song\"}}}}]\n";

    Poco::Net::HTTPRequest req;
    req.read( str );

    std::cout << "Host: " << req.getHost() << "\nMethod: " << req.getMethod() <<
            "\nUser-Agent: " << req.get( "User-Agent" ) << "\nURI: " << req.getURI() << std::endl;

    Poco::Net::NameValueCollection cookies;
    req.getCookies( cookies );
    for( auto curCookieIt = cookies.begin(); curCookieIt != cookies.end(); ++curCookieIt )
        std::cout << "Cookie: " << curCookieIt->first << "\n\tValue: " << curCookieIt->second << std::endl;

    Poco::URI uri( req.getURI() );
    auto params = uri.getQueryParameters();
    for( auto curParamIt = params.cbegin(); curParamIt != params.cend(); ++curParamIt )
        std::cout << curParamIt->first << " : " << curParamIt->second << std::endl;

    return 0;
}

1 个答案:

答案 0 :(得分:0)

HTTPRequest对象对请求主体一无所知。因此,您无法从HTTPRequest获取此信息。如果需要发送请求正文,请使用HTTPClientSession。来自文档:

  

要向HTTP服务器发送HTTP请求,请首先实例化HTTPClientSession对象并指定服务器的主机名和端口号。   然后创建一个HTTPRequest对象,相应地填充它,并将其作为参数传递给sendRequst()方法。   sendRequest()将返回一个输出流,可用于发送请求主体(如果有)。   完成发送请求主体后,创建一个HTTPResponse对象并将其传递给receiveResponse()。   这将返回一个可用于读取响应主体的输入流。