C++WinHttp获取响应标头和正文
C++ WinHttp get response header and body
我目前正在尝试编写一个类,以使发送简单请求更容易。
最后,我希望它能像这样使用:
int _tmain(int argc, _TCHAR* argv[])
{
HttpRequest Request(L"Example UserAgent/1.0",L"",L"");
Request.SendRequest(L"google.com",L"GET",NULL);
if (Request.responseHeader)
printf("%s",Request.responseHeader);
if (Request.responseBody)
printf("%s",Request.responseBody);
getchar();
return 0;
}
但就目前而言,它根本不起作用。我不知道如何获得响应标头,而且我无法将响应标头写入类的公共成员
是的,我真的不擅长C++,尤其是在winapi方面
我希望你能帮我
这是我到目前为止的代码:
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")
class HttpRequest {
private:
DWORD dwSize;
DWORD dwDownloaded;
LPSTR pszOutBuffer;
BOOL bResults;
HINTERNET hSession;
HINTERNET hConnect;
HINTERNET hRequest;
LPCWSTR _userAgent;
//LPCWSTR _proxyIp;
//LPCWSTR _proxyPort;
size_t bodySize;
public:
HttpRequest(LPCWSTR, LPCWSTR, LPCWSTR);
void SendRequest(LPCWSTR, LPCWSTR, LPVOID);
LPSTR responseHeader[1000000];
LPSTR responseBody[1000000];
};
HttpRequest::HttpRequest(LPCWSTR userAgent, LPCWSTR proxyIp, LPCWSTR proxyPort) {
_userAgent = userAgent;
//_proxyIp = proxyIp;
//_proxyPort = proxyPort;
hSession = WinHttpOpen( userAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
}
void HttpRequest::SendRequest(LPCWSTR url, LPCWSTR method, LPVOID body) {
bodySize = 0;
if (hSession)
hConnect = WinHttpConnect( hSession, url, INTERNET_DEFAULT_HTTPS_PORT, 0 );
else
printf("session handle failedn");
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, method, NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE );
else
printf("connect handle failedn");
if (hRequest)
bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, body, 0, 0, 0 );
else
printf("request handle failedn");
if( bResults )
bResults = WinHttpReceiveResponse( hRequest, NULL );
if( bResults )
{
do
{
// Check for available data.
dwSize = 0;
if( !WinHttpQueryDataAvailable( hRequest, &dwSize ) )
printf( "Error %u in WinHttpQueryDataAvailable.n", GetLastError( ) );
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if( !pszOutBuffer )
{
printf( "Out of memoryn" );
dwSize=0;
}
else
{
// Read the data.
ZeroMemory( pszOutBuffer, dwSize+1 );
if( !WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded ) )
printf( "Error %u in WinHttpReadData.n", GetLastError( ) );
else {
//printf( "%s", pszOutBuffer );
responseBody[bodySize++] = pszOutBuffer;
}
// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
}
} while( dwSize > 0 );
}
// Report any errors.
if( !bResults )
printf( "Error %d has occurred.n", GetLastError( ) );
// Close any open handles.
if( hRequest ) WinHttpCloseHandle( hRequest );
if( hConnect ) WinHttpCloseHandle( hConnect );
if( hSession ) WinHttpCloseHandle( hSession );
}
使用WinHttpQueryHeaders()
访问响应标头。使用WINHTTP_QUERY_RAW_HEADERS(_CRLF)
标志指定要检索所有可用标头。
您还需要更改类以动态分配其responseHeader
和responseBody
成员。通过使用静态数组,您不仅浪费了大量内存,还限制了可以处理的响应大小。
试试这个:
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#include <string>
#include <vector>
#pragma comment(lib, "winhttp.lib")
class HttpRequest
{
private:
std::wstring _userAgent;
//std::wstring _proxyIp;
//std::wstring _proxyPort;
public:
HttpRequest(const std::wstring&, const std::wstring&, const std::wstring&);
bool SendRequest(const std::wstring&, const std::wstring&, void*, DWORD);
std::wstring responseHeader;
std::vector<BYTE> responseBody;
};
HttpRequest::HttpRequest(const std::wstring &userAgent, const std::wstring &proxyIp, const std::wstring &proxyPort) :
_userAgent(userAgent)
//,_proxyIp(proxyIp)
//,_proxyPort(proxyPort)
{
}
bool HttpRequest::SendRequest(const std::wstring &url, const std::wstring &method, void *body, DWORD bodySize)
{
DWORD dwSize;
DWORD dwDownloaded;
DWORD headerSize = 0;
BOOL bResults = FALSE;
HINTERNET hSession;
HINTERNET hConnect;
HINTERNET hRequest;
responseHeader.resize(0);
responseBody.resize(0);
hSession = WinHttpOpen( _userAgent.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0 );
if (hSession)
hConnect = WinHttpConnect( hSession, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0 );
else
printf("session handle failedn");
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, method.c_str(), NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE );
else
printf("connect handle failedn");
if (hRequest)
bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, body, bodySize, 0, 0 );
else
printf("request handle failedn");
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL );
if (bResults)
{
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, WINHTTP_NO_OUTPUT_BUFFER, &headerSize, WINHTTP_NO_HEADER_INDEX);
if ((!bResults) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
responseHeader.resize(headerSize / sizeof(wchar_t));
if (responseHeader.empty())
{
bResults = TRUE;
}
else
{
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, &responseHeader[0], &headerSize, WINHTTP_NO_HEADER_INDEX);
if( !bResults ) headerSize = 0;
responseHeader.resize(headerSize / sizeof(wchar_t));
}
}
}
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
bResults = WinHttpQueryDataAvailable( hRequest, &dwSize );
if (!bResults)
{
printf( "Error %u in WinHttpQueryDataAvailable.n", GetLastError( ) );
break;
}
if (dwSize == 0)
break;
do
{
// Allocate space for the buffer.
DWORD dwOffset = responseBody.size();
responseBody.resize(dwOffset+dwSize);
// Read the data.
bResults = WinHttpReadData( hRequest, &responseBody[dwOffset], dwSize, &dwDownloaded );
if (!bResults)
{
printf( "Error %u in WinHttpReadData.n", GetLastError( ) );
dwDownloaded = 0;
}
responseBody.resize(dwOffset+dwDownloaded);
if (dwDownloaded == 0)
break;
dwSize -= dwDownloaded;
}
while (dwSize > 0);
}
while (true);
}
// Report any errors.
if (!bResults)
printf( "Error %d has occurred.n", GetLastError( ) );
// Close any open handles.
if( hRequest ) WinHttpCloseHandle( hRequest );
if( hConnect ) WinHttpCloseHandle( hConnect );
if( hSession ) WinHttpCloseHandle( hSession );
return bResults;
}
int _tmain(int argc, _TCHAR* argv[])
{
HttpRequest Request(L"Example UserAgent/1.0",L"",L"");
if (Request.SendRequest(L"google.com",L"GET",NULL,0))
{
printf("%ls",Request.responseHeader.c_str());
if (!Request.responseBody.empty())
printf("%*s",Request.responseBody.size(),(char*)&Request.responseBody[0]);
}
getchar();
return 0;
}
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 使用指针从C++中的数组中获取最大值
- 如何获取std::result_of函数的返回类型
- 如何在openssl-ecc中获取十六进制格式的私钥
- 使用Unreal C++获取VR耳机的世界位置/方向
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 从C字符串中获取奇怪的字符串长度
- 为什么我的for循环不能正确获取argv
- 从python中调用C++函数并获取返回值
- 如何获取一个数字的前3位
- 获取字符串的长度并将其分配给数组
- 无法获取菜单选择以运行函数.C++
- 数组长度,为什么从命令行获取时不能使用它?
- 获取加密的正文响应WinHttp HTTPS
- 如何在Crypto++ ECDSA中从签名正文中获取签名长度
- 如何在 c++ 中从文本文件的正文中获取特定的单词和行
- Apache模块-获取请求正文
- C++WinHttp获取响应标头和正文