基於libcurl實現REST風格http/https的get和post

蝸牛201發表於2018-10-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

 1 /********************************************************
 2 Copyright (C),  2016-2018,
 3 FileName:        Get
 4 Author:            woniu201
 5 Email:             wangpengfei.201@163.com
 6 Created:           2018/10/15
 7 Description:    實現HTTP/HTTPS GET請求
 8 ********************************************************/
 9 #include "main.h"
10 
11 size_t WriteGetResp(void *buffer, size_t size, size_t nmemb, void *userp)
12 {
13     ((string*)userp)->append((char*)buffer, 0, size*nmemb);
14     return size*nmemb;
15 }
16 
17 /************************************
18 @ Brief:        GET請求
19 @ Author:        woniu201 
20 @ Created:        2018/10/15
21 @ Return:            
22 ************************************/
23 int HttpGet(char* url)
24 {
25     string respData;
26     CURL* curl;
27     CURLcode res;
28 
29     curl = curl_easy_init();
30     if (curl == NULL)
31     {
32         return 1;
33     }
34 
35     curl_easy_setopt(curl, CURLOPT_URL, url);
36     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteGetResp);
37     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respData);
38 
39 //      curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超時bug,如果裝置小於1000ms立即返回失敗
40 //      curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //設定超時時間
41 
42     bool bCA = FALSE;
43     if (!bCA)
44     {
45         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//設定為不驗證證照和HOST 
46         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
47     }
48     else
49     {
50         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 
51         curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 
52     }
53 
54     res = curl_easy_perform(curl);
55     if (res != CURLE_OK)
56     {
57         cout << curl_easy_strerror(res) << endl;
58     }
59 
60     curl_easy_cleanup(curl);
61 
62     cout << Utf8ToAscii(respData) << endl;
63     return 0;
64 }

實現HTTP/POST:

Post.cpp

 1 /********************************************************
 2 Copyright (C),  2016-2018,
 3 FileName:        Post
 4 Author:            woniu201
 5 Email:             wangpengfei.201@163.com
 6 Created:           2018/10/15
 7 Description:    實現HTTP/HTTPS POST請求
 8 ********************************************************/
 9 #include "main.h"
10 
11 size_t WritePostBodyResp(void *buffer, size_t size, size_t nmemb, void *userp)
12 {
13     ((string*)userp)->append((char*)buffer, 0, size*nmemb);
14     return size*nmemb;
15 }
16 
17 size_t WritePostHeaderResp(void *buffer, size_t size, size_t nmemb, void *userp)
18 {
19     ((string*)userp)->append((char*)buffer, 0, size*nmemb);
20     return size*nmemb;
21 }
22 
23 /************************************
24 @ Brief:        POST請求
25 @ Author:        woniu201 
26 @ Created:        2018/10/15
27 @ Return:            
28 ************************************/
29 int HttpPost(char* url, char* body)
30 {
31     string respBodyData;
32     string respHeadData;
33     CURL* curl;
34     CURLcode res;
35 
36     //設定頭
37     struct curl_slist *headers = NULL;
38     headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
39     
40     curl = curl_easy_init();
41     if (curl == NULL)
42     {
43         return 1;
44     }
45 
46     curl_easy_setopt(curl, CURLOPT_URL, url);
47     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
48     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
49 
50     curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WritePostHeaderResp);
51     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritePostBodyResp);
52     curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &respHeadData);
53     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respBodyData);
54 
55     //      curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超時bug,如果裝置小於1000ms立即返回失敗
56     //      curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //設定超時時間
57 
58     bool bCA = FALSE;
59     if (!bCA)
60     {
61         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//設定為不驗證證照和HOST 
62         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
63     }
64     else
65     {
66         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 
67         curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 
68     }
69 
70     res = curl_easy_perform(curl);
71     if (res != CURLE_OK)
72     {
73         cout << curl_easy_strerror(res) << endl;
74     }
75     curl_slist_free_all(headers);
76     curl_easy_cleanup(curl);
77 
78     cout << Utf8ToAscii(respHeadData) << endl;
79     cout << Utf8ToAscii(respBodyData) << endl;
80 
81     return 0;
82 }

其他程式碼:

utils.cpp
 1 /********************************************************
 2 Copyright (C),  2016-2018,
 3 FileName:        utils
 4 Author:            woniu201
 5 Email:             wangpengfei.201@163.com
 6 Created:           2018/10/15
 7 Description:    ASSIC--UTF8互轉
 8 ********************************************************/
 9 #include "main.h"
10 #include <string>
11 #include <Windows.h>
12 #include <wchar.h>
13 using namespace std;
14 
15 wstring    AsciiToUnicode(const string& str) {  
16     // 預算-緩衝區中寬位元組的長度    
17     int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);  
18     // 給指向緩衝區的指標變數分配記憶體    
19     wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);  
20     // 開始向緩衝區轉換位元組    
21     MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);  
22     wstring ret_str = pUnicode;  
23     free(pUnicode);  
24     return ret_str;  
25 }  
26 string UnicodeToAscii(const wstring& wstr) {  
27     // 預算-緩衝區中多位元組的長度    
28     int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);  
29     // 給指向緩衝區的指標變數分配記憶體    
30     char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);  
31     // 開始向緩衝區轉換位元組    
32     WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);  
33     string ret_str = pAssii;  
34     free(pAssii);  
35     return ret_str;  
36 }
37 
38 wstring Utf8ToUnicode(const string& str) {  
39     // 預算-緩衝區中寬位元組的長度    
40     int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);  
41     // 給指向緩衝區的指標變數分配記憶體    
42     wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);  
43     // 開始向緩衝區轉換位元組    
44     MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, pUnicode, unicodeLen);  
45     wstring ret_str = pUnicode;  
46     free(pUnicode);  
47     return ret_str;  
48 }  
49 string UnicodeToUtf8(const wstring& wstr) {  
50     // 預算-緩衝區中多位元組的長度    
51     int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);  
52     // 給指向緩衝區的指標變數分配記憶體    
53     char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);  
54     // 開始向緩衝區轉換位元組    
55     WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);  
56     string ret_str = pAssii;  
57     free(pAssii);  
58     return ret_str;  
59 }  
60 
61 /************************************
62 @ Brief:        ASSIC轉UTF8
63 @ Author:        woniu201 
64 @ Created:        2018/10/16
65 @ Return:            
66 ************************************/
67 string AsciiToUtf8(const string& str) {  
68     return UnicodeToUtf8(AsciiToUnicode(str));  
69 }  
70 
71 /************************************
72 @ Brief:        UTF8轉ASSIC
73 @ Author:        woniu201 
74 @ Created:        2018/10/16
75 @ Return:            
76 ************************************/
77 string Utf8ToAscii(const string& str) {  
78     return UnicodeToAscii(Utf8ToUnicode(str));  
79 }  
 1 #ifndef _MAIN_H
 2 #define _MAIN_H
 3 
 4 #include <iostream>
 5 #include <string>
 6 #include "include/curl.h"
 7 
 8 using namespace std;
 9 
10 
11 #pragma comment(lib, "ssleay32.lib")
12 #pragma comment(lib, "libcurl.lib")
13 
14 string AsciiToUtf8(const string& str);
15 string Utf8ToAscii(const string& str);
16 
17 int HttpGet(char* url);
18 int HttpPost(char* url, char* body);
19 int HttpDownload(char* url,  char* filePath);
20 #endif

對應libcurl庫和標頭檔案下載地址(支援HTTPS):點選下載

掃碼關注公眾號

專注分享C/C++,C++(11,14,17),STL,Java,Spring,mybatis,mysql,redis,分散式,高併發,設計模式,爬蟲,docker,shell程式設計等相關技術,還有高薪網際網路職位內推,在這裡一起探討,一起學習,一起進步,同時不定期分享視訊書籍資源,充分利用碎片化時間,讓我們的技術之路更加有樂趣。

相關文章