Introduction
The WinHttpGateway is a dynamic library to simplify a work with
the WinHttp API. It is wrapper code for this API. WinHtpp API is a
replacement of WinINet API (see About
WinHTTP for more information of Microsoft recommends to use
WinHttp API). Feature of the given library is usage of an
asynchronous mode of data transfer. The library is used as
dynamically connected module and gives the simple interface that it
was possible to spend from any thread calls independent of another
threads of http protocol. Also the library supports (at base level)
the HTTPS protocol. The library can be used in services, to organize
call on HTTP/HTTPS protocols.
The quick review of library usage.
Dynamic module export function
Since the library was developed as dynamically connected actually
it exports only one function (that is a GetInterface).
extern "C" LPVOID __declspec(dllexport)
GetInterface()
{
return static_cast(&g_winhttplauncher);
}
Which returns the pointer on the interface which gives functionality
of the given library. For convenience of usage in C ++ a code of the
given library wrapper the interface IWinHttpLauncher (class
CWinHttpLauncherStub which gives the call mechanism to dynamic
WinHttpGateway.dll module). And for using of library it is enough to
include the file WinHttpGateway.h. And then to connect to the library
module you should create class CWinHttpLauncherStub.
Usage example can be looked in project WinHttpGatewayTest.
The elementary usage of WinHttpGateway.dll module.
int _tmain(int _argc, TCHAR* _argv[], TCHAR* _envp[])
{
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
cerr << _T("Fatal Error: MFC initialization failed") << endl;
return 1;
}
CWinHttpLauncherStub winhttp;
CString sPath = _T("WinHttpGateway.dll");
if(!winhttp.load(sPath) || !winhttp)
{
CString mess;
mess.Format(_T("Can`t load %s"),(LPCTSTR)sPath);
::AfxMessageBox(mess,MB_OK|MB_ICONERROR);
return 1;
}
CString sProxyURL = _T("");
CString sBypass = _T("");
CString sLogin = _T("");
CString sPassword = _T("");
DWORD dwErrCode = 0;
LPTSTR szError = NULL;
if(!winhttp.initilize(IWinHttpLauncher::PAT_NO_PROXY,sProxyURL,sBypass,&dwErrCode,&szError))
{
CString mess;
mess.Format(_T("Initialization error code = %d \"%s\""),dwErrCode,szError);
::AfxMessageBox(mess,MB_OK|MB_ICONERROR);
winhttp.free_string(szError);
return 1;
}
winhttp.set_options(
IWinHttpLauncher::Option_ProxyLogin
,IWinHttpLauncher::OptionScope_Root
,(LPVOID)(LPCTSTR)sLogin
);
winhttp.set_options(
IWinHttpLauncher::Option_ProxyPassword
,IWinHttpLauncher::OptionScope_Root
,(LPVOID)(LPCTSTR)sPassword
);
CString sUrl = _T("http://www.codeproject.com/info/about.aspx");
CString sMethod = _T("GET");
CString sHeaders = _T("");
CString sData2Send = _T("");
LPTSTR szHeaders = NULL;
LPTSTR szContentType = NULL;
LPTSTR szReadedData = NULL;
if(!winhttp.request(
sUrl,sMethod,sData2Send,sHeaders
,&szHeaders,&szContentType,&szReadedData
,&dwErrCode,&szError
)
)
{
CString mess;
mess.Format(_T("Request error [url=%s] code = %d \"%s\""),(LPCTSTR)sUrl,dwErrCode,szError);
::AfxMessageBox(mess,MB_OK|MB_ICONERROR);
winhttp.free_string(szError);
return 1;
}
long i = 0;
CString sReadedData = szReadedData;
cout << _T("Data was readed") << endl;
cout << _T("ContentType = ") << szContentType << endl;
cout << _T("Data length ") << sReadedData.GetLength() << endl;
cout << _T("Data:") << endl;
for(i=0;i<sReadedData.GetLength();i+=256) cout << (LPCTSTR)sReadedData.Mid(i,256);
winhttp.free_string(szHeaders);
winhttp.free_string(szContentType);
winhttp.free_string(szReadedData);
return 0;
}
Source codes can be found in a folder “contest”. If it is
used proxy a server it need to use other parameter at initialization
and it is necessary to set URL a server proxy, and also a login and
the password of the user (if is necessary).
The example of more difficult usage of library can be found in
a test example (folder WinHttpGatewayTest).
I will result the small description of interface
IWinHttpLauncher.
Interface IWinHttpLauncher is documented in a code (file
WinHttpGateway.h).
Enumerations.
enum ProxyAccessTypeEn
– describes operating
modes WinHttp API.
enum OptionsEn
– describes options for
customization WinHttp API, given for customization in the
WinHttpGateway dynamic module.
enum OptionScopeEn
– sets a scope of an
installed option (see section "The setting an options
(configuration WinHttp API through WinHttpGateway)").
Functions.
void enable_tracing (BOOL _en) const
– enables
or disables tracing of WinHttp API (see WinHttpTraceCfg.exe,
a Trace Configuration Tool for specification of details)
BOOL check_platform () const
– returns TRUE if
the given operating system supports WinHttp API.
BOOL initilize (<br />IN ProxyAccessTypeEn
_proxyaccess<br />,IN LPCTSTR _proxyname<br />,IN
LPCTSTR _proxybypass<br />,OUT DWORD* _dwErrCode<br />,OUT
LPTSTR* _szError<br />);
– Function of
initialization of WinHttpGateway module. It is possible to select to
use a proxy server or not, to install URL of a proxy server, and also
URL list for which it will be bypassed this proxy server. Further all
calls will be carried out, using the sets values.
BOOL set_options(<br />IN OptionsEn _option<br />,IN
OptionScopeEn _scope<br />,IN LPVOID _lpdata<br />);
- Sets options for calls.
BOOL request(<br />IN LPCTSTR _szUrl<br />,IN
LPCTSTR _szMethod<br />,IN LPCTSTR _szData2Send<br />,IN
LPCTSTR _szHeaders2Send<br />,OUT LPTSTR*
_pszReadedHeaders<br />,OUT LPTSTR* _pszContentType<br />,OUT
LPTSTR* _pszReadedData<br />,OUT DWORD* _dwErrCode<br />,
OUT LPTSTR* _pszError<br />);
– Carries out
synchronous call to the URL, set in the parameter
_szUrl
,
by method
_szMethod
, with the data for transmission
_szData2Send
, and headers for transmission
_szHeaders2Send
. But it is important that at call from
parallel threads independent calls (requests will be made
simultaneously and independently) will be carried out.
BOOL request(<br />IN LPCTSTR _szUrl<br />,IN
LPCTSTR _szMethod<br />,IN LPCTSTR _szData2Send<br />,IN
LPCTSTR _szHeaders2Send<br />,IN LPCTSTR _szXSLTFName<br />,OUT
LPTSTR* _pszReadedHeaders<br />,OUT LPTSTR*
_pszContentType<br />,OUT LPTSTR* _pszReadedData<br />,OUT
LPTSTR** _ppszTagNames<br />,OUT LPTSTR**
_ppszTagValues<br />,OUT DWORD* _dwErrCode<br />,OUT
LPTSTR* _pszError<br />);
– Similarly
previous function, but the answer from a server if it has type
'text/xml' will be returned in the form of two lists of strings (in
the first list will be returned names of tags, in the second values
of these tags). Also the returned data can be handled with the help
of xslt conversions (parameter
_szXSLTFName
, setting a
filename of xslt conversions (xstl file)).
void enum_certificates(<br />OUT LPTSTR**
_ppszStorage<br />,OUT LPTSTR** _ppszName<br />);
– Returns the list of the installed certificates in system. For
the use of this names for installation of the used certificate for
realization of calls on https (through function
set_options()
).
Above described functions, return TRUE if call is made
successfully and FALSE in other case. In case of an error the text
error message comes back in parameter _pszError
,
and an error code in parameter _dwErrCode
.Some
error codes are defined for WinHttpGateway module (see file
WinHttpGateway\messages.mc) the others belong the API of operating
system, including WinHttp API. Also if function returns pointers on
strings or on arrays of strings they need to be freed on the client
side. To release this selected data it is better to usefree_list()
and free_string()
functions of class
CWinHttpLauncherStub.
Class CWinHttpLauncherStub.
It is intended to present the WinHttpGateway dynamic module for
the programmer in the form of a class.
Functions.
bool load(LPCTSTR _szDllName)
– loads
WinHttpGateway module into the memory, receives the interface for
operation with this dll module.
void unload()
– unloads WinHttpGateway (dll
module).
operator bool()
- gives the information of validity
of class CWinHttpLauncherStub. A class valid if the module is
successfully loaded and it is possible to call the functions given by
interface IWinHttpLauncher
of this module. The class is
inherited from interface IWinHttpLauncher
and
readdresses to the loaded dynamic module calls if it is loaded (or
only outputs assert and don`t make any calls).
static void free_list(LPTSTR* _ppsz)
– function
releases the memory selected for the list of string values, the
functions of interface IWinHttpLauncher
received by
calls (WinHttpGateway module).
static long get_listlength(LPTSTR* _ppsz)
–
function returning length of the list of string values returned by
interface IWinHttpLauncher
functions (WinHttpGateway
module).
static void free_string(LPTSTR _psz)
– the
function releasing memory selected for string value in WinHttpGateway
module and returned to a code that use this module.
More information about the library.
The setting an options (configuration WinHttp API through
WinHttpGateway).
Since the usual circuit of creation/use the WinHttpGateway module
the creation of class CWinHttpLauncherStub
in one
(usually main thread), and further parallel usage in different
threads (workflows) the setter of a scope of installed options is
provided. Therefore distinguish root options (options which can be
used, as options by default, in all threads) and options of a current
thread which are used only in this thread. I.e. if in any thread use
some option as the option by default, not the current thread option
than this option takes from root options set (by default they
initialized by default values (see file
WinHttpGateway\WinHttpGateway.h, the description of listing OptionsEn
for specification of such values)).
The internal view of library.
The short description of classes (in alphabetic order).
class CAutoLock
- a class realizing automatic locking
for some code snippet with usage of a critical section.
template class CAutoRefPtr
- a template class for
implementation of intellectual pointers of the data. In a code this
template class is used for support of separate parts of the data
received on demand.
struct CBuffer
– the data buffer. It is
intended (at present) for internal data storage. Realizes data
conversions for usage of this data in different representations.
class CCertificate
– a class for presentation
of certificates. Stores a name of storage of the certificate and a
certificate name, and also gives PCCERT_CONTEXT
for
certificate representation in system.
class CCertificates
– the list of certificates.
The list is formed of all certificates installed on the computer for
the given user or the computer (the data about a possible set is
extracted from the register).
struct CHttpVersionInfo
– structure is a
wrapper of system structure HTTP_VERSION_INFO
.
class CmpStrNoCase
– a class extending the
CString class and supporting matching without case sensitivity.
class CPassword
– a class for password
representation.
template class CPropertyBase
– a template class
for implementation of a class of options from fundamental types of
the data.
class CPropMassAction
– realizes operations
over all options.
class CPropMassActionIni
– extends
CPropMassAction
and realizes saving/loading of options
in/from the register.
struct CRefCounter
– a base class of count of
references.
struct CUrlComponents
– a wrapper of system
structure URL_COMPONENTSW
.
class CWinHttp
– an asynchronous class
operation with WinHttp API.
struct CWinHttp::CRequestInfo
- an information set
about request.
struct CWinHttpAsyncResult
– a wrapper for
system structure WINHTTP_ASYNC_RESULT
.
struct CWinHttpAutoproxyOptions
– a wrapper for
system structure WINHTTP_AUTOPROXY_OPTIONS
.
struct CWinHttpCertificateInfo
– a wrapper for
system structure WINHTTP_CERTIFICATE_INFO
.
struct CWinHttpCurrentUserIEProxyConfig
– a
wrapper for system structure WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
.
class CWinHttpError
– a class an exception used
in the WinHttpGateway module.
class CWinHttpGatewayApp
- a class of module
implementation.
class CWinHttpLauncher
- implementation of the unit
for data reading under the circuit: one thread one request. Internal
implementation of interface IWinHttpLauncher
.
class CWinHttpLauncherStub
– a wrapper (for the
programmer – users of the WinHttpGateway module) interface
IWinHttpLauncher
. The class is intended for
simplification of operation with WinHttpGateway module from a client
code.
class CWinHttpLog
– file implementation of a
log of WinHttpGateway module.
struct CWinHttpProxyInfo
– a wrapper of system
structure WINHTTP_PROXY_INFO
.
struct CWinHttpRequest
– implementation of one
request.
struct CXSLTFile
– a class for support of
pooling of xslt files for optimisation of conversions.
class CXSLTProcessor
– the processor of the
data. Realises xslt conversion.
template class IniAccessorBase
– a template
class for implementation traits of the data which are used as an
option.
template class IniAccessorMassAction
– template
implementation of the mechanism (strategy) of saving of the data for
options in a ini file.
interface IWinHttpLauncher
– the interface for
call with WinHttpGateway module
interface IWinHttpRequest
– the interface for
operation with the one request.
template class NullAccessorAction
– template
implementation of the mechanism (strategy) null savings of the data
(don`t save/load anything).
The review of functioning of library
Class of the interface IWinHttpLauncher
.
class CWinHttpLauncher
– is internal
implementation of interface IWinHttpLauncher
with which
help functionality of library WinHttpGateway is given. The given
class stores in itself a set of options, for support of configuration
WinHttp API. The reference to class CWinHttp which realizes directly
operation with WinHttp API (realizing the mechanism of asynchronous
calls). And also the list of certificates a variable of class
CCertificates
which is used for storage and data
representation about certificates in system for support of operation
with certificates in WinHttpGateway module.
At initialization phase is created an object of class CWinHttp
which is used further for the organization of requests.
The main works of this class occurs in functions request(). In it
there is an object of class CWinHttpRequest
, is
initialized, transferred in class CWinHttp
and simply
waits the end of this request (line: request.waitEOR();
).
Setting of options occurs through function set_options()
which simply sets value of the internal variable storing the list of
options. (The error comes back through SetLastError()
,
and can be received by calling of GetLastError()
function, if set_options()
has returned value FALSE).
A class of a kernel of operation with WinHttp API
class CWinHttp
- is a basis of functioning of the
given library. It will organize asynchronous processing of requests:
installation of function of a callback, support of callbacks, data
transfer, waiting of possibility of data transfer,
saving/accumulation of the data received by call. And also support of
processing of some errors which the given module automatically can
handle and to inform the user of WinHttpGateway module only at
impossibility automatically to handle this errors.
As operation to be made asynchronously almost all works of a class
consists in operation callback functions
CWinHttp::WinHttpStatusCallback()
which calls initiate
all operation of WinHttpGateway module on operation with HTTP/HTTPS
requests. We will consider messages from WinHttp API and functions
which handle these messages.
WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
WINHTTP_CALLBACK_STATUS_REDIRECT
WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
Are
handled by function CWinHttp::RequestStatus()
which
simply hands over the information on the status to a class of request
CWinHttpRequest
.
WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
– Are not handled.
WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
It is handled by function CWinHttp::RequestDataAvailable()
.
The given message comes in the presence of the data for reception or
for informing that no more data will be available. If all data is
transferred (the size == 0) the request will be closed and it
processing will be ended. If the size is more then zero, then the
buffer will be created, and function for query of the data of request
will be called from WinHttp API.
WINHTTP_CALLBACK_STATUS_HEADERS_AVAILAB
It is handled by function CWinHttp::RequestHeadersAvalable()
.
The given function supports possibility of authentification both:
from a site, and from a proxy server if a proxy server or a site
request such operations.
If authentification it is not necessary, the header of the come
data is simply requested. And further the size of the data for
reading of this request is requested.
As "errors" which can be handled WinHttpGateway module
(Is the query of the certificate and necessity to transfer request
repeatedly ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED
,
ERROR_WINHTTP_RESEND_REQUEST
) are in addition handled.
WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
It is handled by function CWinHttp::RequestIntermediateResponse()
,
which in other does nothing.
WINHTTP_CALLBACK_STATUS_READ_COMPLETE
It is handled by function CWinHttp::RequestReadComplete()
.
Which transfere the buffer from the status “reading of the
data”, in the status “the data was readed” and
query a new chunk of data.
WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
It is handled CWinHttp::RequestError()
. The given
function handles errors which WinHttpGateway module can handle, or
forms error message which are transferred to the object of class
CWinHttpRequest
, representing the request data.
WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
It is handled by function CWinHttp::RequestSecureFailure()
.
The given function instal ignoring of some errors for operations with
certificates.
WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
It is handled by function CWinHttp::RequestSendCompleted()
.
The given message comes, if the dispatched query consists of several
parts and the given function forces transmission of consecutive
number of pieces of the data. If all data is sent, data receiving is
initiated.
WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
It is handled by function CWinHttp::RequestWriteCompleted()
,
which is almost exact copy of function
CWinHttp::RequestSendCompleted()
, possessing the same
functionality.
Other functions.
CWinHttp::create()
– creates request under its
description by the pointer on the object of class CWinHttpRequest
which is transferred as parametre of the given function. In this
function there is an analysis of URL of request, opening of the
request and sending it.
CWinHttp::Send()
– sends request. How it is
necessary to dispatch request (from the data about errors and/or
messages from WinHttp API), the given function install the given
authentifications and then dispatches request (also and repeatedly).
CWinHttp::set_Certificate()
– frames operation
on installation of the certificate for some request.
CWinHttp::add_request()
, CWinHttp::find_request()
,
CWinHttp::remove_request()
– support functions:
request addition in the internal list of requests, search of the
necessary request on its descriptor, and also request removal (the
termination of operation with request).
void CWinHttp::free()
– function of a stop of
operation of the object of class CWinHttp
Attention: customization of possible
level of safety on operation with certificates it is possible/is
necessary to make at CWinHttp::RequestSecureFailure()
.
An request class
struct CWinHttpRequest
– a class giving
request. This class implements interface IWinHttpRequest
which is used in class CWinHttp
for operation with
request. The class is intended for a request configuration at a phase
before its transmission to class CWinHttp
and further
for data acquisition on demand.
Attention: at present it is not realized
any mechanisms of synchronization of this class.
Other classes.
template class CPool
– a template class for the
organization of a pool. Classes of objects of a pool must be
inherited from a class template struct Construct
which
imposes certain agreements for a pool data item.