WinHttpSendRequest function

The WinHttpSendRequest function sends the specified request to the HTTP server.


BOOLAPI WinHttpSendRequest(
  IN HINTERNET hRequest,
  LPCWSTR      lpszHeaders,
  IN DWORD     dwHeadersLength,
  LPVOID       lpOptional,
  IN DWORD     dwOptionalLength,
  IN DWORD     dwTotalLength,
  IN DWORD_PTR dwContext



An HINTERNET handle returned by WinHttpOpenRequest.


A pointer to a string that contains the additional headers to append to the request. This parameter can be WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to append.


An unsigned long integer value that contains the length, in characters, of the additional headers. If this parameter is -1L and pwszHeaders is not NULL, this function assumes that pwszHeaders is null-terminated, and the length is calculated.


A pointer to a buffer that contains any optional data to send immediately after the request headers. This parameter is generally used for POST and PUT operations. The optional data can be the resource or data posted to the server. This parameter can be WINHTTP_NO_REQUEST_DATA if there is no optional data to send.

If the dwOptionalLength parameter is 0, this parameter is ignored and set to NULL.

This buffer must remain available until the request handle is closed or the call to WinHttpReceiveResponse has completed.


An unsigned long integer value that contains the length, in bytes, of the optional data. This parameter can be zero if there is no optional data to send.

This parameter must contain a valid length when the lpOptional parameter is not NULL. Otherwise, lpOptional is ignored and set to NULL.


An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, then WinHttpWriteData can be used to send additional data.

dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs to be changed, the caller should create a new request.


A pointer to a pointer-sized variable that contains an application-defined value that is passed, with the request handle, to any callback functions.

Return Value

Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Error codes are listed in the following table.

Error Code Description
Returned if connection to the server failed.
The secure HTTP server requires a client certificate. The application retrieves the list of certificate issuers by calling WinHttpQueryOption with the WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST option.

If the server requests the client certificate, but does not require it, the application can alternately call WinHttpSetOption with the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. In this case, the application specifies the WINHTTP_NO_CLIENT_CERT_CONTEXT macro in the lpBuffer parameter of WinHttpSetOption. For more information, see the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option.Windows Server 2003 with SP1, Windows XP with SP2 and Windows 2000:  This error is not supported.

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 URL is invalid.
The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new request handle must be created before retrying the function that originally produced this error.
The server name cannot be resolved.
The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
Returned when an incoming response exceeds an internal WinHTTP size limit.
One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error was encountered, verify through a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more information, see WINHTTP_STATUS_CALLBACK.
The WinHTTP function support is shut down or unloaded.
The request timed out.
The URL specified a scheme other than "http:" or "https:".
Not enough memory was available to complete the requested operation. (Windows error code)

Windows Server 2003, Windows XP and Windows 2000:  The TCP reservation range set with the WINHTTP_OPTION_PORT_RESERVATION option is not large enough to send this request.

The content length specified in the dwTotalLength parameter does not match the length specified in the Content-Length header.

The lpOptional parameter must be NULL and the dwOptionalLength parameter must be zero when the Transfer-Encoding header is present.

The Content-Length header cannot be present when the Transfer-Encoding header is present.

The application must call WinHttpSendRequest again due to a redirect or authentication challenge.

Windows Server 2003 with SP1, Windows XP with SP2 and Windows 2000:  This error is not supported.


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. In either case, if the request is sent successfully, the application is called back with the completion status set to WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. Upon receiving the WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE status callback, the application can start to receive a response from the server with WinHttpReceiveResponse. Before then, no other asynchronous functions can be called, otherwise, ERROR_WINHTTP_INCORRECT_HANDLE_STATE is returned.

An application must not delete or alter the buffer pointed to by lpOptional until the request handle is closed or the call to WinHttpReceiveResponse has completed, because an authentication challenge or redirect that required the optional data could be encountered in the course of receiving the response. If the operation must be aborted with WinHttpCloseHandle, the application must keep the buffer valid until it receives the callback WINHTTP_CALLBACK_STATUS_REQUEST_ERROR with an ERROR_WINHTTP_OPERATION_CANCELLED error code.

If WinHTTP is used synchronously, that is, when WINHTP_FLAG_ASYNC was not set in WinHttpOpen, an application is not called with a completion status even if a callback function is registered. While in this mode, the application can call WinHttpReceiveResponse when WinHttpSendRequest returns.

The WinHttpSendRequest function sends the specified request to the HTTP server and allows the client to specify additional headers to send along with the request.

This function also lets the client specify optional data to send to the HTTP server immediately following the request headers. This feature is generally used for write operations such as PUT and POST.

An application can use the same HTTP request handle in multiple calls to WinHttpSendRequest to re-send the same request, but the application must read all data returned from the previous call before calling this function again.

The name and value of request headers added with this function are validated. Headers must be well formed. For more information about valid HTTP headers, see RFC 2616. If an invalid header is used, this function fails and GetLastError returns ERROR_INVALID_PARAMETER. The invalid header is not added.

Windows 2000:  When sending requests from multiple threads, there may be a significant decrease in network and CPU performance.

Windows XP and Windows 2000:  See Run-Time Requirements.


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 the progress in sending the request:
Note  On Windows 7 and Windows Server 2008 R2, all of the following notifications are deprecated.
If the server closes the connection, the following notifications are also sent, provided that they have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback:

Support for Greater Than 4-GB Upload

Starting in Windows Vista and Windows Server 2008, WinHttp supports uploading files up to the size of a LARGE_INTEGER (2^64 bytes) using the Content-Length header. Payload lengths specified in the call to WinHttpSendRequest are limited to the size of a DWORD (2^32 bytes). To upload data to a URL larger than a DWORD, the application must provide the length in the Content-Length header of the request. In this case, the WinHttp client application calls WinHttpSendRequest with the dwTotalLength parameter set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH.

If the Content-Length header specifies a length less than a 2^32, the application must also specify the content length in the call to WinHttpSendRequest. If the dwTotalLength parameter does not match the length specified in the Content-Length header, the call fails and returns ERROR_INVALID_PARAMETER.

The Content-Length header can be added in the call to WinHttpAddRequestHeaders, or it can be specified in the lpszHeader parameter of WinHttpSendRequest as shown in the following code example.

BOOL fRet = WinHttpSendRequest(
			L"Content-Length: 68719476735\r\n",

Transfer-Encoding Header

Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to the server. When the Transfer-Encoding header is present on the WinHttp request, the dwTotalLength parameter in the call to WinHttpSendRequest is set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH and the application sends the entity body in one or more calls to WinHttpWriteData. The lpOptional parameter of WinHttpSendRequest must be NULL and the dwOptionLength parameter must be zero, otherwise an ERROR_WINHTTP_INVALID_PARAMETER error is returned. To terminate the chunked data transfer, the application generates a zero length chunk and sends it in the last call to WinHttpWriteData.


The following code example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that header to the server.

    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_NO_PROXY_BYPASS, 0);

    // Specify an HTTP server.
    if (hSession)
        hConnect = WinHttpConnect( hSession, L"",
                                   INTERNET_DEFAULT_HTTP_PORT, 0);

    // Create an HTTP Request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest( hConnect, L"PUT", 
                                       NULL, WINHTTP_NO_REFERER, 

    // Send a Request.
    if (hRequest) 
        bResults = WinHttpSendRequest( hRequest, 
                                       0, WINHTTP_NO_REQUEST_DATA, 0, 
                                       0, 0);

    // Place additional code here.

    // Report errors.
    if (!bResults)
        printf("Error %d has occurred.\n",GetLastError());

    // Close open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);


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.

See Also

About Microsoft Windows HTTP Services (WinHTTP)


WinHTTP Versions