简体   繁体   English

有没有一种方法可以解析来自字符串的HTTP请求并使用POCO获取其主体?

[英]Is there a way to parse an HTTP request from a string and get its body using POCO?

I have a pretty old server application written in C++ which I have to support and develop. 我有一个非常老的用C ++编写的服务器应用程序,我必须支持和开发它。 Its code history consists of more than 15 years of development. 它的代码历史包括15多年的开发经验。 Most of the code is written manually, including net parts. 大部分代码是手动编写的,包括网络部分。 There are many other parts which reinvent the wheel, eg Unicode support, etc. 还有许多其他方面可以重新发明轮子,例如Unicode支持等。

My main goal is to gradually substitute bug-prone wheel-ish parts of code with some well designed and supported open source alternatives as a background refactoring process. 我的主要目标是用一些经过良好设计和支持的开源替代品逐渐替换易出错的代码部分,作为后台重构过程。 Net code is priority. 净代码优先。 But I can't do it in one step. 但是我不能一step而就。

Currently what I need is the ability to parse an HTTP request from string. 目前,我需要的是能够从字符串解析HTTP请求的功能。 I don't need to send or receive data, the old code does it and I need to integrate with it - at least for now. 我不需要发送或接收数据,旧代码可以做到,并且我需要与之集成-至少现在是这样。 I need to read various headers, get URI and parse it - including query parameters. 我需要读取各种标头,获取URI并解析它-包括查询参数。

The part I'm having trouble with is to get the request body. 我遇到的问题是获取请求正文。 There is not way to achieve that with the HTTPRequest class. 使用HTTPRequest类无法实现此目的。 I see a method called stream() in the HTTPServerRequestImpl class, but that class seems to be some internal stuff for the HTTPServer - there is no way to construct it without a session, a socket and some params. 我在HTTPServerRequestImpl类中看到了一个称为stream()的方法,但是该类似乎是HTTPServer一些内部内容-没有会话,套接字和一些参数就无法构造它。

The problem is - I don't need to make network requests with POCO, at least for now. 问题是-至少到目前为止,我不需要用POCO发出网络请求。 There are several other libraries which can solve my current tasks (httpxx, cpp-netlib) each with their own missing functionality, but it would be really great to integrate POCO from early stages, because it seems quite versatile, robust and can replace (I think) all manually-written old code in the near future. 还有其他几个库可以解决我当前的任务(httpxx,cpp-netlib),每个库都有各自的缺失功能,但是从早期阶段集成POCO确实很棒,因为它看起来相当通用,健壮并且可以替换(我认为)在不久的将来所有手动编写的旧代码。 There is of course the way to just separate the request by new lines, but I would really prefer some POCO standard tool if it exists. 当然,可以通过换行来分隔请求,但是我确实更喜欢一些POCO标准工具(如果存在)。

Here is my test project code (with some test HTTP data) for POCO, maybe it will help someone or give a better idea how I want to use the library: 这是我针对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;
}

HTTPRequest object knows nothing about body of request. HTTPRequest对象对请求主体一无所知。 So you can't get this information from HTTPRequest. 因此,您无法从HTTPRequest获取此信息。 If need send the request body use HTTPClientSession . 如果需要发送请求正文,请使用HTTPClientSession From documentation: 从文档:

To send a HTTP request to a HTTP server, first instantiate a HTTPClientSession object and specify the server's host name and port number. 要将HTTP请求发送到HTTP服务器,请首先实例化HTTPClientSession对象,然后指定服务器的主机名和端口号。 Then create a HTTPRequest object, fill it accordingly, and pass it as argument to the sendRequst() method. 然后创建一个HTTPRequest对象,进行相应的填充,并将其作为参数传递给sendRequst()方法。 sendRequest() will return an output stream that can be used to send the request body, if there is any. sendRequest()将返回可用于发送请求正文的输出流(如果有)。 After you are done sending the request body, create a HTTPResponse object and pass it to receiveResponse(). 发送完请求正文后,创建一个HTTPResponse对象,并将其传递给receiveResponse()。 This will return an input stream that can be used to read the response body. 这将返回可用于读取响应正文的输入流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM