基於libcurl實現REST風格http/https的get和post
阿新 • • 發佈:2018-11-16
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: [email protected] 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: [email protected] 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: [email protected]
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++開發交流
掃更多技術文章掃碼關注微信公眾號