Discussion:
Cannot send POST-information in WinHttpSendRequest
(too old to reply)
Voidkeeper
2006-06-18 23:16:01 UTC
Permalink
I'm really lost here: I want to POST some information via WinHttp. But when I
check on my webserver, no POST-data was received (if I do the same with GET
options like 'http://myhost/mypath?getoption=it_works', then it works. And
the webserver is showing POST-data from other tests with IE(...), so that one
is working).
I give the URL and a special string with the POST-data to the function.

Here are some parts of the function in my code. pszPostdata and url are
given as char* to this function... (GET functionality left out):


HINTERNET hnd_session;
HINTERNET hnd_connect;
HINTERNET hnd_request;

WCHAR* pswurl = new WCHAR[strlen(url)+1]; //WCHAR[] of url
WCHAR* pswHostname = NULL; //WCHAR[] of hostname
WCHAR* pswPath = NULL; //WCHAR[] of url-path

DWORD dwBuffer = ::MultiByteToWideChar(CP_ACP, 0, url, -1, NULL, 0);
MultiByteToWideChar(CP_ACP, 0, url, -1, pswurl, dwBuffer);

DWORD dwFlag = WINHTTP_FLAG_SECURE;
URL_COMPONENTS urlComp;
ZeroMemory(&urlComp, sizeof(urlComp));
urlComp.dwStructSize = sizeof(urlComp);
urlComp.dwSchemeLength = -1;
urlComp.dwHostNameLength = -1;
urlComp.dwUrlPathLength = -1;
urlComp.dwExtraInfoLength = -1;
urlComp.nPort = 0;

if (!WinHttpCrackUrl( pswurl, wcslen(pswurl), 0, &urlComp))
{
return false;
}
else
{
if(urlComp.nScheme==INTERNET_SCHEME_HTTP)
{
dwFlag=0;
}
DWORD dwlen = urlComp.dwHostNameLength;
pswHostname = new WCHAR[dwlen+1];
wcsncpy(pswHostname, urlComp.lpszHostName, dwlen);
pswHostname[dwlen] = L'\0';
dwlen = urlComp.dwUrlPathLength;
pswPath = new WCHAR[dwlen+1];
wcsncpy(pswPath, urlComp.lpszUrlPath, dwlen);
pswPath[dwlen] = L'\0';

//here, I send an output: ("Hostname %s ,urlpath is %s, Port %d, internet
scheme is %d, POST-data: %s"),
W2A(pswHostname),W2A(pswPath),urlComp.nPort,dwFlag, pszPostdata);
// so I have in WCHAR strings the hostname and url-path, then the port, the
flags(scheme) and the POST-data, which was char string anyway.
}

hnd_session = WinHttpOpen(L"myApplication",
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
if(hnd_session)
{
hnd_connect = WinHttpConnect(hnd_session,
pswHostname,
urlComp.nPort,
0);
if(hnd_connect)
{
hnd_request = WinHttpOpenRequest(hnd_connect,
L"POST",
urlComp.lpszUrlPath,
L"HTTP/1.1",
WINHTTP_NO_REFERER,

WINHTTP_DEFAULT_ACCEPT_TYPES,
0);

if(hnd_request)
{
DWORD dwTlen = (DWORD)(strlen(pszPostdata)*sizeof(char));
BOOL bResults = WinHttpSendRequest(hnd_request,
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
(LPVOID)pszPostdata, dwTlen, // pszPostdata is multibyte, not widechar
dwTlen, 0 );


// ...
// bResults = WinHttpReceiveResponse(hnd_request, NULL ); ...etc


So please: Where is my mistake?!? I tried many things, changing options in
all functions, changing the HTTP header and playing with the
string-encryption but with no positive result.

Thanks
Stephen Sulzer
2006-06-20 03:52:12 UTC
Permalink
Hello,

You should capture traces of the HTTP traffic for both the IE and WinHttp
scenarios and compare them. (Use a network analyzer like NETMON or
Ethereal.) Compare IE and WinHttp to see what the HTTP request headers look
like and check for differences between them.

Also, what do you mean by "string-encryption"?

A possible cause of the problem with your WinHttp code is that you need to
set a "Content-Type: application/x-www-form-urlencoded" request header. You
need to set this request header if your application is trying to do a
"FORM-submit" style POST request (this type of POST request is defined in
the HTML specification). In such a request, the POST data is formatted as a
set of "name=value" pairs separated by "&". Is that what you mean by
"special string with the POST-data"?

Hope that helps.

- Stephen

Loading...