zoukankan      html  css  js  c++  java
  • 基于libcurl实现REST风格http/https的get和post

    c/c++开发中经常要用到http/https协议,直接使用socket工作量很大,要是使用socket实现https,那更不可思议,开源的c/c++的http客户端框架,libcurl是首选,而且也相当成熟稳定,最近C++项目中用到https请求,就做下研究。

    libcurl简介(来源官网)

    libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。官网地址:https://curl.haxx.se/libcurl/

    实现HTTP/GET:

    Get.cpp

    /********************************************************
    Copyright (C),  2016-2018,
    FileName:		Get
    Author:        	woniu201
    Email:         	wangpengfei.201@163.com
    Created:       	2018/10/15
    Description:	实现HTTP/HTTPS GET请求
    ********************************************************/
    #include "main.h"
    
    size_t WriteGetResp(void *buffer, size_t size, size_t nmemb, void *userp)
    {
    	((string*)userp)->append((char*)buffer, 0, size*nmemb);
    	return size*nmemb;
    }
    
    /************************************
    @ Brief:		GET请求
    @ Author:		woniu201 
    @ Created:		2018/10/15
    @ Return:            
    ************************************/
    int HttpGet(char* url)
    {
    	string respData;
    	CURL* curl;
    	CURLcode res;
    
    	curl = curl_easy_init();
    	if (curl == NULL)
    	{
    		return 1;
    	}
    
    	curl_easy_setopt(curl, CURLOPT_URL, url);
    	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteGetResp);
    	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respData);
    
    //  	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超时bug,如果设备小于1000ms立即返回失败
    //  	curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //设置超时时间
    
    	bool bCA = FALSE;
    	if (!bCA)
    	{
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//设定为不验证证书和HOST 
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
    	}
    	else
    	{
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 
    		curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 
    	}
    
    	res = curl_easy_perform(curl);
    	if (res != CURLE_OK)
    	{
    		cout << curl_easy_strerror(res) << endl;
    	}
    
    	curl_easy_cleanup(curl);
    
    	cout << Utf8ToAscii(respData) << endl;
    	return 0;
    }

    实现HTTP/POST:

    Post.cpp

    /********************************************************
    Copyright (C),  2016-2018,
    FileName:		Post
    Author:        	woniu201
    Email:         	wangpengfei.201@163.com
    Created:       	2018/10/15
    Description:	实现HTTP/HTTPS POST请求
    ********************************************************/
    #include "main.h"
    
    size_t WritePostBodyResp(void *buffer, size_t size, size_t nmemb, void *userp)
    {
    	((string*)userp)->append((char*)buffer, 0, size*nmemb);
    	return size*nmemb;
    }
    
    size_t WritePostHeaderResp(void *buffer, size_t size, size_t nmemb, void *userp)
    {
    	((string*)userp)->append((char*)buffer, 0, size*nmemb);
    	return size*nmemb;
    }
    
    /************************************
    @ Brief:		POST请求
    @ Author:		woniu201 
    @ Created:		2018/10/15
    @ Return:            
    ************************************/
    int HttpPost(char* url, char* body)
    {
    	string respBodyData;
    	string respHeadData;
    	CURL* curl;
    	CURLcode res;
    
    	//设置头
    	struct curl_slist *headers = NULL;
    	headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
    	
    	curl = curl_easy_init();
    	if (curl == NULL)
    	{
    		return 1;
    	}
    
    	curl_easy_setopt(curl, CURLOPT_URL, url);
    	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
    	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    
    	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WritePostHeaderResp);
    	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritePostBodyResp);
    	curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &respHeadData);
    	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respBodyData);
    
    	//  	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超时bug,如果设备小于1000ms立即返回失败
    	//  	curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //设置超时时间
    
    	bool bCA = FALSE;
    	if (!bCA)
    	{
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//设定为不验证证书和HOST 
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
    	}
    	else
    	{
    		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 
    		curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 
    	}
    
    	res = curl_easy_perform(curl);
    	if (res != CURLE_OK)
    	{
    		cout << curl_easy_strerror(res) << endl;
    	}
    	curl_slist_free_all(headers);
    	curl_easy_cleanup(curl);
    
    	cout << Utf8ToAscii(respHeadData) << endl;
    	cout << Utf8ToAscii(respBodyData) << endl;
    
    	return 0;
    }

    其他代码:

    Utils.cpp

    /********************************************************
    Copyright (C),  2016-2018,
    FileName:		utils
    Author:        	woniu201
    Email:         	wangpengfei.201@163.com
    Created:       	2018/10/15
    Description:	ASSIC--UTF8互转
    ********************************************************/
    #include "main.h"
    #include <string>
    #include <Windows.h>
    #include <wchar.h>
    using namespace std;
    
    wstring	AsciiToUnicode(const string& str) {  
    	// 预算-缓冲区中宽字节的长度    
    	int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);  
    	// 给指向缓冲区的指针变量分配内存    
    	wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);  
    	// 开始向缓冲区转换字节    
    	MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);  
    	wstring ret_str = pUnicode;  
    	free(pUnicode);  
    	return ret_str;  
    }  
    string UnicodeToAscii(const wstring& wstr) {  
    	// 预算-缓冲区中多字节的长度    
    	int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);  
    	// 给指向缓冲区的指针变量分配内存    
    	char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);  
    	// 开始向缓冲区转换字节    
    	WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);  
    	string ret_str = pAssii;  
    	free(pAssii);  
    	return ret_str;  
    }
    
    wstring Utf8ToUnicode(const string& str) {  
    	// 预算-缓冲区中宽字节的长度    
    	int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);  
    	// 给指向缓冲区的指针变量分配内存    
    	wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);  
    	// 开始向缓冲区转换字节    
    	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, pUnicode, unicodeLen);  
    	wstring ret_str = pUnicode;  
    	free(pUnicode);  
    	return ret_str;  
    }  
    string UnicodeToUtf8(const wstring& wstr) {  
    	// 预算-缓冲区中多字节的长度    
    	int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);  
    	// 给指向缓冲区的指针变量分配内存    
    	char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);  
    	// 开始向缓冲区转换字节    
    	WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);  
    	string ret_str = pAssii;  
    	free(pAssii);  
    	return ret_str;  
    }  
    
    /************************************
    @ Brief:		ASSIC转UTF8
    @ Author:		woniu201 
    @ Created:		2018/10/16
    @ Return:            
    ************************************/
    string AsciiToUtf8(const string& str) {  
    	return UnicodeToUtf8(AsciiToUnicode(str));  
    }  
    
    /************************************
    @ Brief:		UTF8转ASSIC
    @ Author:		woniu201 
    @ Created:		2018/10/16
    @ Return:            
    ************************************/
    string Utf8ToAscii(const string& str) {  
    	return UnicodeToAscii(Utf8ToUnicode(str));  
    }  

     main.h

    #ifndef _MAIN_H
    #define _MAIN_H
    
    #include <iostream>
    #include <string>
    #include "include/curl.h"
    
    using namespace std;
    
    
    #pragma comment(lib, "ssleay32.lib")
    #pragma comment(lib, "libcurl.lib")
    
    string AsciiToUtf8(const string& str);
    string Utf8ToAscii(const string& str);
    
    int HttpGet(char* url);
    int HttpPost(char* url, char* body);
    int HttpDownload(char* url,  char* filePath);
    #endif

    对应libcurl库和头文件下载地址(支持HTTPS):点击下载

    欢迎加群交流:C/C++开发交流

                                                            

  • 相关阅读:
    HADOOP_HIVE安装和配置
    LInux__增加交换空间(SWAP)的大小
    ORACLE__Linux下Oracle数据库的卸载、删除
    HADOOP__HBASE集群安装(自带ZOOKEEPER)
    HADOOP__PIG安装与配置
    HADOOP__HADOOP基础安装和配置
    PYTHON__Thread达到上限的解决方案(设置线程上限)
    MYSQL__MYSQL的一些基础设置
    Android Studio Unable to access Android SDK addon list Mac
    dmg 文件打不开,双击没反应
  • 原文地址:https://www.cnblogs.com/woniu201/p/11694574.html
Copyright © 2011-2022 走看看