I'm still relatively new to c++ so this really bothering me for a while....
What I'm trying to do here is to send a bunch of data on windows MFC to the server API and get data back. The only library I can use now is the winhttp.h.I have a couple data sets want to send for example:
name : AA
code : BBB
type : CCC
Because the WinHttpSendRequest has its own format as below, I need to reformat the header and body. I'm reallly unfamiliar with these types used but I googled a lot and trying to get some formatting done.
WinHttpSendRequest
(
IN HINTERNET hRequest,
_In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders,
IN DWORD dwHeadersLength,
_In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional,
IN DWORD dwOptionalLength,
IN DWORD dwTotalLength,
IN DWORD_PTR dwContext
);
CStringW header;
header += _T("__id: "+ GetID());
CString body_builder;
body_builder = "name: "+m_name+"\r\n";
body_builder+= "code: "+m_code+"\r\n";
body_builder+= "type: "+m_type+"\r\n";
LPCSTR body = (LPCSTR)(LPCTSTR)body_builder;
response = SendPOSTRequest(m_postUri, header, (DWORD)header.length() body, body_builder.GetLength());
The SendPOSTRequest
function will basically pass parameters to the WinHttpSendRequest
.
The problem is the response from the server is always
HTTP_STATUS_BAD_REQUEST 400 // invalid syntax
I cannot find any good resources about how to format body and header in winhttp c++. Can anyone explain to me how the body and header should be formatted?
Edit: Here's the definition to SendPOSTRequest and futher called functions.
WebServiceResponse CCommonWebService::SendPOSTRequest(LPCSTR uri, CStringW headers, LPCSTR body, DWORD body_length) {
return send_request(uri, L"POST", headers, body, body_length);
}
WebServiceResponse WebServices::send_request(LPCSTR uri, LPCWSTR method, CStringW headers, LPCSTR body, DWORD body_length)
{
WebServiceResponse response;
CStringW wuri = to_wchar(uri);
HandleObject request;
if (!m_init)
{
// WebServices is not initialized
return response;
}
if (m_protocol == PROTOCOL_HTTP)
{
request.handle = WinHttpOpenRequest(m_handle_connection, method, wuri, REQUEST_HTTP_VERSION, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, FLAGS_HTTP);
}
else
{
request.handle = WinHttpOpenRequest(m_handle_connection, method, wuri, REQUEST_HTTP_VERSION, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, FLAGS_HTTPS);
DWORD dwOptions = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
| SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
// Set HTTPS security flags
WinHttpSetOption(request.handle, WINHTTP_OPTION_SECURITY_FLAGS, &dwOptions, sizeof(DWORD));
}
// Set custom timeout values for request handle
WinHttpSetTimeouts(request, 0, 30000, 15000, 15000);
if (m_try_proxy)
{
setup_proxy(request.handle, wuri);
}
// Sending request with len(header) and len(body)
if (!WinHttpSendRequest(request.handle, headers, (DWORD)headers.GetLength(), (LPVOID)body, body_length, body_length, 0))
{
DWORD last_err = GetLastError();
// WinHttpSendRequest() failed with error last_err
response.text.Format("Failed when sending request to connect to server (Error %d).", (int)last_err);
return response;
}
// Request sent, waiting for response
if (WinHttpReceiveResponse(request.handle, NULL))
{
response.code = get_response_code(request.handle);
if (response.code == HTTP_STATUS_NO_CONTENT)
{
return response;
}
DWORD content_length = get_response_content_length(request.handle);
if (content_length < 1)
{
return response;
}
DWORD dwSize = sizeof(DWORD);
if (WinHttpQueryDataAvailable(request.handle, &dwSize))
{
DWORD dwDownloaded = 0;
char* buffer = response.text.GetBufferSetLength(content_length+1);
memset(buffer, '\0', content_length+1);
response.length = content_length;
if (WinHttpReadData(request.handle, buffer, content_length+1, &dwDownloaded))
{
if (dwDownloaded != content_length)
{
// Did not read full content length
}
}
response.text.ReleaseBuffer();
}
}
else
{
DWORD last_err = GetLastError();
// WinHttpReceiveResponse() failed with error last_err;
response.text.Format("Failed when receiving response from server (Error %d).", (int)last_err);
}
return response;
}