WinHTTPWrappers v1.35 A set of
C++ classes to encapsulate WinHTTP
Welcome to WinHTTPWrappers, a set of C++ classes to encapsulate WinHTTP and especially
its asynchronous support. The classes are based on the MSDN Magazine article about
WinHTTP by Kenny Kerr at
https://docs.microsoft.com/en-us/archive/msdn-magazine/2008/august/windows-with-c-asynchronous-winhttp.
You should read this article to get a better understanding on how to properly use
WinHTTP (especially when in asynchronous mode). Coming back to my classes then should
make more sense<gg>.
The classes provided are: WinHTTPWrappers::CHandle, WinHTTPWrappers::CSession,
WinHTTPWrappers::CConnection, WinHTTPWrappers::CRequest,
WinHTTPWrappers::CResolver, WinHTTPWrappers::CWebSocket, WinHTTPWrappers::CAsyncDownloader &
WinHTTPWrappers::CSyncDownloader.
CHandle provides a class based encapsulation of a HINTERNET handle and
various WinHTTP methods which work on any HINTERNET type handle. It also provides
a prebuilt virtual callback method called "OnCallback" which derived classes
can customize.
CSession provides encapsulation of a WinHTTP session HINTERNET handle.
It provides an "Initialize" method which encapsulates the WinHttpOpen
API.
CConnection provides encapsulation of a WinHTTP connection HINTERNET handle.
It provides an "Initialize" method which encapsulates the WinHttpConnect
API.
CRequest provides encapsulation of a WinHTTP request HINTERNET handle.
It provides an "Initialize" method which encapsulates the WinHttpOpenRequest
API. It also encapsulates all the WinHTTP API calls which take a request handle
such as WinHttpAddRequestHeaders, WinHttpQueryHeaders, WinHttpReadData, WinHttpQueryAuthSchemes
etc etc.
CResolver provides encapsulation of a WinHTTP resolver HINTERNET
handle as created via the WinHttpCreateProxyResolver API.
CWebSocket provides encapsulation of a WinHTTP web sockets HINTERNET
handle as created via the WinHttpWebSocketCompleteUpgrade API.
CAsyncDownloader which derives from CRequest which provides for a high
level wrapping of an asynchronous WinHTTP request. It supports sending request bodies
from a file or from an in-memory array. It also supports downloading to a file or
to an in-memory array. Internally this class looks after a memory buffer and file
for downloading the request into. It also supports various authentication schemes
and bandwidth throttling. It also implements proper thread protection of these values
to ensure correct operation when WinHTTP is used in asynchronous mode. It also provides
a number of virtual methods, including OnReadData, OnWriteData, GetHeaders, GetContentLength,
DoAuthentication, ChooseAuthScheme, On407Response, On401Response and OnCallbackComplete
which provide various notifications during the lifetime of a WinHTTP download request.
Finally CSyncDownloader which derives from CAsyncDownloader is provided.
This class provides a high level wrapping of a synchronous WinHTTP request.
Features
- Provides a simple C++ Header only module to easily encapsulate WinHTTP.
- Supports both WinHTTP synchronous and asynchronous modes.
- Provides a complete wrapping for all the WinHTTP functionality.
- Provides a version of a asynchronous callback method which dumps all the
status to the debugger output window when in debug mode. This helps provides
a good understanding of the various callbacks which WinHTTP can provide.
The enclosed zip file contains the
WinHTTPWrappers source code and a simple VC 2017 dialog based application which
demonstrates the classes using a simply asynchronous download of a HTTP page to
a local file using the "CMyDownloadFileWinHTTPRequest" class. It also
demonstrates cancelling of pending requests as well as reporting the various callbacks
which occur during the download.
Copyright
- You are allowed to include the source code in any product (commercial, shareware,
freeware or otherwise) when your product is released in binary form.
- You are allowed to modify the source code in any way you want except you
cannot modify the copyright details at the top of each module.
- If you want to distribute source code with your application, then you are
only allowed to distribute versions released by the author. This is to maintain
a single distribution point for the source code.
Updates
v1.35 (10 May 2023)
- Updated copyright details.
- Updated module to indicate that it needs to be compiled using
/std:c++17. Thanks to Martin Richter for reporting this issue.
v1.34 (17 August 2022)
- Reset more member variables in CAsyncDownloader::ReleaseResources.
- CAsyncDownloader::m_dwLastStatusCode is now implemented as a
std::optional.
- CAsyncDownloader::m_nContentLength is now implemented as a
std::optional.
- Made all CAsyncDownloader member variables public to allow easier
customisation of the class
- Implemented a version of CAsyncDownloader::SendRequest which allows the
headers to be provided as a parameter.
- Implemented a version of CSyncDownloader ::SendRequestSync which allows
the headers to be provided as a parameter.
- Reworked CAsyncDownloader::On407Response,
CAsyncDownloader::On401Response and CAsyncDownloader::OnRequestErrorCallback
to use correct value for dwTotalLength when calling WinHttpSendRequest.
- Reworked CSyncDownloader::SendRequestSync to call OnCheckStatusCode
method.
v1.33 (16 May 2022)
- Fixed a static code analysis warning from PVS-Studio in
CHandle::_Callback related to an unnecessary ATLASSERT. Thanks to David
Lowndes for reporting this issue.
- Fixed a static code analysis warning from PVS-Studio in the CWebSocket
class which had an unnecessary "m_h" member that clashes with the same named
member in the base class CHandle. Thanks to David Lowndes for reporting this
issue.
v1.32 (10 February 2022)
- Updated the code to use C++ uniform initialization for all variable
declarations
- Replaced ATL::CHeapPtr variables with std::vector.
v1.31 (22 January 2022)
- Updated copyright details.
- Fixed more static code analysis warnings in Visual Studio 2022.
v1.30 (25 July 2021)
- Moved the QueryConnectionGroup method from CHandle into CConnection and
CRequest
- Moved some of the resuable functionality in
CAsyncDownloader::OnHeadersAvailableCallback into a new virtual
OnCheckStatusCode method.
v1.29 (24 July 2021)
- Added support for new WinHttpQueryConnectionGroup API available in
latest Windows 11 SDK.
- Fixed up return value handling in GetProxySettingsVersion.
v1.28 (9 April 2021)
- Updated copyright details
- Fixed more /analyze static code analysis warnings in the code.
v1.27 (13 November 2020)
- Added support for new WinHttpReadDataEx & WinHttpQueryHeadersEx APIs
available in latest Windows 10 SDK.
v1.26 (12 April 2020)
- Fixed more Clang-Tidy static code analysis warnings in the code.
v1.25 (1 February 2020)
- Fixed a bug in the sample app when calling the WinHttpCrackUrl. Thanks
to Onur Senturk for reporting this issue.
- Fixed a bug in CSyncDownloader::SendRequestSync where the resources
would not be released if the download was successful. Again thanks to to
Onur Senturk for reporting this issue.
v1.24 (18 January 2020)
- Updated copyright details
- Fixed more Clang-Tidy static code analysis warnings in the code.
- Replaced BOOL with bool in various places
v1.23 (17 December 2019)
- Fixed various Clang-Tidy static code analysis warnings in the code.
v1.22 (3 November 2019)
- Updated initialization of various structs to use C++ 11 list
initialization
v1.21 (16 September 2019)
- Updated code to handle all 2XX response codes.
v1.20 (14 August 2019)
- Fixed some further compiler warnings when using VC 2019 Preview v16.3.0
Preview 2.0
- Added support for new WinHttpAddRequestHeadersEx API available in latest
Windows 10 SDK
v1.19 (23 June 2019)
- Updated the code to clean compile when _ATL_NO_AUTOMATIC_NAMESPACE is
defined.
v1.18 (19 April 2019)
- Updated copyight details
- Updated the code to clean compile on VC 2019
v1.17 (24 November 2018)
- Fixed some further compiler warnings when using VS 2017 15.9.2
v1.16 (29 September 2018)
- Removed code which supported WINHTTPWRAPPERS_MFC_EXTENSIONS define
- Added wrappers for WinHttpWebSocketCompleteUpgrade,
WinHttpWebSocketSend, WinHttpWebSocketReceive, WinHttpWebSocketShutdown,
WinHttpWebSocketClose & WinHttpWebSocketQueryCloseStatus APIs.
- Added wrappers for WinHttpGetProxyForUrlEx,
WinHttpGetProxyForUrlEx2, WinHttpGetProxyResult & WinHttpGetProxyResultEx
APIs.
- Reworked TimeSinceStartDownload to use GetTickCount64 API.
v1.15 (2 September 2018)
- Fixed a number of compiler warnings when using VS 2017 15.8.2
v1.14 (23 May 2018)
- Replaced NULL with nullptr throughout the code.
- Fixed a number of C++ core guidelines compiler warnings. These
changes mean that the code will now only compile on VC 2017 or later.
v1.13 (18 September 2017)
- Replaced CString::operator LPC*STR() calls throughout the codebase with
CString::GetString calls
v1.12 (27 April 2017)
- Updated the code to compile cleanly using /permissive-.
v1.11 (16 April 2017)
- Updated copyright details.
- Added support for WinHttpCreateProxyResolver, WinHttpResetAutoProxy, WinHttpWriteProxySettings,
WinHttpReadProxySettings & WinHttpGetProxySettingsVersion from the latest
Windows 10 SDK
v1.10 (6 March 2016)
- Updated copyright details.
- The CAsyncDownloader destructor now resets the status callback function
via SetStatusCallback(NULL, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS). This prevents
spurious callbacks occuring after the C++ object is destroyed which depending
on how you allocated the C++ object could cause access violations in CHandle::_Callback.
- Optimized the logic in the sample app when updating the edit box with status
information
v1.09 (7 November 2015)
- Updated SAL annotations in CHandle::SetOption to be consistent with Windows
10 SDK.
- Fixed an issue in the use of _When_ SAL annotation in CHandle::SetOption.
- Update the code to compile cleanly on VC 2015.
v1.08 (14 June 2015)
- Addition of a CAsyncDownloader::GetLastStatusCode method.
- CAsyncDownloader::OnHeadersAvailableCallback and CSyncDownloader::SendRequestSync
now preserves the HTTP status code when the value received is not 200, 206,
401 or 407 and the return value ATL::AtlHresultFromWin32(ERROR_WINHTTP_INVALID_HEADER)
is about to be returned.
- CSyncDownloader::SendRequestSync method has been made virtual.
- Update the sample app to report the last status code if available when a
download request fails.
v1.07 (11 March 2015)
- Optimized allocation of temporary string stack variables in CAsyncDownloader::Initialize &
CAsyncDownloader::DeleteDownloadedFile. Thanks to Paul Jackson for reporting
this issue.
v1.06 (8 March 2015)
- Updated copyright details.
- Reworked the classes to optionally compile without MFC. By default the classes
now use STL classes and idioms but if you define WINHTTPWRAPPERS_MFC_EXTENSTIONS
the classes will revert back to the MFC behaviour.
- Moved all the classes to a WinHTTPWrappers namespace
- Renamed CWinHTTPHandle class to CHandle
- Renamed CWinHTTPSession class to CSession
- Renamed CWinHTTPConnection class to CConnection
- Renamed CWinHTTPRequest class to CRequest
- Renamed CAsyncWinHTTPDownloader class to CAsyncDownloader
- Renamed CSyncWinHTTPDownloader class to CSyncDownloader
- DeleteDownloadedFile now checks to see if "m_sFileToDownloadInto"
is valid before it calls DeleteFile. Thanks to Paul Jackson for reporting this
issue.
- Reworked the CAsyncDownloader::SendRequest, On407Response, On401Response &
OnRequestErrorCallback methods to pass a more correct value for the "dwTotalLength"
parameter in the call to WinHttpSendRequest. Thanks to Paul Jackson for reporting
this issue.
v1.05 (8 June 2014)
- Updated copyright details.
- Updated CAsyncWinHTTPDownloader::Initialize to allow the dwShareMode parameter
of the ATL::CAtlFile::Create call for the file instances to be download and
uploaded to be customized. The default value for the share mode is now 0 instead
of FILE_SHARE_READ. Thanks to Simon Orde for providing this nice addition.
- All the class methods have had SAL annotations added
v1.04 (1 December 2013)
- Updated the code to clean compile on VC 2013.
v1.03 (30 March 2013)
- Updated copyright details.
- Updated the sample app to correctly release the file handles when the file
is downloaded. Thanks to David Lowndes for reporting this bug.
- Updated the code to clean compile on VC 2012.
- TimeSinceStartDownload() method has been extended to return a __int64 return
value instead of a DWORD.
- Changed class names to use C*WinHTTP* prefix instead of C*WinHttp*.
v1.02 (1 August 2011)
- CDownloadFileWinHttpRequest class is now called CAsyncWinHttpDownloader
- Major rework of the CAsyncWinHttpDownloader to now support HTTP and Proxy
authentication, pre-authentication, resumed downloads, file uploads, in-memory
arrays and bandwidth throttling.
- Fixed an issue in TraceCallback where WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
would be reported incorrectly by TRACE statements
- Addition of a new CSyncWinHttpDownloader class which provides for synchronous
WinHTTP downloads.
- Updated the sample app to allow all of the new configuration settings of
CAsyncWinHttpDownloader and CSyncWinHttpDownloader classes to be exercised.
- Fixed a bug in CWinHTTPRequest::WriteData() where buffer parameter was incorrectly
set as a LPVOID instead of a LPCVOID.
v1.01 (30 May 2011)
- All tracing in CWinHTTPHandle::OnCallback has been moved into a new TraceCallback
method which client code is free to call. Also all tracing in CWinHTTPHandle::
OnCallbackComplete has been moved into a new TraceCallbackComplete method. Also
all tracing in CDownloadFileWinHttpRequest::OnCallbackComplete has been moved
into a new TraceCallbackComplete method.
- Moved cleanup of resources from CDownloadFileWinHttpRequest::OnCallbackComplete
to a new public method called ReleaseResources()
v1.0 (29 May 2011)