Share a C + + encapsulated Libcurl code (support for downloading files, Get\post, redirect, and other features) __c++

Source: Internet
Author: User
Tags assert curl setcookie strlen wrapper
Preface

Previously shared a Windows on the packaging WinHTTP and WinInet API code, the results of the download page very much praise (hehe), thank you for your welcome. Article Address: Open source A C + + implementation of a simple HTTP protocol processing library, which has code resources to download the address. However, in the actual development process I found that the WinHTTP API is heavily dependent on Microsoft's IE components, the download process will appear some rare anomalies. (for example, downloading files is not the same as downloading files using a Chrome browser.) Therefore, it is necessary to replace this HTTP wrapper library. Why Choose Libcurl. Famous Libcurl, many open source software and domestic clients are used, Cross-platform, powerful features (various requests, redirects, Power continued, support HTTPS ...) )。 I've also written a small example of using Libcurl to download a file, which is just a long way from getting started: using Libcurl to download files in small cases. Code

/***************************************** * Package Libcurl download *author:jelin *date:2016 Year February 24 * * #pragma once #include <





curl/curl.h> #include <string> using std::string;

Class Clibcurlcallback {public:virtual void Progress (void* lpparam, double dtotal, double bloaded) = 0;};

Enum Libcurlflag {lf_none = 0, Lf_download, Lf_post, Lf_get,};
	Class Clibcurl {public:clibcurl (void);
	~clibcurl (void); Outer calling interface of/****************************************************************************** * Encapsulation class/bool SetPort (LONG											Port);										Set the connection port number bool settimeout (int nsecond);								Set Execution Timeout (sec) bool Setconnecttimeout (int nsecond);									Sets the Connection timeout (sec) bool Setuseragent (LPCSTR lpagent);										Set User agent bool Setresumefrom (LONG lpos);							Set the starting position of the breakpoint to be continued at bool Setresumefromlarge (Longlong llpos);						Set the starting position of the breakpoint continuation, for large file bool AddHeader (LPCSTR Lpkey, lpcstr lpvalue);												Add custom header void Clearheaderlist ();							Clean HTTP list header bool Setcookie (LPCSTR Lpcookie);		Set HTTP request cookie bool Setcookiefile (LPCSTR Lpfilepath);										Set the HTTP request cookie File const char* geterror () const;		Get error details void Setcallback (clibcurlcallback* pcallback, void* lpparam);					Set download Progress callback bool Downloadtofile (LPCSTR Lpurl, lpcstr lpfile);								Download files to disk bool Post (LPCSTR Lpurl, LPCSTR lpdata); Post String data bool Post (LPCSTR lpurl, unsigned char* lpdata, unsigned int nsize);												Post string or binary data bool get (LPCSTR Lpurl);									Get Request const string& getrespons () const;									Get Post/get Request return Data const char* GETRESPONSPTR () const;
	Obtain Post/get request return Data protected:static size_t writecallback (void* pbuffer, size_t nsize, size_t nmembyte, void* pParam);
	Static size_t Headercallback (void* pbuffer, size_t nsize, size_t nmembyte, void* pparam);

static int progresscallback (void *pparam, double dltotal, double Dlnow, double ultotal, double ulnow);
	Private:curl *m_pcurl;
	LONG M_nport;
	HANDLE M_hfile;
	Curlcode M_curlcode;
	String m_strrespons; LibcUrlflag M_lfflag;
	Curl_slist *m_curllist;
	void *m_pcallbackparam;
Clibcurlcallback *m_pcallback;
 };

#include "StdAfx.h" #include "Libcurl.h" #include <assert.h> #ifdef _debug #pragma comment (lib, "Libcurl/libcurld_ SSL ") #pragma comment (lib," Libcurl/libeay32.lib ") #pragma comment (lib," Libcurl/ssleay32.lib ") #else #pragma comment ( LIB, "Libcurl//libcurl") #endif #pragma comment (lib, "ws2_32") #pragma comment (lib, "Iphlpapi") #pragma comment (lib, "wld")  Ap32 ") Clibcurl::clibcurl (void): M_pcurl (null), M_nport (), M_hfile (INVALID_HANDLE_VALUE), m_pcallback (null),
	M_pcallbackparam (NULL), M_curlcode (CURLE_OK), M_lfflag (Lf_none), m_curllist (null) {M_pcurl = Curl_easy_init ();
	Curl_easy_setopt (M_pcurl, curlopt_writefunction, Writecallback);
Curl_easy_setopt (M_pcurl, Curlopt_writedata, this);
	} clibcurl::~clibcurl (void) {clearheaderlist ();
	Curl_easy_cleanup (M_pcurl);
	if (m_hfile!= invalid_handle_value) {CloseHandle (m_hfile);
	BOOL Clibcurl::setport (LONG port) {if (port = = M_nport) return true;
	M_nport = port; M_curlcode = curl_easy_setopt(M_pcurl, Curlopt_port, M_nport);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::settimeout (int nsecond) {if (nsecond<0) return false;
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_timeout, Nsecond);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::setconnecttimeout (int nsecond) {if (nsecond<0) return false;
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_connecttimeout, Nsecond);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::setuseragent (LPCSTR lpagent) {if (NULL = = lpagent) return false;
	int nlen = strlen (lpagent);
	if (Nlen = = 0) return false;
	M_curlcode = curl_easy_setopt (M_pcurl, curlopt_useragent, lpagent);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::setresumefrom (LONG lpos) {if (lpos<0) return false;
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_resume_from, lpos);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::setresumefromlarge (Longlong llpos) {if (llpos<0) return false; M_curlcode = Curl_easy_setoPT (M_pcurl, Curlopt_resume_from_large, Llpos);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::addheader (LPCSTR Lpkey, Lpcstr lpvalue) {assert (Lpkey!=null && lpvalue!=null);
	int nLen1 = strlen (lpkey), nLen2 = strlen (Lpvalue);
	ASSERT (nlen1>0 && nlen2>0);
	String Strheader (Lpkey);
	Strheader.append (":");
	Strheader.append (Lpvalue);
	M_curllist = Curl_slist_append (M_curllist, Strheader.c_str ());
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_httpheader, m_curllist);
return CURLE_OK = = M_curlcode;
		} void Clibcurl::clearheaderlist () {if (m_curllist) {curl_slist_free_all (m_curllist);
	M_curllist = NULL;
	} bool Clibcurl::setcookie (LPCSTR Lpcookie) {assert (lpcookie!=null);
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_cookie, Lpcookie);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::setcookiefile (LPCSTR Lpfilepath) {assert (lpfilepath!=null);
	M_curlcode = curl_easy_setopt (M_pcurl, Curlopt_cookiefile, Lpfilepath); return CURLE_OK = = m_curlcode;

Const char* Clibcurl::geterror () const {return curl_easy_strerror (M_curlcode);}
	void Clibcurl::setcallback (clibcurlcallback* pcallback, void* lpparam) {m_pcallbackparam = LpParam;
M_pcallback = pcallback; BOOL Clibcurl::D ownloadtofile (lpcstr lpurl, Lpcstr lpfile) {Curlcode code = curl_easy_setopt (M_pcurl, CURLOPT_URL,
	Lpurl);
	DeleteFileA (Lpfile);
	M_hfile = Createfilea (Lpfile, generic_write, file_share_write, NULL, create_always, file_attribute_normal, NULL);
	if (Invalid_handle_value = = m_hfile) {return FALSE;
	} curl_easy_setopt (M_pcurl, curlopt_noprogress, 0);
	Curl_easy_setopt (M_pcurl, curlopt_progressfunction, Progresscallback);
	Curl_easy_setopt (M_pcurl, Curlopt_progressdata, this);
	M_lfflag = Lf_download;
	Start execution Request M_curlcode = Curl_easy_perform (M_pcurl);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::P OST (LPCSTR Lpurl, Lpcstr lpdata) {assert (lpdata!=null);
	Curl_easy_setopt (M_pcurl, Curlopt_post, 1); Curl_easy_setopt (M_pcurl, CurlOpt_postfields, lpdata);
	Curl_easy_setopt (M_pcurl, Curlopt_postfieldsize, lpdata);
	Curl_easy_setopt (M_pcurl, Curlopt_url, Lpurl);
	M_lfflag = Lf_post;
	M_strrespons.clear ();
	M_curlcode = Curl_easy_perform (M_pcurl);
return CURLE_OK = = M_curlcode; BOOL Clibcurl::P OST (LPCSTR lpurl, unsigned char* lpdata, unsigned int nsize) {assert (Lpdata!=null && nsize&
	GT;0);
	Curl_easy_setopt (M_pcurl, Curlopt_post, 1);
	Curl_easy_setopt (M_pcurl, Curlopt_postfields, lpdata);
	Curl_easy_setopt (M_pcurl, Curlopt_postfieldsize, nsize);
	Curl_easy_setopt (M_pcurl, Curlopt_url, Lpurl);
	M_lfflag = Lf_post;
	M_strrespons.clear ();
	M_curlcode = Curl_easy_perform (M_pcurl);
return CURLE_OK = = M_curlcode;
	BOOL Clibcurl::get (LPCSTR Lpurl) {assert (lpurl!=null);
	Curl_easy_setopt (M_pcurl, Curlopt_httpget, 1);
	Curl_easy_setopt (M_pcurl, Curlopt_url, Lpurl);
	Curl_easy_setopt (M_pcurl, curlopt_followlocation, 1);//Support redirect Curl_easy_setopt (M_pcurl, Curlopt_ssl_verifypeer, 0L); Curl_easy_setopt (M_pcurl, Curlopt_ssl_verifyhost, 0L);
	M_lfflag = Lf_get;
	M_strrespons.clear ();
	M_curlcode = Curl_easy_perform (M_pcurl);
return CURLE_OK = = M_curlcode;

Const string& Clibcurl::getrespons () const {return m_strrespons;}

Const char* CLIBCURL::GETRESPONSPTR () const {return m_strrespons.c_str ();} size_t Clibcurl::writecallback (void* pbuffer, size_t nsize, size_t nmembyte, void* pparam) {//write the downloaded data to the file in an additional way (must have a,
	Otherwise the previously written content will be overwritten) clibcurl* PThis = (clibcurl*) pparam;
	DWORD dwwritten = 0; Switch (pthis->m_lfflag) {case lf_download://Download {if (pthis->m_hfile = = INVALID_HANDLE_VALUE) return
			0; if (!
		WriteFile (Pthis->m_hfile, pbuffer, Nsize*nmembyte, &dwwritten, NULL)) return 0;
	} break;
			Case Lf_post://post Data Case lf_get://get Data {pthis->m_strrespons.append (const char*) pbuffer, nsize*nmembyte);
		Dwwritten = Nsize*nmembyte;
	} break;
	Case lf_none://does not define a break;
return dwwritten; } size_t Clibcurl::headercallback ( void* pbuffer, size_t nsize, size_t nmembyte, void* pparam) {clibcurl* pThis = (clibcurl*) pparam;
return 0;  int Clibcurl::P rogresscallback (void *pparam, double dltotal, double Dlnow, double ultotal, double ulnow) {clibcurl*
	PThis = (clibcurl*) pparam;
	if (pthis->m_pcallback) {pthis->m_pcallback->progress (Pthis->m_pcallbackparam, Dltotal, Dlnow);
return 0;
 }
I am more sensitive to the style of the code, write code must be neat and clean, easy to read. PS: My comments are also very neat, here are all messed up, Csdn's web editor. )


The purpose of encapsulation is to make libcurl easier to use, using C + + packaging a series of C functions, so that we can directly set some properties, call methods, get return data and error information.


Use

The following code describes downloading, get, and post requests using a wrapper library

LibcurlLoad.cpp: Defines the entry point for a console application. #include "stdafx.h" #include "Libcurl.h" class Clibcurlcallbackex:public Clibcurlcallback {public:virtual vo
		ID Progress (void* lpparam, double dtotal, double dloaded) {if (dtotal = = 0.0) return;
		Double bpercent = (dloaded/dtotal) *100;
	printf ("Download Progress:%0.2lf%%\n", bpercent);

}

};
void Downloadtest ();
void Posttest ();
void Gettest ();
	int _tmain (int argc, _tchar* argv[]) {//downloadtest ();
	Posttest ();
	Gettest ();
return 0;
	} void Downloadtest () {const char* PURL = "Http://download.*******.com/software/1.2.3.3639/32//package";
	Clibcurl Libcurl;
	Clibcurlcallbackex CB; Libcurl. Setuseragent ("mozilla/5.0" (Windows NT 6.1;
	WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/46.0.2490.86 safari/537.36 "); Libcurl.
	Setconnecttimeout (2); Libcurl.
	Setresumefrom (2); Libcurl.
	Setcallback (&AMP;CB, NULL); Libcurl.
Downloadtofile (PURL, "c:\\test.zip");
	} void Posttest () {Clibcurl libcurl; Libcurl. Setuseragent ("mozilla/5.0" (WiNdows NT 6.1;
	WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/46.0.2490.86 safari/537.36 "); Libcurl.
	Setport (80); Libcurl.
	Setconnecttimeout (2); Libcurl.
	AddHeader ("name", "Jelin"); Libcurl.
	AddHeader ("Sex", "man"); Libcurl.
	Setcookiefile ("C:\\cookie"); char* pData = "Maintype=10001&subtype=100&appver=2.5.19.3753&sysver=microsoft Windows 7&applist=
	100:15,200:2&AMP;SIGN=2553D888BC922275ECA2FC539A5F0C1B "; Libcurl.
	Post ("Http://interface.***********.com/v2/stat/index/jingpin", pData); String strret = Libcurl.

Getrespons ();
	} void Gettest () {Clibcurl libcurl; Libcurl. Setuseragent ("mozilla/5.0" (Windows NT 6.1;
	WOW64) applewebkit/537.36 (khtml, like Gecko) chrome/46.0.2490.86 safari/537.36 "); Libcurl.
	Get ("https://www.baidu.com"); Const char* phtml = Libcurl.
	Getresponsptr (); Const char* perror = Libcurl.
GetError (); }

If you want to know the download progress, please inherit Clibcurlcallback, in the virtual function to implement the next.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.