POST Request in WinHttp c++ - c++

I'm trying to make a POST request in c++ with the WinHTTP api Click to the Microsoft Guide, the problem is that the example that is available in the microsoft webpage is a "GET" request so I came up with this code searching on the internet:
First we call the code:
HttpsWebRequestPost("example.com", "/api.php?action=UserLogin", "loginUsername=" + USERNAME + "&loginPassword=" + PASSWORD + "&url=/index.php?page=Portal");
Then:
#include <Windows.h>
#include <WinHttp.h>
#include <stdio.h>
#include <iostream> //getchar
#include <fstream>
#pragma comment(lib, "winhttp.lib")
using namespace std;
std::wstring get_utf16(const std::string &str, int codepage)
{
if (str.empty()) return std::wstring();
int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
std::wstring res(sz, 0);
MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
return res;
}
string HttpsWebRequestPost(string domain, string url, string dat)
{
//Extra
LPSTR data = const_cast<char *>(dat.c_str());;
DWORD data_len = strlen(data);
wstring sdomain = get_utf16(domain, CP_UTF8);
wstring surl = get_utf16(url, CP_UTF8);
string response;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, sdomain.c_str(),
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", surl.c_str(),
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)data, data_len,
data_len, 0);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
// Keep checking for data until there is nothing left.
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 memory\n");
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);
response = response + string(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);
return response;
}
But using WireShark I only get:
Hypertext Transfer Protocol
POST ***************** HTTP/1.1\r\n
Connection: Keep-Alive\r\n
User-Agent: WinHTTP Example/1.0\r\n
Content-Length: **\r\n
Host: ******\r\n
\r\n
Anyone can help meto fix this or know an easier method?
Thanks

In order for PHP (or any other post-processing language) to recognise POST data, add this:
LPCWSTR additionalHeaders = L"Content-Type: application/x-www-form-urlencoded\r\n";
DWORD headersLength = -1;
bResults = WinHttpSendRequest( hRequest,
additionalHeaders,
headersLength ,
(LPVOID)data,
data_len,
data_len,
0);
The rest of a code is functional, should work:

The following code works for me when I tried to post text in key(info) and value(this is some info) pair. The status code 200 returned at the end.
int main()
{
DWORD dwSize = 0;
LPVOID lpOutBuffer = NULL;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
std::wstring url{ L"http://app.pomdit.com:3010/uploadfile" };
URL_COMPONENTS components{};
components.dwStructSize = sizeof(components);
components.dwHostNameLength = (DWORD)-1;
components.dwUrlPathLength = (DWORD)-1;
if (!WinHttpCrackUrl(url.c_str(), static_cast<DWORD>(url.length()), 0, &components)) {
wprintf((L"WinHttpCrackUrl(): " + ErrorMessage(GetLastError())).c_str());
}
std::wstring hostName(components.lpszHostName ? std::wstring{ components.lpszHostName, components.dwHostNameLength } : L"localhost");
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, hostName.c_str(),
components.nPort, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"POST", components.lpszUrlPath,
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
const WCHAR* ContentType =
L"Content-Type: multipart/form-data;boundary = 19024605111143684786787635207";
const char* MultipartRequestBody =
"--19024605111143684786787635207\r\n"
"Content-Disposition: form-data; name=\"info\"\r\n"
"\r\n"
"this is some info\r\n"
"--19024605111143684786787635207\r\n";
bResults = WinHttpSendRequest(hRequest, ContentType, wcslen(ContentType),
(LPVOID)MultipartRequestBody,
strlen(MultipartRequestBody),
strlen(MultipartRequestBody),
NULL);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
// First, use WinHttpQueryHeaders to obtain the size of the buffer.
if (bResults)
{
DWORD status{}, len = sizeof(status);
bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &len, NULL);
if (bResults)
{
printf("Status code = %d.\n", status);
}
}
else
{
wprintf(L"WinHttpReceiveResponse(): %s\n", ErrorMessage(GetLastError()).c_str());
}
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
}

Related

Access secure website using winhttp . TLS 1.3

I have the following code that works with SSL sites like microsoft.com
but not with www.dmo.gov.uk.
When I open the site using chrome I can see that it requires TLS 1.3
But when I open this side from my Android phone it falls back on using 1.2
Is there any header or another way to force website to negotiate TLS 1.2 when I access it using Winhttp.
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <Winhttp.h>
#pragma comment(lib, "winhttp.lib")
static void APIENTRY StatusCallback(
HINTERNET handle,
DWORD_PTR context,
DWORD status,
LPVOID info,
DWORD size) {
handle;
DWORD err = 0;
if (status == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE) {
err = *(DWORD*)info;
printf("Error flags %#010x\n", err);
}
}
int main()
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BOOL ret = FALSE;
hSession = WinHttpOpen(
L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
DWORD secure_protocols =
WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
| WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
ret = ::WinHttpSetOption(
hSession,
WINHTTP_OPTION_SECURE_PROTOCOLS,
&secure_protocols,
sizeof(secure_protocols));
WinHttpSetStatusCallback(
hSession,
StatusCallback,
WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0);
if (hSession)
hConnect = WinHttpConnect(
hSession,
L"www.dmo.gov.uk",
// L"www.microsoft.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
if (hConnect)
hRequest = WinHttpOpenRequest(
hConnect, L"GET", NULL,
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
DWORD dwFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA
| SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE
| SECURITY_FLAG_IGNORE_CERT_CN_INVALID
| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
ret = WinHttpSetOption(
hRequest,
WINHTTP_OPTION_SECURITY_FLAGS,
(void *)&dwFlags,
sizeof(dwFlags));
if (FALSE == ret) {
printf("Error %u in WinHttpSetOption.\n", GetLastError());
}
// Send a request.
if (hRequest) {
bResults = WinHttpSendRequest(
hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA,
0, 0, 0);
}
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse(
hRequest, nullptr);
// Keep checking for data until there is nothing left.
if (bResults)
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
printf("Error %d in WinHttpQueryDataAvailable.\n", GetLastError());
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize = 0;
}
else
{
// Read the Data.
ZeroMemory(pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
printf("Error %d in WinHttpReadData.\n", GetLastError());
else
printf("%s\n", 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);
}

WinHttpSendRequest continuously fails with windows error code 87, ERROR_INVALID_PARAMETER (C++)

I am trying to send an http post request through a proxy that has headers and optionally, json content, using WinHTTP. I have tried solutions outlined in the questions here:
WinHttpSendRequest failed with error code 87
WinHttpSendRequest returns ERROR_INVALID_PARAMETER
However, it just does not seem to change anything. I have the post request functions pasted below. Perhaps there is something that I missed. Please let me know if there is anything I can do to fix this.
The problematic area is around WinHttpSendRequest
std::string PostRequest(std::wstring token, std::string json, std::string proxy, std::wstring url, std::wstring domain) {
std::cout<<"PostRequest function started"<<std::endl;
std::cout<<"json is being processed"<<std::endl;
LPSTR data = (LPSTR)json.c_str();
DWORD data_len;
if(data!=0) data_len = strlen(data); else data_len = 0;
std::cout<<"json done"<<std::endl<<GetLastError()<<std::endl;
std::string response;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hConnect = NULL, hRequest = NULL;
std::wstring stemp = std::wstring(proxy.begin(), proxy.end());
const wchar_t* sw = stemp.c_str();
std::cout<<"initializing WinHttpOpen"<<std::endl<<GetLastError()<<std::endl;
HINTERNET hSession=WinHttpOpen(L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, L"http://"+*sw, WINHTTP_NO_PROXY_BYPASS, 0);
std::cout<<"initializing WinHttpConnect"<<std::endl<<GetLastError()<<std::endl;
if(hSession) hConnect = WinHttpConnect(hSession, domain.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0 );
std::cout<<"initializing WinHttpOpenRequest"<<std::endl<<GetLastError()<<std::endl;
if(hConnect) hRequest = WinHttpOpenRequest(hConnect, L"POST", url.c_str(), NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
const wchar_t *additionalHeaders =
L"Content-Type: application/json\r\n"
L"User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11\r\n"
L"Authorization: "+*token.c_str()+*L"\r\n";
DWORD headersLength = -1;
std::cout<<"initializing WinHttpSendRequest"<<std::endl<<GetLastError()<<std::endl;
std::cout<<"bResults: "<<bResults<<std::endl;
LPVOID rqdata;
if(data==0)rqdata = WINHTTP_NO_REQUEST_DATA;
else rqdata=(LPVOID)data;
if (hRequest) bResults = WinHttpSendRequest(hRequest, additionalHeaders, headersLength, rqdata, data_len, data_len, 0);
else std::cout<<"else 1"<<std::endl;
std::cout<<"bResults: "<<bResults<<std::endl;
std::cout<<"initializing WinHttpReceiveResponse"<<std::endl<<GetLastError()<<std::endl;
if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL);
else std::cout<<"else 2"<<std::endl;
std::cout<<"bResults: "<<bResults<<std::endl;
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
std::cout<<"Error in WinHttpQueryDataAvailable.\n"<<GetLastError();
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
dwSize = 0;
}
else
{
// Read the data.
ZeroMemory(pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
std::cout<<"Error in WinHttpReadData.\n"<<GetLastError();
else
response = response + std::string(pszOutBuffer);
// Free the memory allocated to the buffer.
delete[] pszOutBuffer;
}
} while (dwSize > 0);
}
if (!bResults)
std::cout<<"Error has occurred.\n"<<GetLastError()<<std::endl;
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
return response;
}
all of the cout's are for debugging which will be removed by me later.
The output looks like this: (sorry if it is kind of messy)
PostRequest function started
json is being processed
json done
0
initializing WinHttpOpen
0
initializing WinHttpConnect
0
initializing WinHttpOpenRequest
0
initializing WinHttpSendRequest
0
bResults: 0
bResults: 0
initializing WinHttpReceiveResponse
87
else 2
bResults: 0
Error has occurred.
87

Prevent winHTTP From Writing to STDOUT

I've taken the following code from a previous SO post:
//Variables
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
std::vector <std::string> vFileContent;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"stackoverflow.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"GET", L"/questions/ask/",
NULL, WINHTTP_NO_REFERER,
NULL,
NULL);
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
0, 0);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);
// Keep checking for data until there is nothing left.
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 memory\n");
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);
// Data in vFileContent
vFileContent.push_back(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);
// Write vFileContent to file
std::ofstream out("./SO/ask.html",std::ios::app);
for (int i = 0; i < (int) vFileContent.size();i++)
out << vFileContent[i];
out.close();
When run it downloads the file and prints it's data. I looked through the code, and couldn't find where it was writing the data to STDOUT. Can someone tell me where it's coming from and how to prevent it?
The line:
printf("%s", ppszOutBuffer);
I believe is the reason here.

Winhttp request give error Error 87 has occurred. Could not close the hSession handle for post json request

hi i am implementing post json request with winhttp function. though no error in code but at time of execution i cant get proper output for it. it gives me error for it like Error 87 has occurred. Could not close the hSession handle. it means open and is not able to be close please give me suggestions how should i remove that error. here is my code
#include "stdafx.h"
#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"localhost",
INTERNET_DEFAULT_HTTPS_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"POST", L":8080/hellowword.jsp",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
TCHAR* szHeaders = _T("Content-Type:application/json\r\n");
TCHAR* szPostData = _T("{\"command\":\"remotecontrol\",\"method\":\"countmon.getgatestatus\",\"param\":\"2\"}");
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
szHeaders, _tcslen(szHeaders),
szPostData, _tcslen(szPostData)
,0, 0);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);
// Keep checking for data until there is nothing left.
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
{
printf( "Error %u in WinHttpQueryDataAvailable.\n",
GetLastError());
break;
}
// No more available data.
if (!dwSize)
break;
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
break;
}
// 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);
}
// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
// This condition should never be reached since WinHttpQueryDataAvailable
// reported that there are bits to read.
if (!dwDownloaded)
break;
} while (dwSize > 0);
}
else
{
// Report any errors.
printf( "Error %d has occurred.\n", GetLastError() );
}
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
system("pause");
return 0;
}

WinHttpReadData in Win32 app dont work properly

I use WinHTTP to get text from URL http://www.google.com/complete/search?output=toolbar&hl=vi&q=hoazzztf. The reponse text must be: <toplevel/> but I get the reponse like this:
Any idea? Thank!
(Reponse text may contains UTF-8 character)
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
BOOL bResults = FALSE;
hSession = WinHttpOpen(L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
WinHttpSetTimeouts(hSession, 1000, 2000, 1000, 1000);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect(hSession, L"www.google.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/complete/search?output=toolbar&hl=vi&q=hoazzztf",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest(hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
0, 0);
if (bResults)
bResults = WinHttpReceiveResponse(hRequest, NULL);
if (!bResults)
{
SetWindowText(hWnd, L"ERR-4");
break;
}
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
break;
}
// No more available data.
if (!dwSize)
break;
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
if (!pszOutBuffer)
{
break;
}
// Read the Data.
ZeroMemory((LPVOID)pszOutBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
{
}
else
{
MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);
}
// Free the memory allocated to the buffer.
delete[] pszOutBuffer;
// This condition should never be reached since WinHttpQueryDataAvailable
// reported that there are bits to read.
if (!dwDownloaded)
break;
} while (dwSize > 0);
}
// Report any errors.
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
WinHttpReadData reads raw data, but you forced it to be an array of 2-byte WCHAR's. I think google uses utf-8 encoding on their pages, so you need to convert it first.
Another problem in your code is that you don't set terminating 0:
...
else
{
pszOutBuffer[ dwDownloaded ] = 0;
MessageBox(hWnd, pszOutBuffer, "", NULL);
}
Then, checking value returned by new is senseless, because new throws an exception in case of failure.
I fixed:
MessageBox(hWnd, (LPCWSTR)pszOutBuffer, L"", NULL);
to:
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, NULL, 0);
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar(CP_UTF8, 0, pszOutBuffer, -1, wstr, wchars_num);