Introduction
This is a fully featured Windows HTTP Wrapper in C++. It is a wrapper in the C++ class. It is fully featured and easy to use. You only need to include one single header file to use the wrapper.
Background
Several months ago, I posted my first article A Simple Windows HTTP Wrapper Using C++ on CodeProject. I continued to update it in the last several months and finally got the fully featured Windows HTTP Wrapper based on WinHTTP
APIs in C++.
Features
- Cookies supported
- Proxy supported
GET
, POST
methods supported - Request headers customization supported
- Disable automatic redirection supported
- HTTPS supported
- Receive progress supported
- Some other features
Using the Code
The class diagram is as follows:
You can understand most of the functions from their names. Please refer to the examples section for some typical examples.
Examples
Simple Get Request
Get request is the most common request. Browsing a web page causes one or several Get requests.
WinHttpClient client(L"http://www.codeproject.com/");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
Simple Post Request
Post request usually occurs while logging in or posting a thread.
WinHttpClient client(L"http://www.codeproject.com/");
string data = "title=A_NEW_THREAD&content=This_is_a_new_thread.";
client.SetAdditionalDataToSend((BYTE *)data.c_str(), data.size());
wchar_t szSize[50] = L"";
swprintf_s(szSize, L"%d", data.size());
wstring headers = L"Content-Length: ";
headers += szSize;
headers += L"\r\nContent-Type: application/x-www-form-urlencoded\r\n";
client.SetAdditionalRequestHeaders(headers);
client.SendHttpRequest(L"POST");
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
Getting Request's Progress
You can specify a callback function to get the request's progress.
bool ProgressProc(double progress)
{
wprintf(L"Current progress: %-.1f%%\r\n", progress);
return true;
}
void ProgressTest(void)
{
WinHttpClient client(L"http://www.codeproject.com/", ProgressProc);
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
}
Specifying the User Agent
User agent is a string
used by the clients to identify themselves to the web server so that the server can tell which client software you use, Internet Explorer 8, Chrome or FireFox. You can specify the user agent to pretend to be Internet Explorer 8 to fool the web server because sometimes the server only supports Internet Explorer 8.
WinHttpClient client(L"http://www.codeproject.com/");
client.SetUserAgent(L"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;...)");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
Specifying the Proxy
Sometimes, we have to connect to the web through proxies. WinHttpClient
connects to the web server directly and then uses the Internet Explorer setting to connect if it fails by default. You can also specify the proxy by calling function SetProxy
.
WinHttpClient client(L"http://www.codeproject.com/");
client.SetProxy(L"192.168.0.1:8080");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
Handling Cookies
A cookie (also tracking cookie, browser cookie, and HTTP cookie) is a small piece of text stored on a user's computer by a web browser. A cookie consists of one or more name-value pairs containing bits of information.
The cookie is sent as an HTTP header by a web server to a web browser and then sent back unchanged by the browser each time it accesses that server. A cookie can be used for authentication, session tracking (state maintenance), storing site preferences, shopping cart contents, the identifier for a server-based session, or anything else that can be accomplished through storing textual data (http://en.wikipedia.org/wiki/HTTP_cookie).
You can specify cookies to send by calling SetAdditionalRequestCookies
and get the response cookies by calling GetResponseCookies
.
WinHttpClient client(L"http://www.codeproject.com/");
client.SetAdditionalRequestCookies(L"username=jack");
client.SendHttpRequest();
wstring httpResponseCookies = client.GetResponseCookies();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
HTTPS
WinHttpClient client(L"https://www.google.com/");
client.RequireValidSslCertificates(false);
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
Multiple Requests
WinHttpClient client(L"http://www.google.com/");
client.SendHttpRequest();
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();
client.UpdateUrl(L"http://www.microsoft.com/");
client.SendHttpRequest();
httpResponseHeader = client.GetResponseHeader();
httpResponseContent = client.GetResponseContent();
A Complete Example
Codeproject.com needs logging in to download the files. This example logs in, gets the cookies, requests the source code (win_HTTP_wrapper/WinHttpClient_Src.zip) of my first CodeProject article, A Simple Windows HTTP Wrapper Using C++, and then saves the file to hard disk. This example includes cookies handling, post requests, request headers customization, etc.
WinHttpClient getClient
(L"http://www.codeproject.com/script/Membership/LogOn.aspx");
getClient.SetAdditionalRequestHeaders
(L"Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, ...");
if (!getClient.SendHttpRequest())
{
return;
}
WinHttpClient postClient
(L"http://www.codeproject.com/script/Membership/LogOn.aspx?rp=
%2fscript%2fMembership%2fLogOn.aspx");
wstring username = L"YourCodeProjectUsername";
wstring password = L"YourPassword";
postClient.SetAdditionalRequestCookies(getClient.GetResponseCookies());
string data = "FormName=MenuBarForm&Email=";
data += (char *)_bstr_t(username.c_str());
data += "&Password=";
data += (char *)_bstr_t(password.c_str());
data += "&RememberMeCheck=1";
postClient.SetAdditionalDataToSend((BYTE *)data.c_str(), data.size());
wstring headers = L"...Content-Length: %d\r\nProxy-Connection:
Keep-Alive\r\nPragma: no-cache\r\n";
wchar_t szHeaders[MAX_PATH * 10] = L"";
swprintf_s(szHeaders, MAX_PATH * 10, headers.c_str(), data.size());
postClient.SetAdditionalRequestHeaders(szHeaders);
if (!postClient.SendHttpRequest(L"POST", true))
{
return;
}
WinHttpClient downloadClient(L"win_HTTP_wrapper/WinHttpClient_Src.zip");
downloadClient.SetUserAgent(L"Mozilla/4.0
(compatible; MSIE 8.0; Windows NT 5.1; ...)");
downloadClient.SetAdditionalRequestCookies(postClient.GetResponseCookies());
if (!downloadClient.SendHttpRequest())
{
return;
}
downloadClient.SaveResponseToFile(L"C:\\WinHttpClient_Src.zip");
Points of Interest
- Sometimes, it is a good idea to get a piece of new code working first and improve it later.
- Reading the Hypertext Transfer Protocol (RFC 2616) will help a lot.
- Use HTTP monitoring tools to help the development, such as
HTTPAnalyzer
or HTTPWatch
. - It is fast and easy to use class
_bstr_t
to convert between wchar_t*
and char*
.
History
- 2010-9-21 2 enhancements, thanks Scott Leckie
- 2010-4-29 2 Bugs fixed, thanks Wong Shao Voon
- 2009-9 Fully featured version
- 2008-7 Initial version