WinHttpWriteData function (winhttp.h)
The WinHttpWriteData function writes request data to an HTTP server.
Syntax
WINHTTPAPI BOOL WinHttpWriteData(
[in] HINTERNET hRequest,
[in] LPCVOID lpBuffer,
[in] DWORD dwNumberOfBytesToWrite,
[out] LPDWORD lpdwNumberOfBytesWritten
);
Parameters
[in] hRequest
Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function.
[in] lpBuffer
Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after WinHttpWriteData completes.
[in] dwNumberOfBytesToWrite
Unsigned long integer value that contains the number of bytes to be written to the file.
[out] lpdwNumberOfBytesWritten
Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must be set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault.
Return value
Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error codes returned are:
Error Code | Description |
---|---|
|
The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. |
|
The requested operation cannot be carried out because the handle supplied is not in the correct state. |
|
The type of handle supplied is incorrect for this operation. |
|
An internal error has occurred. |
|
The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. |
|
The request has timed out. |
|
Not enough memory was available to complete the requested operation. (Windows error code) |
Remarks
Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion to determine whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed.
If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server:
- WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
- WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
- WINHTTP_CALLBACK_STATUS_DATA_WRITTEN
- WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
- WINHTTP_CALLBACK_STATUS_REQUEST_SENT
- WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for each authentication legs. This can be very inefficient for large data uploads.
To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the same socket as long as the socket is not pooled with concurrent requests competing for it.
Examples
This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is fictitious and must be replaced with the name of a server for which you have write access.
PCSTR pszData = "WinHttpWriteData Example";
DWORD dwBytesWritten = 0;
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);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"PUT",
L"/writetst.txt",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
(DWORD)strlen(pszData), 0);
// Write data to the server.
if (bResults)
bResults = WinHttpWriteData( hRequest, pszData,
(DWORD)strlen(pszData),
&dwBytesWritten);
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL);
// 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);
Requirements
Requirement | Value |
---|---|
Minimum supported client | Windows XP, Windows 2000 Professional with SP3 [desktop apps only] |
Minimum supported server | Windows Server 2003, Windows 2000 Server with SP3 [desktop apps only] |
Target Platform | Windows |
Header | winhttp.h |
Library | Winhttp.lib |
DLL | Winhttp.dll |
Redistributable | WinHTTP 5.0 and Internet Explorer 5.01 or later on Windows XP and Windows 2000. |