C++ curl handler class 예제
C언어 curl, C++ curl, libcurl, linux curl
C++ 클래스로 curl 을 쉽게 사용하게끔 구현하여 공유한다.
혹시 C에서 사용하고 싶다면 해당 소스코드의 클래스 내에 libcurl 함수를 제어하는 부분만 뽑아서 사용하길 바란다.
https://github.com/muabow/home/tree/main/library/cpp/api_curl
목차
1. 소스코드 : include/api_curl.h
2. 소스코드 : src/api_curl.cpp
3. 소스코드 : sample.cpp
4. 컴파일 및 실행 결과
1. 소스코드 : include/api_curl.h
#ifndef __API_CURL_H__
#define __API_CURL_H__
#include <stdarg.h>
#include <iostream>
#include <string>
#include <curl/curl.h>
using namespace std;
class CURL_Handler {
private :
bool is_debug_print;
bool is_header_print;
void print_debug_info(const char *_format, ...);
bool is_init;
bool is_set_url;
bool is_post;
CURL *curl_handle;
CURLcode curl_ret_code;
string read_buffer;
string url;
string data;
struct curl_slist *headers;
static size_t write_callback(void *_contents, size_t _size, size_t _nmemb, void *_userp);
public :
CURL_Handler(bool _is_debug_print = false);
~CURL_Handler(void);
void set_debug_print(void);
void set_header_print(void);
bool init(void);
void clear(void);
void set_header(string _header);
void set_header_content(string _content, string _info);
void set_post(string _data);
void set_url(string _url);
void set_server_info(string _target_url);
int request(void);
string response(void);
};
#endif
2. 소스코드 : src/api_curl.cpp
#include "api_curl.h"
CURL_Handler::CURL_Handler(bool _is_debug_print) {
this->is_debug_print = false;
this->is_header_print = false;
if( this->is_debug_print ) {
this->set_debug_print();
}
this->print_debug_info("CURL_Handler() create instance\n");
this->curl_handle = NULL;
this->clear();
return ;
}
CURL_Handler::~CURL_Handler(void) {
this->print_debug_info("CURL_Handler() instance destructed\n");
if( this->curl_handle != NULL ) {
curl_easy_cleanup(this->curl_handle);
this->curl_handle = NULL;
}
return ;
}
void CURL_Handler::print_debug_info(const char *_format, ...) {
if( !this->is_debug_print ) return ;
fprintf(stdout, "CURL_Handler::");
va_list arg;
va_start(arg, _format);
vprintf(_format, arg);
va_end(arg);
return ;
}
void CURL_Handler::set_debug_print(void) {
this->is_debug_print = true;
this->print_debug_info("set_debug_print() is set on\n");
return ;
}
void CURL_Handler::set_header_print(void) {
this->is_header_print = true;
this->print_debug_info("set_header_print() is set on\n");
return ;
}
size_t CURL_Handler::write_callback(void *_contents, size_t _size, size_t _nmemb, void *_userp) {
((string *)_userp)->append((char *)_contents, _size * _nmemb);
return _size * _nmemb;
}
bool CURL_Handler::init(void) {
if( (this->curl_handle = curl_easy_init()) > 0 ) {
this->print_debug_info("init() curl_easy_init() success\n");
this->is_init = true;
} else {
this->print_debug_info("init() curl_easy_init() failed\n");
this->is_init = false;
}
curl_easy_setopt(this->curl_handle, CURLOPT_WRITEFUNCTION, this->write_callback);
curl_easy_setopt(this->curl_handle, CURLOPT_WRITEDATA, &this->read_buffer);
curl_easy_setopt(this->curl_handle, CURLOPT_HTTPHEADER, this->headers);
if( (this->is_debug_print && this->is_header_print ) ) {
curl_easy_setopt(this->curl_handle, CURLOPT_VERBOSE, true);
}
return this->is_init;
}
void CURL_Handler::clear(void) {
this->headers = NULL;
this->read_buffer = "";
this->url = "";
this->data = "";
this->is_init = false;
this->is_set_url = false;
this->is_post = false;
if( this->curl_handle != NULL ) {
curl_easy_cleanup(this->curl_handle);
this->curl_handle = NULL;
}
this->headers = curl_slist_append(this->headers, "Content-Type: application/json");
this->print_debug_info("clear() clear handler\n");
return ;
}
void CURL_Handler::set_header(string _header) {
if( !this->is_init ) {
this->print_debug_info("set_header() init not ready\n");
return ;
}
this->headers = curl_slist_append(this->headers, _header.c_str());
this->print_debug_info("set_header() set [%s]\n", _header.c_str());
return ;
}
void CURL_Handler::set_url(string _url) {
if( !this->is_init ) {
this->print_debug_info("set_url() init not ready\n");
return ;
}
this->print_debug_info("set_url() set [%s]\n", _url.c_str());
this->is_set_url = true;
this->url = _url;
return ;
}
void CURL_Handler::set_post(string _data) {
if( !this->is_init ) {
this->print_debug_info("set_post() init not ready\n");
return ;
}
this->print_debug_info("set_post() set [%s]\n", _data.c_str());
this->is_post = true;
this->data = _data;
return ;
}
int CURL_Handler::request(void) {
if( !this->is_init ) {
this->print_debug_info("request() init not ready\n");
return -1;
}
if( !this->is_set_url ) {
this->print_debug_info("request() set not url\n");
return -1;
}
this->print_debug_info("request() request [%s] %s\n",
this->is_post ? "POST" : "GET", this->url.c_str());
if( this->is_post ) {
curl_easy_setopt(this->curl_handle, CURLOPT_POSTFIELDS, this->data.c_str());
curl_easy_setopt(this->curl_handle, CURLOPT_POSTFIELDSIZE, this->data.length());
}
curl_easy_setopt(this->curl_handle, CURLOPT_URL, this->url.c_str());
this->read_buffer = "";
this->curl_ret_code = curl_easy_perform(this->curl_handle);
if( this->curl_ret_code != CURLE_OK ) {
this->read_buffer = string(curl_easy_strerror(this->curl_ret_code));
}
return (int)this->curl_ret_code;
}
string CURL_Handler::response(void) {
return this->read_buffer;
}
void CURL_Handler::set_header_content(string _content, string _info) {
string content = _content;
content.append(": ");
content.append(_info);
this->set_header(content);
return ;
}
void CURL_Handler::set_server_info(string _target_url) {
this->set_url(_target_url);
return ;
}
3. 소스코드 : sample.cpp
sample.cpp 에서 위 api_curl library 를 간단하게 사용하는 예제를 보여준다.
set_server_info() 메서드에 curl 을 전송할 대상을 적는다.
여기선 공개된 Rest API reply server 를 사용하였다.
#include <stdio.h>
#include "api_curl.h"
int main(int _argc, char *_argv[]) {
CURL_Handler curl_handle;
curl_handle.set_debug_print();
curl_handle.init();
curl_handle.set_header_content("Content-Type", "application/json");
// POST 사용 시 string data를 인자로 사용
// curl_handle.set_post(str_curl_data);
curl_handle.set_server_info("https://httpbin.org/get");
curl_handle.request();
string response = curl_handle.response();
printf("response : [%s]\n", response.c_str());
curl_handle.clear();
return 0;
}
4. 컴파일 및 실행 결과
# api_curl 라이브러리 생성
muabow@muabow:~/dev/cpp_file/api_curl$ make clean ; make
rm -Rf ./src/api_curl.o libapi_curl.so
rm -Rf
g++ -fPIC -I./include -lcurl -c src/api_curl.cpp -o src/api_curl.o
# Create library
g++ -shared -o libapi_curl.so ./src/api_curl.o
muabow@muabow:~/dev/cpp_file/api_curl$
# 샘플 컴파일
muabow@muabow:~/dev/cpp_file/api_curl$ g++ -o sample sample.cpp -I./include -L. -lapi_curl -lcurl -std=c++11
# LD_LIBRARY_PATH 추가
muabow@muabow:~/dev/cpp_file/api_curl$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)
# 샘플 파일 실행
muabow@muabow:~/dev/cpp_file/api_curl$ ./sample
CURL_Handler::set_debug_print() is set on
CURL_Handler::init() curl_easy_init() success
CURL_Handler::set_header() set [Content-Type: application/json]
CURL_Handler::set_url() set [https://httpbin.org/get]
CURL_Handler::request() request [GET] https://httpbin.org/get
response : [{
"args": {},
"headers": {
"Accept": "*/*",
"Content-Type": "application/json",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-61e02c1a-3695de6450096c363303f52c"
},
"origin": "1.239.233.108",
"url": "https://httpbin.org/get"
}
]
CURL_Handler::clear() clear handler
CURL_Handler::CURL_Handler() instance destructed
muabow@muabow:~/dev/cpp_file/api_curl$
응답이 바르게 온 것을 확인할 수 있다.
혹시 라이브러리 빌드 및 컴파일 시 curl library 를 찾을 수 없다고 에러가 나면 아래처럼 libcurl 을 설치하자.
sudo apt-get install libcurl4-openssl-dev
많은 도움이 되길 바란다.
끝.
C++ curl handler class 예제, C언어 curl 구현
'IT > programming' 카테고리의 다른 글
[C/C++] select 를 활용한 non-block I/O, FD_SET, FD_ISSET (0) | 2022.01.14 |
---|---|
[C/C++] 전역 네임스페이스, 시스템 함수와 동일한 클래스 메서드 이름 사용 방법 (0) | 2022.01.14 |
[C/C++] C언어 Big-endian <-> Little-endian 상호 변환 (0) | 2022.01.13 |
[C/C++] sprintf indicator 및 format 관련 (0) | 2022.01.13 |
[C/C++] 리눅스 C언어 소켓 통신 서버, C++ socket server example (7) | 2022.01.11 |
댓글