Introduction
WinINet makes network programming easier, but it's difficult to use for C++ because of its C-style interface, so I write this code to wrap it. Using it, you can easily create an asynchronous HTTP request and receive event callback. It can be applied to MFC and ATL projects.
This code mainly consists of two classes: class FCHttpRequest
and class FCHttpRequestManager
.
Class FCHttpRequest
is responsible for implementing send HTTP request and receive response, it's a wrapper class for WinINet.
Class FCHttpRequestManager
is a management of FCHttpRequest
, responsible for add, delete FCHttpRequest
object and receive event from FCHttpRequest
.
Similar to the STL and Boost, all source code consists of .h and .inl file, you can easily integrate it into your program.
How to Use
- Include http_request_manager.h file in your project. normally include it at the end of the stdafx.h.
- Create HTTP request manager class derived from class
FCHttpRequestManager
.
class CMyManager : public FCHttpRequestManager
{
};
class CMyManager : public CDialog,
public FCHttpRequestManager
{
virtual void OnAfterRequestSend (FCHttpRequest& rTask)
{
}
virtual void OnAfterRequestFinish (FCHttpRequest& rTask)
{
}
};
The manager will receive two events: OnAfterRequestSend
and OnAfterRequestFinish
, overwrite event you find interesting. Most of the time, we should overwrite OnAfterRequestFinish
to process received data.
- Now, you can send HTTP request by calling
AddRequest
.
Examples
... Download File
Send HTTP request:
AddDownload (_T("http://phoxo.com/t.zip")) ;
HTTP_REQUEST_HEADER h ;
h.m_url = _T("http://phoxo.com/t.zip") ;
h.m_start = 30 ; AddRequest (h) ;
Response finish event, process downloaded data:
void OnAfterRequestFinish (FCHttpRequest& rTask)
{
const HTTP_RESPONSE_INFO & r = rTask.GetResponseInfo() ;
bool bOK = false ;
if (r.m_status_code == HTTP_STATUS_OK)
{
if (r.m_content_length)
{
if (r.m_content_length == rTask.GetTotalReceiveByte())
bOK = true ;
}
else
{
if (r.m_final_read_result)
bOK = true ;
}
}
if (bOK)
{
std::string receive_data ;
rTask.PopReceived (receive_data) ;
}
}
... Specifying the User-Agent
HTTP_REQUEST_HEADER h ;
h.m_url = _T("http://phoxo.com/") ;
h.m_user_agent = _T("My User-Agent") ;
AddRequest (h) ;
... Custom HTTP Header
HTTP_REQUEST_HEADER h ;
h.m_url = _T("http://phoxo.com/") ;
h.m_header += _T("Referer: http://google.com\r\n") ;
h.m_header += _T("Accept: */*\r\n") ;
h.m_header += _T("x-flash-version: 10,0,0,1\r\n") ;
AddRequest (h) ;
... Specifying the Proxy
HTTP_REQUEST_HEADER h ;
h.m_url = _T("http://phoxo.com/") ;
h.m_proxy_ip = _T("8.8.8.8") ;
h.m_proxy_port = 8080 ;
AddRequest (h) ;
... Decompress GZip HTTP Data
This feature requires the ZLib library, you can get it from http://www.zlib.org.
Include headers in the following order:
#include "zlib.h"
#include "http_request_manager.h"
#include "utility/gzip_decompress.h"
Add Accept-Encoding
field in request header, notify the server that you can accept gzip compressed data:
HTTP_REQUEST_HEADER h ;
h.m_url = _T("http://phoxo.com/") ;
h.m_header += L"Accept-Encoding: gzip, deflate\r\n" ;
AddRequest (h) ;
In finish callback, you can use gzip_decompress
to decompress received data.
void OnAfterRequestFinish (FCHttpRequest& rTask)
{
std::string receive_data ;
rTask.PopReceived (receive_data) ;
if (IsReceiveGZipStream(rTask) && receive_data.size())
{
std::string raw_data ;
if (gzip_decompress (receive_data.c_str(), receive_data.size(), raw_data))
{
receive_data = raw_data ;
}
}
}
... Post multipart/form-data
std::vector<byte /> buf ;
FCFileEx::Read (_T("c:\\1.jpg"), buf) ;
HTTP_REQUEST_HEADER h (HTTP_REQUEST_HEADER::VERB_TYPE_POST_MULTIPART) ;
h.m_url = _T("http://phoxo.com/") ;
h.AddMultipartFormData ("param1", "value1") ;
h.AddMultipartFormData ("param2", "value2") ;
h.AddMultipartFormData ("pic", &buf[0], buf.size(), "1.jpg") ;
h.EndMultipartFormData() ;
m_task_id = AddRequest (h) ;
... HTTPS
HTTP_REQUEST_HEADER h ;
h.m_url = _T("https://phoxo.com/") ;
h.m_open_flag |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID ;
h.m_open_flag |= INTERNET_FLAG_IGNORE_CERT_DATE_INVALID ;
AddRequest (h) ;
History
- 25th August, 2011: V2.0
- Refactoring code, more features, more efficient
- Added multipart/form-data POST support
- Added HTTPS support
- Added GZip decompress support
- 30th January, 2010: V1.1
- Renamed from
FCHttpDownloadExec
to FCHttpDownload
- Fixed a bug when popping a modal dialog in callback
- Modified interface of
FCHttpRequestManager
- Got default User-Agent from Internet Explorer
- 17th November, 2009: Initial post