2016-09-01 5 views
1

C++로 작성된 꽤 오래된 서버 응용 프로그램을 지원하고 개발해야합니다. 코드 기록은 15 년 이상의 개발로 이루어져 있습니다. 대부분의 코드는 네트 파트를 포함하여 수동으로 작성됩니다. 휠을 재발견하는 많은 부품이 있습니다 (예 : 유니 코드 지원 등.문자열에서 HTTP 요청을 구문 분석하고 POCO를 사용하여 본문을 가져 오는 방법이 있습니까?

내 주요 목표는 백그라운드 리팩터링 프로세스로서 잘 설계되고 지원되는 오픈 소스 대안으로 버그의 경향이있는 휠 - 틱 부분을 점진적으로 대체하는 것입니다. 인터넷 코드가 우선합니다. 그러나 나는 한 걸음 내 그것을 할 수는 없다.

현재 내가 필요로하는 것은 문자열로부터 HTTP 요청을 구문 분석 할 수있는 능력입니다. 데이터를 보내거나받을 필요가 없습니다. 예전의 코드는 그것을 수행하기 때문에 적어도 지금은 통합해야합니다. 다양한 헤더를 읽고 URI를 가져 와서 구문 분석해야합니다 (쿼리 매개 변수 포함).

문제가있는 부분은 요청 본문을 얻는 것입니다. HTTPRequest 클래스를 사용하여이를 달성 할 방법이 없습니다. HTTPServerRequestImpl 클래스에 stream()이라는 메서드가 있지만이 클래스는 HTTPServer에 대한 내부 용품 인 것 같습니다. 세션, 소켓 및 일부 매개 변수 없이는이 방법을 사용할 수 없습니다.

문제는 - 지금 당장은 POCO로 네트워크 요청을 할 필요가 없습니다. 내 현재 작업 (httpxx, cpp-netlib) 각각의 누락 된 기능을 해결할 수있는 몇 가지 다른 라이브러리가 있지만, 매우 다목적, 강력하고 대체 할 수 있기 때문에 초기 단계에서 POCO를 통합하는 것은 정말 좋을 것입니다. 생각해라.) 가까운 장래에 수동으로 작성된 모든 오래된 코드. 물론 새로운 라인으로 요청을 분리하는 방법이 있지만 실제로 POCO 표준 도구가 있으면 선호합니다.

#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; 
} 
+0

코드가 제대로 작동하면 [Codereview] (http://codereview.stackexchange.com)에서 더 잘 질문하십시오. –

+0

@Atomic_alarm 아니요, 그렇지 않습니다! 컴파일하고 예상대로 작동하지만, 요청 본문을 가져 오지 않습니다. 질문의 목적은 요청의 본문을 가져 오는 방법을 찾는 것입니다. –

답변

0

HTTPRequest 객체에 대해 아무것도 알고 : 여기

어쩌면 누군가를 돕거나 내가 라이브러리를 사용하는 방법을 더 나은 아이디어를 줄 것이다, POCO에 대한 (일부 테스트 HTTP 데이터와) 내 테스트 프로젝트 코드 요청 본문. 따라서 HTTPRequest에서이 정보를 얻을 수 없습니다. 요청 본문을 보내려면 HTTPClientSession을 사용하십시오. 문서에서 :

HTTP 요청을 HTTP 서버로 보내려면 먼저 HTTPClientSession 개체를 인스턴스화하고 서버의 호스트 이름과 포트 번호를 지정하십시오. 그런 다음 HTTPRequest 객체를 만들고 적절하게 채우고 인수로 sendRequest() 메서드에 전달합니다. sendRequest()는 요청 본문을 보낼 때 사용할 수있는 출력 스트림을 반환합니다 (있는 경우). 요청 본문 보내기가 완료되면 HTTPResponse 개체를 만들어 receiveResponse()에 전달합니다. 응답 본문을 읽는 데 사용할 수있는 입력 스트림을 반환합니다.

+0

도움을 주셔서 감사합니다. 그러나 몇 가지 질문에 명확하게 언급했듯이 - 나는 POCO로 아무 것도 보낼 필요가 없습니다. 이미 작성된 코드가 있습니다. 그에 대한. 나는 문자열에서 모든 요청 \ 응답을 가지고 있고 그것을 분석 할 필요가있다. 그것은 코드 스 니펫에서 분명해야합니다 ... –

+0

@Occulta, 음, 그때 나는 그 질문을 이해하지 못합니다. 문자열을 2 부분으로 나누려면 예를 들어 regex를 사용할 수 있습니다. http://ideone.com/okLnIS –

+0

요청을 받도록 POCO 표준 방법이 있기를 바랍니다.질문에서 인용하자면 :'새로운 라인으로 요청을 분리하는 방법은 물론 있지만, POCO 표준 도구가 있다면 그것을 선호 할 것입니다. ' –