`

UtilBox(ub)基础组件 -- EasyCurl 发送http请求(2)

阅读更多

       EasyCurl简单封装了一下libcurl调用,对外的提供抽象化的接口,下面就把源码分享出来,此源码和接口还带进一步完善优化,尤其是一些curl_set_opt()的上层封装。大家可以自己写哈,最后写一个满足自己需求的Curl。

       ubplus_curl.h : EasyCurl的类定义和接口,还有一些宏

/*
* =====================================================================================
 *
 *       Filename:  ubplus_curl.h
 *
 *    Description:  A curl wrapper of libcurl
 *
 *        Created:  08/16/2012 04:55:34 PM
 *       Compiler:  g++ 4.6.1
 *
 *         Author:  Michael LiuXin
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdint.h>
#include <memory.h>
#include <string>
#include <curl/curl.h>

//#define NO_USE_UB_LOG
#include "ub_log.h"

#define	UBPLUS_CURL_OK									0 	/* OK */
#define	UBPLUS_CURL_GLOBAL_INIT_FAILD		1 	/* curl_global_init */
#define	UBPLUS_CURL_EASY_INIT_FAILD			2 	/* curl_easy_init */
#define	UBPLUS_CURL_PERFORM_FAILD				3 	/* curl_easy_perform */
#define	UBPLUS_CURL_SET_OPTION_FAILD		4 	/* curl_easy_setopt */
#define	UBPLUS_CURL_HANDLE_NOT_VAILD 		5 	/* CURL* bad*/
#define	UBPLUS_CURL_URL_NOT_VAILD 			6 	/* url string bad */
#define	UBPLUS_CURL_POST_NOT_VAILD 			7 	/* post data bad */
#define UBPLUS_CURL_USER_BUFFER_NOT_VAILD   8   /* user buffer bad */
#define UBPLUS_CURL_TIMEOUT_NOT_VAILD   	9   /* time bad */

namespace ubplus
{
	typedef size_t (*CURL_CALLBACK)(char*,size_t,size_t,void*);

	extern const char* ERROR_MSG[];

	/**
	 * Wrapper of libcurl
	 */
	class EasyCurl
	{
		public:

			/** 
			 * @brief  : constructor , initialize libcrul
			 */
			EasyCurl();

			/**
			 * @brief  : destroy CURL* 
			 */
			~EasyCurl();

			/** 
			 * @brief  : do curl action
			 *
			 * @return : curl ok or not , get_error() will set
			 */
			int fetch();

			/** 
			 * @brief  : set user's buffer , if we do fetch() then we 
			 * 			 write the content to buffer if user set their
			 * 			 own callback , this buffer will ignore
			 *
			 * @param  : [out] user buffer 
			 * 			 [in] buffer length  
			 *
			 * @return : if buffer is invaild , get_error() will set
			 */
			int set_user_buffer(char** buf,size_t len);

			/** 
			 * @brief  : give curl a callback which is called
			 * 			 when fetched data is ready to copy
			 *
			 * @param  : function pointer
			 */
			int set_curl_callback(CURL_CALLBACK);

			/** 
			 * @brief  : pass to callback lastest param
			 *
			 * @param  : function pointer
			 */
			int set_curl_callback_context(void*);

			/** 
			 * @brief  : curl_set_opt(CURLOPT_URL)
			 *
			 * @param  : [in] url , url string 
			 *
			 * @return : if CURL* not vaild , get_error() will set
			 */
			int set_url(std::string url);

			/** 
			 * @brief  : curl_set_opt(CURLOPT_TIMEOUT)
			 *
			 * @param  : [in] timeout , time in seconds 
			 *
			 * @return : if CURL* not vaild , get_error() will set
			 */
			int set_timeout(unsigned long time);

			/** 
			 * @brief  : enable post method and set post data
			 *
			 * @param  : [in] post , post data
			 *
			 * @return : if CURL* not vaild , get_error() will set
			 */
			int set_post_data(void* post);


			/** 
			 * @brief  : test the curl is good to using
			 *
			 * @return : true , would be used
			 */
			bool is_good() {return this->is_good_;}

			uint8_t get_error(){return this->error_;}

			const char* get_error_msg(){return ERROR_MSG[this->error_];}
			
			bool __global_init();

			static size_t __data_callback(char*,size_t,size_t,void*);

			static size_t total_size(){return total_size_;}

		protected :

			static bool global_init_;

			/* user buffer */
			typedef struct __curl_buffer {
				__curl_buffer(){mem=NULL;offset=0;max=0;}
				char* 	mem;
				size_t 	offset;
				size_t 	max;
			}curl_buffer;

			static curl_buffer user_buffer;

			static size_t total_size_;
			
		private :
			CURL* curl_;
			uint8_t error_;
			bool is_good_;
			
	}; 	// end of class 



} 	// end of namespace


        ubplus_curl.cc :  实现,用到了ub_log.h日志组件

/*
 * =====================================================================================
 *
 *       Filename:  ubplus_curl.cc
 *
 *    Description:  A curl wrapper of libcurl
 *
 *        Created:  08/16/2012 04:55:34 PM
 *       Compiler:  g++ 4.6.1
 *
 *         Author:  Michael LiuXin
 *
 * =====================================================================================
 */
#include "ubplus_curl.h"

#define CURL_OK 0

namespace ubplus
{
	#define CURL_GLOBAL_INIT_ONCE __global_init();

	const char* ERROR_MSG[] = {
		"EasyCurl OK",
		"Global Init Failed",
		"Easy Init Failed",
		"Easy Perform Failed",
		"Easy SetOption Failed",
		"Curl Handle Not Vaild",
		"Curl URL Not Vaild",
		"Curl PostData Not Vaild",
		"Curl User Buffer Not Vaild",
		"Curl TimeOut Not Vaild",

		"Unkown Error"
	};

	// ***********************************************************
 	size_t EasyCurl::__data_callback(char* content,size_t size,size_t n,void* null)
	{
		UB_LOG_DEBUG("[ok=curl] Default callback invoke");
		// copy to buffer(this is from user) and ensure space is enough
		if (NULL != EasyCurl::user_buffer.mem) {

			size_t full = n*size;

			// we have no space
			if (EasyCurl::user_buffer.offset >= EasyCurl::user_buffer.max) {
				UB_LOG_TRACE("[ok=curl] User buffer has no space , ignore ");
				return full;
			}

			// as write enough as we can
			size_t to_write = (EasyCurl::user_buffer.offset+n*size<EasyCurl::user_buffer.max
					? n*size : (EasyCurl::user_buffer.max-EasyCurl::user_buffer.offset));

			memcpy(EasyCurl::user_buffer.mem+EasyCurl::user_buffer.offset,content,to_write);
			UB_LOG_DEBUG("[ok=memory] Copy memory to user buffer");
			EasyCurl::user_buffer.offset += to_write;
			EasyCurl::total_size_ += to_write;
		} 

		return n*size;

	}

	// ***********************************************************
	bool EasyCurl::__global_init()
	{
		if (!EasyCurl::global_init_) {
			// call global init only one time
			CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
			if (CURL_OK != code) {
				this->is_good_ = false;
				this->error_ = UBPLUS_CURL_GLOBAL_INIT_FAILD;
				UB_LOG_FATAL("[err=curl] Curl global init error[%s]",curl_easy_strerror(code));
				return false;
			} else {  	
				UB_LOG_TRACE("[ok=curl] Curl global init");
				EasyCurl::global_init_ = true;
				return true;
			}
		} else
			return true;

	}

	// ***********************************************************
	EasyCurl::EasyCurl()
	{
		CURL_GLOBAL_INIT_ONCE

		// curl initial
		this->curl_ = curl_easy_init();
		if (!this->curl_) {
			this->error_ = UBPLUS_CURL_EASY_INIT_FAILD;
			this->is_good_ = false;
			UB_LOG_WARNNING("[warn=curl] Curl easy init failed");
			return;
		} else {
			// set our default write function
			if (CURL_OK != curl_easy_setopt(this->curl_,CURLOPT_WRITEFUNCTION,EasyCurl::__data_callback)) {
				this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
				this->is_good_ = false;
			} else {
				this->error_ = UBPLUS_CURL_OK;
				this->is_good_ = true;
			}
		}
			
	}
	
	// ***********************************************************
	EasyCurl::~EasyCurl()
	{
		if (this->curl_) {
			UB_LOG_DEBUG("[ok=curl] Curl cleanup ok");
			curl_easy_cleanup(this->curl_);
		}
	}

	// ***********************************************************
	int EasyCurl::set_curl_callback(CURL_CALLBACK func)
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
						
		if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_WRITEFUNCTION,func))
			return UBPLUS_CURL_OK;
		else {
			UB_LOG_WARNNING("[warn=curl] set option[call_back] failed");
			this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
			return UBPLUS_CURL_SET_OPTION_FAILD;	
		}
	}

	// ***********************************************************
	int EasyCurl::set_curl_callback_context(void* user_context)
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
						
		if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_WRITEDATA,user_context))
			return UBPLUS_CURL_OK;
		else {
			UB_LOG_WARNNING("[warn=curl] set option[call_back_context] failed");
			this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
			return UBPLUS_CURL_SET_OPTION_FAILD;	
		}
	}
	
	// ***********************************************************
	int EasyCurl::set_user_buffer(char** user,size_t len) 
	{
		if (NULL == user || NULL == *user || 0 == len) {
			this->is_good_ = false;
			return this->error_ = UBPLUS_CURL_USER_BUFFER_NOT_VAILD;
		}

		EasyCurl::user_buffer.mem = *user;
		memset(EasyCurl::user_buffer.mem,0,len);
		EasyCurl::user_buffer.offset = 0;
		EasyCurl::user_buffer.max = len;
		UB_LOG_DEBUG("[ok=curl] User Buffer set");

		return UBPLUS_CURL_OK;
	}

	// ***********************************************************
	int EasyCurl::fetch() 
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;
		
		// actual perform curl
		CURLcode code = curl_easy_perform(this->curl_);
		// don't forget to clear user buffer
		EasyCurl::user_buffer.offset = 0;
		if (CURL_OK == code) {
			return UBPLUS_CURL_OK;
		} else {
			UB_LOG_WARNNING("[warn=curl] curl perform error[%s]",curl_easy_strerror(code));
			this->error_ = UBPLUS_CURL_PERFORM_FAILD;
			return UBPLUS_CURL_PERFORM_FAILD;
		}
	}

	// ***********************************************************
	int EasyCurl::set_timeout(unsigned long time) 
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;

		if (0 == time)
			return this->error_ = UBPLUS_CURL_TIMEOUT_NOT_VAILD;
						
		if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_TIMEOUT,time))
			return UBPLUS_CURL_OK;
		else {
			UB_LOG_WARNNING("[warn=curl] set option[timeout] failed");
			this->error_ = UBPLUS_CURL_SET_OPTION_FAILD;
			return UBPLUS_CURL_SET_OPTION_FAILD;	
		}

	}

	// ***********************************************************
	int EasyCurl::set_url(std::string url) 
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;

		if (url.length()<5)
			return this->error_ = UBPLUS_CURL_URL_NOT_VAILD;
						
		if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_URL,url.c_str()))
			return UBPLUS_CURL_OK;
		else {
			UB_LOG_WARNNING("[warn=curl] set option[url] failed");
			this->error_ = UBPLUS_CURL_URL_NOT_VAILD;
			return UBPLUS_CURL_URL_NOT_VAILD;	
		}
	}

	// ***********************************************************
	int EasyCurl::set_post_data(void* post_data) 
	{
		if (!this->curl_ || !this->is_good_) 
			return this->error_ = UBPLUS_CURL_HANDLE_NOT_VAILD;

		if (NULL == post_data)
			return this->error_ = UBPLUS_CURL_POST_NOT_VAILD;
						
		if (CURL_OK == curl_easy_setopt(this->curl_,CURLOPT_POSTFIELDS,post_data))
			return UBPLUS_CURL_OK;
		else {
			UB_LOG_WARNNING("[warn=curl] set option[post] failed");
			this->error_ = UBPLUS_CURL_POST_NOT_VAILD;
			return UBPLUS_CURL_POST_NOT_VAILD;	
		}
	}

	size_t EasyCurl::total_size_ = 0;
	bool EasyCurl::global_init_ = false;
	EasyCurl::curl_buffer EasyCurl::user_buffer;

} 	// end of namespace


 

分享到:
评论

相关推荐

    TI芯片DS90UB925Q-Q1

    根据提供的文件信息,我们可以深入探讨TI芯片DS90UB925Q-Q1的相关知识点。 ### TI芯片DS90UB925Q-Q1概述 #### 核心特性: - **双向控制接口**:DS90UB925Q-Q1具备双向控制接口,能够通过I2C兼容的串行控制总线实现...

    TI-DS90UB947N-Q1.pdf

    TI的DS90UB947N-Q1是一款专为汽车应用设计的FPD-Link串行器,符合AEC-Q100 Grade 2标准,可在-40°C到+105°C的温度范围内稳定工作。该器件主要用于将高清视频信号转换为适合长距离传输的串行数据流。 该串行器支持...

    ds90ub928q-q1中文.pdf

    DS90UB928Q-Q1 928QSQ FPD-link解串器芯片手册。 The DS90UB928Q-Q1 deserializer, in conjunction with a DS90UB925Q-Q1 or DS90UB927Q-Q1 serializer, provides a solution for distribution of digital video and...

    audacity-macosx-ub-2.1.1-screen-reader.dmg

    audacity-macosx-ub-2.1.1-screen-reader.dmg audacity-macosx-ub-2.1.1-screen-reader.dmg audacity-macosx-ub-2.1.1-screen-reader.dmg

    TI-DS90UB925Q-Q1.pdf

    TI公司的DS90UB925Q-Q1是一款专用于汽车行业的FPD-Link III串行器,设计用于处理高清视频、音频和控制数据的并行传输。该器件是FPD-Link串行器和解串器芯片组的一部分,与DS90UB926Q-Q1解串器配对使用,能够实现车载...

    TI-DS90UB928Q-Q1.pdf

    TI的DS90UB928Q-Q1是一款专用于汽车行业的FPD-Link解串器,用于在视频传输和控制系统中实现高质量的数字视频和音频解决方案。该解串器设计用于与DS90UB925Q-Q1或DS90UB927Q-Q1串行器配合工作,共同构建一套高效且低...

    TI-DS90UB904Q-Q1.pdf

    7. **ESD保护**:满足ISO 10605和IEC 61000-4-2 ESD标准,提供静电放电防护。 8. **均衡控制**:解串器输入具有均衡控制功能,以补偿长距离传输中信号的损耗,确保信号质量。 9. **封装与EMI/EMC管理**:DS90UB903...

    TI-DS90UB913Q-Q1.pdf

    TI的DS90UB913Q-Q1和DS90UB914Q-Q1是针对汽车电子领域的FPD-Link串行器和解串器芯片,它们主要用于在电子控制单元(ECU)中实现图像传感器与视频处理器之间的高效通信。这两个器件都支持FPD-Link III标准,这是一种...

    TI-DS90UB914A-Q1.pdf

    10. **ESD保护**:符合ISO 10605 和 IEC 61000-4-2 ESD 标准,增强系统抗静电能力。 11. **EMI/EMC缓解**:通过可编程扩展频谱 (SSCG) 和接收器交错输出减少电磁干扰。 **应用场景** 1. **汽车领域**:适用于环视...

    ub-0.2-src.zip_Semantic Model_semantic service_uB_语义web

    ub-0.2-src.zip 文件包含了关于“语义模型”和“语义服务”的核心组件,让我们一起深入探讨这个领域的关键知识点。 首先,我们关注的是“语义模型”(Semantic Model)。这是一个用于描述和组织信息的框架,使得...

    RT-N56UB1-newif3D2-512M_20190923.zip

    标题中的"RT-N56UB1-newif3D2-512M_20190923.zip"表明这是一个针对特定型号路由器的固件升级包。RT-N56U是华硕(ASUS)生产的一款双频千兆无线路由器,B1可能是其某个特定版本或变种。"newif3D2"可能是固件的新功能...

    RT-N56UB1-newifi2D1-256M_3.4.3.9-099.trx

    H大2019.11.24日版newifi2D1固件RT-N56UB1-newifi2D1-512M_3.4.3.9-099

    TI-DS90UB913A-Q1.pdf

    9. **ESD防护**:符合ISO 10605和IEC 61000-4-2静电放电标准,提高了设备的可靠性。 10. **小型化封装**:采用5mm x 5mm的小型WQFN封装,减小了安装空间。 该器件在汽车领域中的应用广泛,如环视系统(SVS)、前置...

    TI-DS90UB927Q-Q1.pdf

    **TI-DS90UB927Q-Q1 - FPD-Link串行器详解** TI的DS90UB927Q-Q1是一款专为汽车应用设计的高性能FPD-Link串行器,适用于高清视频和音频传输。它与DS90UB928Q-Q1或DS90UB926Q-Q1解串器配合使用,构建出完整的数字视频...

    TI-DS90UB949A-Q1.pdf

    【TI-DS90UB949A-Q1】是一款专为汽车应用设计的FPD-Link串行器,符合AEC-Q100标准的第二级温度等级,可在-40°C至105°C的工作温度范围内稳定工作。这款设备能够支持最高210MHz的TMDS时钟频率,允许传输3K、QXGA、2K...

    TI-DS90UB926Q-Q1.pdf

    在典型的应用场景中,如汽车导航显示屏、后座娱乐系统、驾驶辅助设备和车载百万像素摄像头系统,DS90UB926Q-Q1解串器是建立高效、可靠和高质量视频传输的关键组件。 总的来说,DS90UB926Q-Q1是一款高性能、高可靠性...

    Behringer_UB1204FX_Pro_Schematics

    根据提供的文件信息“Behringer_UB1204FX_Pro_Schematics”,我们可以深入探讨这一设备的关键组件及其工作原理。Behringer UB1204FX-Pro 是一款多功能调音台,它集成了多种音频处理功能,适用于现场演出、录音室等...

    ds90ub954-q1.pdf

    - 支持 CSI-2 数据速率可扩展性:每个数据通道支持 400Mbps/800Mbps/1.5Gbps/1.6Gbps。 - 支持四个虚拟通道和 ECC/CRC 生成,提高数据完整性。 5. **超低延迟:** - 提供极低的数据和控制路径延迟,确保实时性能...

    RT-N56UB1-newif3D2-512M_3.4.3.9-099.trx

    newifi3固件用一个路由器上传工具,名字一时想不起来,很简单,从adbyby下载文件,直接上传到路由器tmp目录下,然后进路由器点击右上角adbyby就可以打开了!

    百灵达UB1202-UB1002-UB802-UB502中文说明书-快速开始.zip

    百灵达UB系列调音台,包括UB1202、UB1002、UB802和UB502,是音频处理设备中的重要工具,尤其适用于小型演出、录音室、教育环境以及家庭音乐制作。这些调音台以其高性价比和易用性在业内广受欢迎。本压缩包提供了这四...

Global site tag (gtag.js) - Google Analytics