Click here to Skip to main content
11,708,116 members (77,851 online)
Click here to Skip to main content

A Fully Featured Windows HTTP Wrapper in C++

, 22 Sep 2010 CPOL 174.6K 12.8K 276
Rate this:
Please Sign up or sign in to vote.
A fully featured and easy-to-use Windows HTTP wrapper in C++

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:

class.JPG

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.

// Set URL.
WinHttpClient client(L"http://www.codeproject.com/");
 
// Send HTTP request, a GET request by default.
client.SendHttpRequest();
 
// The response header.
wstring httpResponseHeader = client.GetResponseHeader();
 
// The response content.
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/");
 
// Set post data.
string data = "title=A_NEW_THREAD&content=This_is_a_new_thread.";
client.SetAdditionalDataToSend((BYTE *)data.c_str(), data.size());
 
// Set request headers.
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);
 
// Send HTTP post request.
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.

// Progress - finished percentage.
bool ProgressProc(double progress)
{
    wprintf(L"Current progress: %-.1f%%\r\n", progress);
    return true;
}
 
void ProgressTest(void)
{
    // Set URL and call back function.
    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/");
 
// Set the user agent to the same as Internet Explorer 8.
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/");
 
// Set the proxy to 192.168.0.1 with port 8080.
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/");
 
// Set the cookies to send.
client.SetAdditionalRequestCookies(L"username=jack");
 
client.SendHttpRequest();
 
// Get the response cookies.
wstring httpResponseCookies = client.GetResponseCookies();
 
wstring httpResponseHeader = client.GetResponseHeader();
wstring httpResponseContent = client.GetResponseContent();

HTTPS

WinHttpClient client(L"https://www.google.com/");

// Accept any certificate while performing HTTPS request.
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();

// Update the URL.
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.

// 1. Get the initial cookie.
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;
}
 
// 2. Post data to get the authentication cookie.
WinHttpClient postClient
	(L"http://www.codeproject.com/script/Membership/LogOn.aspx?rp=
	%2fscript%2fMembership%2fLogOn.aspx");
 
// Post data.
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());
 
// Post headers.
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;
}
 
// 3. Finally get the zip file.    
WinHttpClient downloadClient(L"win_HTTP_wrapper/WinHttpClient_Src.zip");
downloadClient.SetUserAgent(L"Mozilla/4.0 
		(compatible; MSIE 8.0; Windows NT 5.1; ...)");
 
// Sending this cookie makes the server believe you have already logged in.
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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

shicheng
Software Developer Philips
China China
Cheng Shi is a software developer in China. He is interested in COM, ATL, Direct3D, etc. He is now working for Philips.

Cheng Shi loves Formula1 and watchs every Grand Prix. He is dreaming to be a racing car driver. Hope his dream can come true.

You may also be interested in...

Comments and Discussions

 
SuggestionStudents will not make it Pin
Member 84741974-Apr-15 14:47
memberMember 84741974-Apr-15 14:47 
GeneralRe: Students will not make it Pin
Genkobar16-Jun-15 16:33
memberGenkobar16-Jun-15 16:33 
SuggestionHttps example Pin
Member 1067569216-Mar-14 23:06
memberMember 1067569216-Mar-14 23:06 
QuestionFew include files missing Pin
Pandian Raju17-Feb-14 9:28
memberPandian Raju17-Feb-14 9:28 
AnswerRe: Few include files missing Pin
lightniinja12-Jan-15 20:37
memberlightniinja12-Jan-15 20:37 
QuestionUser and password Authentication Pin
reivaj11719-Dec-13 1:57
memberreivaj11719-Dec-13 1:57 
AnswerRe: User and password Authentication Pin
shicheng22-Dec-13 0:34
membershicheng22-Dec-13 0:34 
Questionwchar_t compile errors in RegExp.h Pin
Vern Jensen12-Dec-13 16:47
memberVern Jensen12-Dec-13 16:47 
AnswerRe: wchar_t compile errors in RegExp.h Pin
Member 127940731-Mar-14 7:43
memberMember 127940731-Mar-14 7:43 
QuestionProject which uses <wininet.h> Pin
Michael Haephrati17-Oct-13 8:26
mvpMichael Haephrati17-Oct-13 8:26 
AnswerRe: Project which uses <wininet.h> Pin
Member 936400819-Oct-13 18:10
memberMember 936400819-Oct-13 18:10 
GeneralRe: Project which uses <wininet.h> Pin
Michael Haephrati20-Oct-13 6:45
mvpMichael Haephrati20-Oct-13 6:45 
GeneralRe: Project which uses <wininet.h> Pin
Member 936400820-Oct-13 6:59
memberMember 936400820-Oct-13 6:59 
GeneralRe: Project which uses <wininet.h> Pin
Michael Haephrati20-Oct-13 7:10
mvpMichael Haephrati20-Oct-13 7:10 
GeneralRe: Project which uses <wininet.h> Pin
Member 936400820-Oct-13 17:35
memberMember 936400820-Oct-13 17:35 
QuestionHTTP content not complete Pin
Member 1030225530-Sep-13 7:13
memberMember 1030225530-Sep-13 7:13 
AnswerRe: HTTP content not complete Pin
Md Atiqur Rahman (Atique)12-Aug-15 16:22
memberMd Atiqur Rahman (Atique)12-Aug-15 16:22 
QuestionThanks a lot. Pin
Member 95446636-Sep-13 16:30
memberMember 95446636-Sep-13 16:30 
GeneralThanks for posting this. Pin
Member 835136114-Jul-13 6:20
memberMember 835136114-Jul-13 6:20 
SuggestionPartial reading Pin
Member 100922565-Jun-13 5:02
memberMember 100922565-Jun-13 5:02 
GeneralRe: Partial reading Pin
shicheng5-Jun-13 16:19
membershicheng5-Jun-13 16:19 
BugA few issues Pin
Member 100922565-Jun-13 4:47
memberMember 100922565-Jun-13 4:47 
GeneralRe: A few issues Pin
shicheng5-Jun-13 16:08
membershicheng5-Jun-13 16:08 
GeneralMy vote of 5 Pin
madkoala19-May-13 0:42
membermadkoala19-May-13 0:42 
Questionhow is it possibility to use this Wrapper in Win CE ? Pin
O_D_I_M16-May-13 2:35
memberO_D_I_M16-May-13 2:35 
AnswerRe: how is it possibility to use this Wrapper in Win CE ? Pin
shicheng16-May-13 16:12
membershicheng16-May-13 16:12 
GeneralMy vote of 5 Pin
Member 1004277410-May-13 5:24
memberMember 1004277410-May-13 5:24 
GeneralMy vote of 2 Pin
KarstenK17-Apr-13 1:54
memberKarstenK17-Apr-13 1:54 
GeneralMy vote of 5 Pin
Marcos Roberto Silva21-Mar-13 10:49
memberMarcos Roberto Silva21-Mar-13 10:49 
Question'RequireValidSslCertificates' is not a member of 'WinHttpClient' Pin
kuhliefumdenteich30-Jan-13 2:01
memberkuhliefumdenteich30-Jan-13 2:01 
AnswerRe: 'RequireValidSslCertificates' is not a member of 'WinHttpClient' Pin
black_wizard2-Aug-13 1:13
memberblack_wizard2-Aug-13 1:13 
GeneralMy vote of 5 Pin
littlewater27-Jan-13 20:29
memberlittlewater27-Jan-13 20:29 
QuestionGreat library Pin
Yiannis Spyridakis13-Dec-12 0:02
memberYiannis Spyridakis13-Dec-12 0:02 
GeneralMy vote of 5 Pin
Fred Ackers20-Sep-12 11:55
memberFred Ackers20-Sep-12 11:55 
QuestionMy Vote of 5 Pin
Philippe Marechal16-Sep-12 1:48
memberPhilippe Marechal16-Sep-12 1:48 
GeneralMy vote of 5 Pin
rahul.kulshreshtha31-Jan-12 23:01
memberrahul.kulshreshtha31-Jan-12 23:01 
QuestionHow to Retrieve cookies from browsers? Pin
Avinash Pachar20-Dec-11 21:14
memberAvinash Pachar20-Dec-11 21:14 
QuestionWinHttpWriteData and large data Pin
petushok18-Oct-11 5:34
memberpetushok18-Oct-11 5:34 
Questionwhy must i include WinCrypt.h in StringProcess.h, but the sample compiles without?? Pin
Member 303633916-Oct-11 3:35
memberMember 303633916-Oct-11 3:35 
Questionhowto compile with multi-byte charset? Pin
Member 303633916-Oct-11 3:31
memberMember 303633916-Oct-11 3:31 
AnswerRe: howto compile with multi-byte charset? Pin
el_tel17-Feb-13 11:35
memberel_tel17-Feb-13 11:35 
AnswerRe: howto compile with multi-byte charset? Pin
Sgz31-May-13 2:56
memberSgz31-May-13 2:56 
GeneralRe: howto compile with multi-byte charset? Pin
Member 835136114-Jul-13 9:52
memberMember 835136114-Jul-13 9:52 
AnswerCannot POST on Windows 7 Pin
redgreenloko5-Oct-11 3:56
memberredgreenloko5-Oct-11 3:56 
GeneralRe: Cannot POST on Windows 7 Pin
hans23456729-Jan-12 9:56
memberhans23456729-Jan-12 9:56 
QuestionWinHttpClient wrapped in a DLL Pin
Balthasar21-Sep-11 23:29
memberBalthasar21-Sep-11 23:29 
QuestionProxy and Running as SYSTEM Pin
Member 820973718-Sep-11 20:22
memberMember 820973718-Sep-11 20:22 
AnswerRe: Proxy and Running as SYSTEM Pin
shicheng19-Sep-11 2:28
membershicheng19-Sep-11 2:28 
GeneralRe: Proxy and Running as SYSTEM Pin
Member 820973719-Sep-11 12:59
memberMember 820973719-Sep-11 12:59 
GeneralRe: Proxy and Running as SYSTEM Pin
shicheng19-Sep-11 21:18
membershicheng19-Sep-11 21:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150819.1 | Last Updated 22 Sep 2010
Article Copyright 2010 by shicheng
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid