WinHttpWriteData fails sending more than a byte

OPN_Analysis 41 Reputation points
2023-03-23T17:35:03.1366667+00:00

I'm writing a C++ server client that's POSTing and GETting data from a server on an RPi. It's sending and receiving a string of information since that's what C++ can handle, however WinHttpWriteData returns an error of 87, which I believe is ERROR_INVALID_PARAMETER.

What prints out from GetLastError(): Failed to write HTTP data (WinHttpWriteData): 87

I'm using the the Windows docs as a reference (https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata) to make sure that I've got it set up correctly, but their string is about as long as the one I'm using. If I change the parameter dwNumberOfBytesToWrite to 8, it sends. Do I have to change my code to loop through sections of 8 or less to send? No matter the length of the string I'm sending, the server prints a 400 error.

The server's running python's flask if that helps. I know that I can connect to the server GET data without issue.

Any help or insight is much appreciated, thank you!

Code:

bool webClient::postDevices(char* i_buffer)
{
	bool l_results = true;
	DWORD l_bytesWritten = 0;

	if (request(MIXER_IP_ADDR, L"POST", L"devices"))
	{
		// Send the POST request
		if (!WinHttpSendRequest(m_httpRequest,
								WINHTTP_NO_ADDITIONAL_HEADERS,
								0,
								WINHTTP_NO_REQUEST_DATA,
								0,
								sizeof(i_buffer),
								0))
		{
			std::cout << "Failed to send HTTP Request (WinHttpSendRequest): " << GetLastError() << std::endl;
			l_results = false;
			goto end_request;
		}

		// Write data to the server.
		if (!WinHttpWriteData(m_httpRequest, 
							 i_buffer,
							 (DWORD)strlen(i_buffer),
							 &l_bytesWritten))
		{
			std::cout << "Failed to write HTTP data (WinHttpWriteData): " << GetLastError() << std::endl;
			l_results = false;
			goto end_request;
		}
		
		// End the request.
		if (!WinHttpReceiveResponse(m_httpRequest, NULL))
		{
			std::cout << "Failed to end HTTP request (WinHttpReceiveRequest): " << GetLastError() << std::endl;
			l_results = false;
			goto end_request;
		}
	}

end_request:
	closeConnection();
	return l_results;
}
Windows Server
Windows Server
A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.
12,127 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,527 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Limitless Technology 43,931 Reputation points
    2023-03-24T12:25:22.2333333+00:00

    Hello there,

    Yes, you are right Error code 87 is ERROR_INVALID_PARAMETER.

    When you say it returns "error code (87)", is that the value returned by a call to GetLastError()?

    Do you get any other error messages so we can compare it? The error values listed in below article are returned by GetLastError when one of the Microsoft Windows HTTP Services (WinHTTP) functions fails, and are also returned in the lower 16 bits of HRESULT error returns from the WinHttpRequest object.

    https://learn.microsoft.com/en-us/windows/win32/winhttp/error-messages

    Hope this resolves your Query !!

    --If the reply is helpful, please Upvote and Accept it as an answer–

    0 comments No comments

  2. OPN_Analysis 41 Reputation points
    2023-03-27T18:44:33.83+00:00

    Thank you David Lowndes & Minxin Yu, my value to dwTotalLength was the size of the pointer, not the length of the string it contains. Using strlen(i_buffer) solved it so it posts the correct length of data.

    Thanks again!


  3. David Lowndes 4,711 Reputation points
    2023-03-28T01:26:01.81+00:00

    It looks wrong to me to pass sizeof(i_buffer) (the size of a pointer!) in your call to WinHttpSendRequest.

    0 comments No comments