Microsoft Windows HTTP Services (WinHTTP) provides developers with a server-supported, high-level interface to the HTTP/1.1 Internet protocol. WinHTTP is designed to be used primarily in server-based scenarios by server applications that communicate with HTTP servers.
WinINet was designed as an HTTP client platform for interactive desktop applications, such as Microsoft Internet Explorer, Microsoft Office, and Microsoft Money. WinINet displays a user interface for some operations such as collecting user credentials. WinHTTP, however, handles these operations programmatically. Server applications that require HTTP client services should use WinHTTP instead of WinINet. For more information, see Porting WinINet Applications to WinHTTP.
WinHTTP is also designed for use in system services and HTTP-based client applications. However, single-user applications that require FTP protocol functionality, cookie persistence, caching, automatic credential dialog handling, Internet Explorer compatibility, or downlevel platform support should consider using WinINet.
This interface is accessible from C/C++ by using either the WinHTTP application programming interface (API), or by using the IWinHttpRequest and IWinHttpRequestEvents interfaces. WinHTTP is also accessible from script and Microsoft Visual Basic through the WinHTTP object. For more information and descriptions of the individual functions, see the WinHTTP functions reference for the specific language.
Caution WinHTTP is not reentrant except during asynchronous completion callback. That is, while a thread has a call pending to one of the WinHTTP functions such as WinHttpSendRequest, WinHttpReceiveResponse, WinHttpQueryDataAvailable, WinHttpSendData, or WinHttpWriteData, it must never call WinHTTP a second time until the first call has completed. One scenario under which a second call could occur is as follows: If an application queues an Asynchronous Procedure Call (APC) to the thread that calls into WinHTTP, and if WinHTTP performs an alertable wait internally, the APC can run. If the APC routine happens also to call WinHTTP, it reenters the WinHTTP API, and the internal state of WinHTTP can be corrupted.
WinHTTP 5.1 Features
The following features have been added in version 5.1 of WinHTTP:
IPv6 support.
AutoProxy capabilities.
HTTP/1.0 protocol, including support for keep-alive (persistent) connections and session cookies.
HTTP/1.1 chunked transfer support for HTTP responses.
Keep-alive pooling of anonymous connections across sessions.
Secure Sockets Layer (SSL) functionality, including client certificates. Supported SSL protocols include the following: SSL 2.0, SSL 3.0, and Transport Layer Security (TLS) 1.0.
Support for server and proxy authentication, including integrated support for Microsoft Passport 1.4 and the Negotiate/ Kerberos package.
Automatic handling of redirects unless suppressed.
Scriptable interface in addition to the API.
Trace utility to help troubleshoot problems.
A number of WinINet features are not supported in WinHTTP, including URL caching and persistent cookies, autoproxy, autodialing, offline support, and File Transfer Protocol (FTP).
The IWinHttpRequestEvents interface provides events for Microsoft Windows HTTP Services (WinHTTP). It uses only event methods.
Methods:
OnError
Occurs when there is a run-time error in the application.
OnResponseDataAvailable
Occurs when data is available from the response.
OnResponseFinished
Occurs when the response data is complete.
OnResponseStart
Occurs when the response data starts to be received.
The following class can be used to connect with the events fired by the IWinHttpRequestEvents Interface.
' ########################################################################################
' Class CIWinHttpRequestEvents
' Interface name = IWinHttpRequestEvents
' IID = {F97F4E15-B787-4212-80D1-D380CBBF982E}
' IWinHttpRequestEvents Interface
' Attributes = 384 [&H180] [Nonextensible] [Oleautomation]
' ########################################################################################
CLASS CIWinHttpRequestEvents GUID$("{F61C1135-792C-4845-95A5-981C19B4F477}") AS EVENT
INTERFACE IWinHttpRequestEventsImpl GUID$("{F97F4E15-B787-4212-80D1-D380CBBF982E}") AS EVENT
INHERIT IUnknown
' =====================================================================================
METHOD OnResponseStart ( _
BYVAL nStatus AS LONG _ ' __in long Status
, BYVAL ContentType AS WSTRING _ ' __in BSTR ContentType
) ' void
' *** Insert your code here ***
END METHOD
' =====================================================================================
' =====================================================================================
METHOD OnResponseDataAvailable ( _
BYREF pData AS DWORD _ ' __in SAFEARRAY *Data
) ' void
' *** Insert your code here ***
END METHOD
' =====================================================================================
' =====================================================================================
METHOD OnResponseFinished
' *** Insert your code here ***
END METHOD
' =====================================================================================
' =====================================================================================
METHOD OnError ( _
BYVAL ErrorNumber AS LONG _ ' __in long ErrorNumber
, BYVAL ErrorDescription AS WSTRING _ ' __in BSTR ErrorDescription
) ' void
' *** Insert your code here ***
END METHOD
' =====================================================================================
END INTERFACE
END CLASS
The following code example shows how to open an HTTP connection, send an HTTP request, and get all of the headers from the response.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' get all of the headers from the response.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL bstrResponseHeaders AS WSTRING
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response headers
bstrResponseHeaders = pWHttp.GetAllResponseHeaders
MSGBOX bstrResponseHeaders
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following code example shows how to open an HTTP connection, send an HTTP request, and get the date header from the response.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' get the date header from the response.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL bstrResponseHeader AS WSTRING
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://microsoft.com"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response headers
bstrResponseHeader = pWHttp.GetResponseHeader("Date")
MSGBOX bstrResponseHeader
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following example shows how to open an HTTP connection, send an HTTP request, and read the response text.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response text.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL bstrResponseText AS WSTRING
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.powerbasic.com"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Gets the response entity body as a string
bstrResponseText = pWHttp.ResponseText
MSGBOX bstrResponseText
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following example shows how to open an HTTP connection, send an HTTP request, and read the response body.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response body.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL vBody AS VARIANT
LOCAL nBytes AS LONG
LOCAL buffer AS STRING
DIM vByteArray(0) AS BYTE
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.powerbasic.com"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response body
vBody = pWHttp.ResponseBody
' Convert the variant to an array of bytes
vByteArray() = vBody
' Convert the array of bytes to a string
nBytes = UBOUND(vByteArray) - LBOUND(vByteArray) + 1
IF nBytes THEN
buffer = PEEK$(VARPTR(vByteArray(0)), nBytes)
MSGBOX buffer
END IF
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
Same as above, but using the safe array API functions.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response body.
' Same as EX_WHTTP_ResponseBody.bas, but using the safe array API functions.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL vBody AS VARIANT
LOCAL nBytes AS LONG
LOCAL buffer AS STRING
LOCAL pv AS tagVARIANT PTR
LOCAL nDims AS LONG
LOCAL nLBound AS LONG
LOCAL nUBound AS LONG
LOCAL pData AS DWORD
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.powerbasic.com"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response body
vBody = pWHttp.ResponseBody
' Get a pointer to the returned safearray
pv = VARPTR(vBody)
IF @pv.parray THEN
' Retrieve the number of dimensions (must be 1)
nDims = SafeArrayGetDim(@pv.parray)
IF nDims = 1 THEN
' Retrieve the number of elements of the array
SafeArrayGetLBound(@pv.parray, 1, nLBound)
SafeArrayGetUBound(@pv.parray, 1, nUBound)
' Calculate the number of bytes to read
nBytes = nUbound - nLBound + 1
IF nBytes THEN
' Lock the safearray for access
SafeArrayAccessData(@pv.parray, pData)
IF pData THEN
' Read the data
buffer = PEEK$(pData, nBytes)
' Unlock the array
SafeArrayUnaccessData(@pv.parray)
' Show the data
MSGBOX buffer
END IF
END IF
END IF
END IF
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following example shows how to open an HTTP connection, send an HTTP request, and read the response body. The downloaded image, returned as an array of bytes, is saved into a file.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response body. The downloaded image, returned as an array of bytes, is saved
' into a file.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL vBody AS VARIANT
DIM vByteArray(0) AS BYTE
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response body
vBody = pWHttp.ResponseBody
IF OBJRESULT = %S_OK THEN
' Convert the variant to an array of bytes
vByteArray() = vBody
' Save the array into a file
OPEN "ms-banner.gif" FOR BINARY AS #1
PUT #1, 1, vByteArray()
CLOSE #1
MSGBOX "File saved"
END IF
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following example shows how to open an HTTP connection, send an HTTP request, and read the response as an IStream. The data from the IStream is written to a file.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response as an IStream. The data from the IStream is written to a file.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL vSTream AS VARIANT
LOCAL pIStream AS IStream
LOCAL Buffer AS STRING * 8192
LOCAL strBuffer AS STRING
LOCAL cb AS DWORD
LOCAL cbRead AS DWORD
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response as a stream
vStream = pWHttp.ResponseStream
IF VARIANTVT(vStream) = %VT_UNKNOWN THEN
pIStream = vStream
vStream = EMPTY
' Read the stream in chunks
DO
pIStream.Read VARPTR(buffer), SIZEOF(buffer), cbRead
IF cbRead = 0 THEN EXIT DO
IF cbRead < SIZEOF(buffer) THEN
strBuffer = strBuffer & LEFT$(buffer, cbRead)
ELSE
strBuffer = strBuffer & buffer
END IF
LOOP
pIStream = NOTHING
' Save the buffer into a file
OPEN "ms-banner.gif" FOR BINARY AS #1
PUT #1, 1, strBuffer
CLOSE #1
MSGBOX "File saved"
END IF
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
Same as above but reading all the data in one call instead of by chunks.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response as an IStream. The data from the IStream is written to a file.
' ========================================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "httprequest.inc"
#INCLUDE ONCE "ole2utils.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN
LOCAL pWHttp AS IWinHttpRequest
LOCAL vSTream AS VARIANT
LOCAL pIStream AS IStream
LOCAL tstatstg AS STATSTG
LOCAL strBuffer AS STRING
LOCAL cb AS DWORD
LOCAL cbRead AS DWORD
LOCAL iSucceeded AS INTEGER
' Creates an instance of the HTTP service
pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
IF ISNOTHING(pWHttp) THEN EXIT FUNCTION
TRY
' Opens an HTTP connection to an HTTP resource
pWHttp.Open "GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif"
' Sends an HTTP request to the HTTP server
pWHttp.Send
' Wait for response with a timeout of 5 seconds
iSucceeded = pWHttp.WaitForResponse(5)
' Get the response as a stream
vStream = pWHttp.ResponseStream
IF VARIANTVT(vStream) = %VT_UNKNOWN THEN
pIStream = vStream
vStream = EMPTY
' Get the size of the stream
pIStream.Stat(tstatstg, %STATFLAG_NONAME)
' Use a string as a buffer
strBuffer = SPACE$(tstatstg.cbsize)
' Read the stream
pIStream.Read STRPTR(strBuffer), LEN(strBuffer), cbRead
IF cbRead < tstatstg.cbsize THEN strBuffer = LEFT$(strBuffer, cbRead)
pIStream = NOTHING
' Save the buffer into a file
OPEN "ms-banner.gif" FOR BINARY AS #1
PUT #1, 1, strBuffer
CLOSE #1
MSGBOX "File saved"
END IF
CATCH
OleShowErrorInfo OBJRESULT
END TRY
END FUNCTION
' ========================================================================================
The following code example shows how to set the automatic logon policy to never use NTLM or Negotiate authentication automatically.
DIM pHttpReq AS IWinHttpRequest
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "https://www.fabrikam.com/", %FALSE
' Do not automatically send user credentials
pHttpReq.SetAutoLogonPolicy 2
' Send the HTTP Request
pHttpReq.Send
The following code example shows how to select a client certificate to send with a request. A certificate with the subject "My Middle-Tier Certificate" is chosen from the "Personal" certificate store in the registry under HKEY_LOCAL_MACHINE.
DIM pHttpReq AS IWinHttpRequest
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "https://www.fabrikam.com/", %FALSE
' Select a client certificate.
pHttpReq.SetClientCertificate "LOCAL_MACHINE\Personal\My Middle-Tier Certificate"
' Send the HTTP Request
pHttpReq.Send
The following code example shows how to open an HTTP connection, set credentials for the server, send an HTTP request, and read the response text.
DIM pHttpReq AS IWinHttpRequest
DIM bstrResponseText AS WSTRING
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Set credentials for server.
pHttpReq.SetCredentials "User Name", "Password", %HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
' Send the HTTP Request
pHttpReq.Send
' Get the response text
bstrResponseText = pWHttp.ResponseText
? bstrResponseText
The following code example shows how to set the proxy settings for a particular proxy server, open an HTTP connection, send an HTTP request, and read the response text. These proxy settings work only if you have a proxy server named "proxy_server" that uses port 80 and your computer can bypass the proxy server when the host name ends with ".microsoft.com".
DIM pHttpReq AS IWinHttpRequest
DIM bstrResponseText AS WSTRING
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Set proxy settings.
pHttpReq.SetProxy %HTTPREQUEST_PROXYSETTING_PROXY, "proxy_server:80", "*.microsoft.com"
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Send the HTTP Request
pHttpReq.Send
' Get the response text
bstrResponseText = pWHttp.ResponseText
? bstrResponseText
The following example shows how to set all WinHTTP time-outs to 30 seconds, open an HTTP connection, send an HTTP request, and read the response text.
DIM pHttpReq AS IWinHttpRequest
DIM bstrResponseHeaders AS WSTRING
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Set time-outs. If time-outs are set, they must be set before open.
pHttpReq.SetTimeouts 30000, 30000, 30000, 30000
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Send the HTTP Request
pHttpReq.Send
' Get all response headers
bstrResponseHeaders = pWHttp.GetAllResponseHeaders
? bstrResponseHeaders
The following code example shows how to open an HTTP connection, set a request header, send an HTTP request, and read the response headers.
DIM pHttpReq AS IWinHttpRequest
DIM bstrResponseHeaders AS WSTRING
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Set request header.
pHttpReq.SetRequestHeader "Date", "Fri, 16 Mar 2001 00:25:54 GMT"
' Send the HTTP Request
pHttpReq.Send
' Get all response headers
bstrResponseHeaders = pWHttp.GetAllResponseHeaders
? bstrResponseHeaders
The following code example shows how to open an HTTP connection, send an HTTP request, display the Status and StatusText, and read the response text.
DIM pHttpReq AS IWinHttpRequest
DIM bstrResponseHeaders AS WSTRING
' Create an instance of the HTTP service
pHttpReq = NEWCOM "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Send the HTTP Request
pHttpReq.Send
' Display the status.
? pHttpReq.Status " - " pHttpReq.StatusText
' Get all response headers
bstrResponseHeaders = pWHttp.GetAllResponseHeaders
? bstrResponseHeaders
The following code example shows how to set and view the user agent string option and other options.
DIM pHttpReq AS IWinHttpRequest
DIM vValue AS VARIANT
' Create an instance of the HTTP service
pHttpReq = NEWCOM ON "WinHttp.WinHttpRequest.5.1"
' Open an HTTP connection
pHttpReq.Open "GET", "http://microsoft.com", %FALSE
' Specify the user agent
pHttpReq.put_Option(%WinHttpRequestOption_UserAgentString, "A WinHttpRequest Example Program"
' Send the HTTP Request.
pHttpReq.Send
' Read WinHTTP option values.
vValue = pHttpReq.Option(%WinHttpRequestOption_UserAgentString)
vValue = pHttpReq.Option(%WinHttpRequestOption_URL)
vValue = pHttpReq.Option(%WinHttpRequestOption_URLCodePage)
vValue = pHttpReq.Option(%WinHttpRequestOption_EscapePercentInURL)