如何通过 HTTPChunkedStreamBuf 获取分块传输编码数据?
How I can get chunked transfer coding data by HTTPChunkedStreamBuf?
美好的一天!
我尝试从 IP 摄像机(事件通知)读取分块传输编码中的 HTTP 消息体。当我发送请求时,网络摄像机会回复我。
但是当我尝试检查缓冲区中的数据时
std::streamsize 大小 1 = chunkStreamBuffer.in_avail();
我看到size1为0,buffer中没有数据。
我已经检查了 Wireshark 的数据传输,可以看到 IP 摄像头为我发送了分块数据。我已经通过浏览器检查了数据传输,可以看到传输正常(我在我的应用程序和浏览器中发送了相同的 URI)。源代码如下。
问题 - 如何通过 POCO 库获取分块数据?
PS。感谢您的帮助。
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPIOStream.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
.....
#include "Poco/Net/..." //other POCO header
HTTPClientSession pSession;
HTTPBasicCredentials pCredentials;
HTTPRequest pRequest;
HTTPResponse pResponse;
pSession.setHost(host);
pCredentials.setUsername(username);
pCredentials.setPassword(password);
pRequest.setMethod(HTTPRequest::HTTP_GET);
pRequest.setVersion(HTTPMessage::HTTP_1_1);
pRequest.setURI(stringURI);
pRequest.setKeepAlive(true);
pSession.setKeepAlive(true);
pCredentials.authenticate(pRequest);
pSession.sendRequest(pRequest);
pHTTPStatus = pResponse.getStatus();
if (pHTTPStatus == HTTPResponse::HTTP_UNAUTHORIZED)
{
pRequest.set("Authorization", AuthorizationString);
pRequest.setKeepAlive(true);
pSession.setKeepAlive(true);
pRequest.set("Accept", "text/html, application/xhtml+xml, */*");
pRequest.set("Accept-Encoding", "gzip, deflate");
pSession.sendRequest(pRequest);
std::istream& rs = pSession.receiveResponse(pResponse);
pHTTPStatus = pResponse.getStatus();
if (pHTTPStatus == HTTPResponse::HTTP_OK)
{
Poco::Net::HTTPChunkedStreamBuf chunkStreamBuffer(pSession, ios_base::in);
chunkStreamBuffer.pubsetbuf( bufResponse, sizeof(bufResponse) );
//chunkStreamBuffer.pubseekpos(0);
std::string strReason = pResponse.getReason(); //in my case strReason is OK
bool keepAlive = pResponse.getKeepAlive(); // is my case keepAlive is true
std::string text = pResponse.get("Connection");
chunkStreamBuffer.pubsync();
std::streamsize size1 = chunkStreamBuffer.in_avail();
chunkStreamBuffer.sgetn( bufResponse, size1 );
bufResponse[size1]=0;
}
}
Poco::Net::HTTPClientSession class 内部处理响应中的分块传输编码,因此这里没有什么特别要做的。只需从响应流中读取。此外,在会话中调用 setKeepAlive(true) 就足够了。不过有一件事,您必须自己处理 deflate 或 gzip 编码:
if (pResponse->get("Content-Encoding", "") == "gzip")
{
Poco::InflatingInputStream inflater(rs, Poco::InflatingStreamBuf::STREAM_GZIP);
// read from inflater
}
else
{
// read from rs
}
通常只处理 gzip content-encoding 就足够了,因为 deflate 可能存在一些兼容性问题。
美好的一天!
我尝试从 IP 摄像机(事件通知)读取分块传输编码中的 HTTP 消息体。当我发送请求时,网络摄像机会回复我。
但是当我尝试检查缓冲区中的数据时 std::streamsize 大小 1 = chunkStreamBuffer.in_avail();
我看到size1为0,buffer中没有数据。
我已经检查了 Wireshark 的数据传输,可以看到 IP 摄像头为我发送了分块数据。我已经通过浏览器检查了数据传输,可以看到传输正常(我在我的应用程序和浏览器中发送了相同的 URI)。源代码如下。
问题 - 如何通过 POCO 库获取分块数据?
PS。感谢您的帮助。
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPIOStream.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
.....
#include "Poco/Net/..." //other POCO header
HTTPClientSession pSession;
HTTPBasicCredentials pCredentials;
HTTPRequest pRequest;
HTTPResponse pResponse;
pSession.setHost(host);
pCredentials.setUsername(username);
pCredentials.setPassword(password);
pRequest.setMethod(HTTPRequest::HTTP_GET);
pRequest.setVersion(HTTPMessage::HTTP_1_1);
pRequest.setURI(stringURI);
pRequest.setKeepAlive(true);
pSession.setKeepAlive(true);
pCredentials.authenticate(pRequest);
pSession.sendRequest(pRequest);
pHTTPStatus = pResponse.getStatus();
if (pHTTPStatus == HTTPResponse::HTTP_UNAUTHORIZED)
{
pRequest.set("Authorization", AuthorizationString);
pRequest.setKeepAlive(true);
pSession.setKeepAlive(true);
pRequest.set("Accept", "text/html, application/xhtml+xml, */*");
pRequest.set("Accept-Encoding", "gzip, deflate");
pSession.sendRequest(pRequest);
std::istream& rs = pSession.receiveResponse(pResponse);
pHTTPStatus = pResponse.getStatus();
if (pHTTPStatus == HTTPResponse::HTTP_OK)
{
Poco::Net::HTTPChunkedStreamBuf chunkStreamBuffer(pSession, ios_base::in);
chunkStreamBuffer.pubsetbuf( bufResponse, sizeof(bufResponse) );
//chunkStreamBuffer.pubseekpos(0);
std::string strReason = pResponse.getReason(); //in my case strReason is OK
bool keepAlive = pResponse.getKeepAlive(); // is my case keepAlive is true
std::string text = pResponse.get("Connection");
chunkStreamBuffer.pubsync();
std::streamsize size1 = chunkStreamBuffer.in_avail();
chunkStreamBuffer.sgetn( bufResponse, size1 );
bufResponse[size1]=0;
}
}
Poco::Net::HTTPClientSession class 内部处理响应中的分块传输编码,因此这里没有什么特别要做的。只需从响应流中读取。此外,在会话中调用 setKeepAlive(true) 就足够了。不过有一件事,您必须自己处理 deflate 或 gzip 编码:
if (pResponse->get("Content-Encoding", "") == "gzip")
{
Poco::InflatingInputStream inflater(rs, Poco::InflatingStreamBuf::STREAM_GZIP);
// read from inflater
}
else
{
// read from rs
}
通常只处理 gzip content-encoding 就足够了,因为 deflate 可能存在一些兼容性问题。