Compare commits
No commits in common. "dev" and "v0.1" have entirely different histories.
60
README.md
60
README.md
@ -1,59 +1,3 @@
|
|||||||
|
# cppurl
|
||||||
|
|
||||||
# Rest client library, using libcurl
|
C++ libcurl framework
|
||||||
|
|
||||||
A small framework for simple client-side REST API requests for C++. It uses libcurl. It got its name from a play on the words curl and cpp.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Object oriented
|
|
||||||
- Adjustable headers
|
|
||||||
- Configurable user agent
|
|
||||||
- Adjustable timeout
|
|
||||||
- Native C++ containers: map, string
|
|
||||||
- QA object
|
|
||||||
- Curl and HTTP code status
|
|
||||||
- It is possible to turn off certificate validation
|
|
||||||
- A configurable version of the HTTP protocol
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Just download the latest release and unzip it into your project. You can turn it on with:
|
|
||||||
|
|
||||||
```
|
|
||||||
#include "cppurl/lib/cppurl.hpp"
|
|
||||||
using namespace marcelb;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```c++
|
|
||||||
// init, and sets
|
|
||||||
Curl rest;
|
|
||||||
string header_value = "3849f438uf9uedu8ejweoijwejd09230";
|
|
||||||
rest.header("API", header_value).timeout(700)
|
|
||||||
.httpv(HTTP2).sslverifyoff();
|
|
||||||
// execute and print
|
|
||||||
cout << rest.get("https://reqres.in/api/users/2") << endl <<
|
|
||||||
"Curl status " << rest.curlStatus << endl <<
|
|
||||||
"HTTP status " << rest.httpStatus << endl;
|
|
||||||
|
|
||||||
for (auto header : rest.responseHeader) {
|
|
||||||
cout << header.first << " " << header.second << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
## License
|
|
||||||
|
|
||||||
[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/)
|
|
||||||
|
|
||||||
|
|
||||||
## Support & Feedback
|
|
||||||
|
|
||||||
For support and any feedback, contact the address: marcelb96@yahoo.com.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are always welcome!
|
|
||||||
|
|
||||||
Feel free to fork and start working with or without a later pull request. Or contact for suggest and request an option.
|
|
||||||
|
|
@ -3,102 +3,53 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/**
|
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp);
|
||||||
* Callback function for parsing the HTTP body
|
|
||||||
*/
|
|
||||||
static size_t bodyCallback(void *contents, size_t size, size_t nmemb, void *body_ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback function for parsing HTTP headers
|
|
||||||
*/
|
|
||||||
static size_t headerCallback(char* buffer, size_t size, size_t nitems, void* header_ptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP supported protocols
|
|
||||||
*/
|
|
||||||
enum http_version { DEFAULT, HTTP1_0, HTTP1_1, HTTP2, HTTP2TLS, HTTP2PK, HTTP3 = 30};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for curl request and response
|
|
||||||
*/
|
|
||||||
class Curl {
|
class Curl {
|
||||||
// input
|
|
||||||
|
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
|
string readBuffer;
|
||||||
struct curl_slist *headers = NULL;
|
struct curl_slist *headers = NULL;
|
||||||
string _useragent;
|
string _useragent;
|
||||||
long _timeout = 0;
|
|
||||||
bool _sslverifyoff = false;
|
|
||||||
http_version _protocol_v = DEFAULT;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// output
|
|
||||||
|
|
||||||
// Curl code response status
|
|
||||||
CURLcode curlStatus;
|
|
||||||
// HTTP code response status
|
|
||||||
long httpStatus;
|
|
||||||
// HTTP response headers
|
|
||||||
map<string, string> responseHeader;
|
|
||||||
// HTTP body
|
|
||||||
string body;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set header with key and value
|
* Postavi zaglavlje s ključem i vrijednošću
|
||||||
* New calls do not delete old headers, repeated ones are overwritten
|
* Novi pozivi ne brišu stara zaglavlja, ponovljena se prepišu
|
||||||
*/
|
*/
|
||||||
Curl& header(const string& key, const string& value);
|
Curl& header(const string& key, const string& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set headers from folder
|
* Postavi zaglavlja iz mape
|
||||||
* The redial will overwrite those headers that exist
|
* Ponovan poziv prepisat će ona zaglavlja koja postoje
|
||||||
*/
|
*/
|
||||||
Curl& header(const map<string, string> &_headers);
|
Curl& header(const map<string, string> &_headers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set in User-Agent header
|
* Postavi u zaglavlje User-Agent
|
||||||
*/
|
*/
|
||||||
Curl& useragent(const string& useragent_);
|
Curl& useragent(const string& useragent_);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set request timeout
|
* Izvršiv HTTP GET zahtjev
|
||||||
*/
|
* Vraća string HTTP tjela
|
||||||
Curl& timeout(const long _timeout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable certificate validation for SSL connections
|
|
||||||
*/
|
|
||||||
Curl& sslverifyoff();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set HTTP protocol version
|
|
||||||
* HTTP1_0 - HTTP1_1 - HTTP2 - HTTP2TLS - HTTP2PK - HTTP3
|
|
||||||
*/
|
|
||||||
Curl& httpv(const http_version protocol_v);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executable HTTP GET request
|
|
||||||
* Returns the HTTP body as string
|
|
||||||
*/
|
*/
|
||||||
string get(const string& req);
|
string get(const string& req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear saved headers
|
* Obriši spremljeno zaglavlje
|
||||||
*/
|
*/
|
||||||
Curl& clearheader();
|
Curl& clearheader();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the current User-Agent
|
* Obrši trenutnog User-Agent -a
|
||||||
*/
|
*/
|
||||||
Curl& clearuseragent();
|
Curl& clearuseragent();
|
||||||
|
|
||||||
|
@ -3,26 +3,11 @@
|
|||||||
|
|
||||||
using namespace marcelb;
|
using namespace marcelb;
|
||||||
|
|
||||||
static size_t marcelb::bodyCallback(void *contents, size_t size, size_t nmemb, void *body_ptr) {
|
static size_t marcelb::WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
|
||||||
((string*)body_ptr)->append((char*)contents, size * nmemb);
|
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||||
return size * nmemb;
|
return size * nmemb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t marcelb::headerCallback(char* buffer, size_t size, size_t nitems, void* header_ptr) {
|
|
||||||
string header_member = string(buffer);
|
|
||||||
string key, value;
|
|
||||||
|
|
||||||
auto doublepoint = header_member.find(": ");
|
|
||||||
if (doublepoint < header_member.length()){
|
|
||||||
key = header_member.substr(0, doublepoint);
|
|
||||||
value = header_member.substr(doublepoint+2, header_member.length()-2);
|
|
||||||
((map<string, string>*)header_ptr)->insert(make_pair(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
return nitems * size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Curl& marcelb::Curl::header(const string& key, const string& value) {
|
Curl& marcelb::Curl::header(const string& key, const string& value) {
|
||||||
headers = curl_slist_append(headers, string(key + ": " + value).c_str());
|
headers = curl_slist_append(headers, string(key + ": " + value).c_str());
|
||||||
return *this;
|
return *this;
|
||||||
@ -41,25 +26,10 @@ Curl& marcelb::Curl::useragent(const string& useragent_) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl& marcelb::Curl::timeout(const long timeout_) {
|
|
||||||
_timeout = timeout_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl& marcelb::Curl::sslverifyoff() {
|
|
||||||
_sslverifyoff = true;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl& marcelb::Curl::httpv(const http_version protocol_v) {
|
|
||||||
_protocol_v = protocol_v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
string marcelb::Curl::get(const string& req){
|
string marcelb::Curl::get(const string& req){
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
|
|
||||||
body.clear();
|
readBuffer.clear();
|
||||||
|
|
||||||
if(curl) {
|
if(curl) {
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, req.c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, req.c_str());
|
||||||
@ -69,30 +39,13 @@ string marcelb::Curl::get(const string& req){
|
|||||||
if (!_useragent.empty()) {
|
if (!_useragent.empty()) {
|
||||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, _useragent.c_str());
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, _useragent.c_str());
|
||||||
}
|
}
|
||||||
if (_timeout > 0) {
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||||
curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS , _timeout);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||||
}
|
res = curl_easy_perform(curl);
|
||||||
if (_sslverifyoff) {
|
|
||||||
curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, _sslverifyoff ? 0 : 1);
|
|
||||||
curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, _sslverifyoff ? 0 : 1);
|
|
||||||
}
|
|
||||||
if (_protocol_v > DEFAULT) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)_protocol_v);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, bodyCallback);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, headerCallback);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeader);
|
|
||||||
|
|
||||||
curlStatus = curl_easy_perform(curl);
|
|
||||||
if(curlStatus == CURLE_OK) {
|
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpStatus);
|
|
||||||
}
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return body;
|
return readBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl& marcelb::Curl::clearheader() {
|
Curl& marcelb::Curl::clearheader() {
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
|
||||||
#include <thread>
|
|
||||||
#include <future>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../lib/cppurl.hpp"
|
#include "../lib/cppurl.hpp"
|
||||||
|
|
||||||
@ -12,64 +8,10 @@ using namespace marcelb;
|
|||||||
int main () {
|
int main () {
|
||||||
|
|
||||||
Curl rest;
|
Curl rest;
|
||||||
string header_value = "3849f438uf9uedu8ejweoijwejd09230";
|
|
||||||
rest.header("API", header_value).timeout(700)
|
|
||||||
.httpv(HTTP2).sslverifyoff();
|
|
||||||
cout << rest.get("https://reqres.in/api/users/2") << endl <<
|
|
||||||
"Curl status " << rest.curlStatus << endl <<
|
|
||||||
"HTTP status " << rest.httpStatus << endl;
|
|
||||||
|
|
||||||
for (auto header : rest.responseHeader) {
|
rest.header("Baba", "Janja").useragent("Dinio api client v1.1.0 - bitelex@bitelex.co");
|
||||||
cout << header.first << " " << header.second << endl;
|
cout << rest.get("http://localhost:5000/?param1=tvt¶m2=2023") << endl;
|
||||||
}
|
// cout << rest.request("https://reqres.in/api/users/2") << endl;
|
||||||
|
|
||||||
|
|
||||||
// vector<thread> thr;
|
|
||||||
|
|
||||||
// for (uint i=0; i<4; i++) {
|
|
||||||
// thr.push_back(thread([](){
|
|
||||||
// Curl rest;
|
|
||||||
// string header_value = "jebiga";
|
|
||||||
// rest.header("API", header_value);
|
|
||||||
// cout << rest.get("https://reqres.in/api/users/2") << endl;
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (uint i=0; i<thr.size(); i++) {
|
|
||||||
// thr[i].join();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// thread t1([](){
|
|
||||||
// Curl rest;
|
|
||||||
// cout << rest.get("https://reqres.in/api/users/2") << endl;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // t1.join();
|
|
||||||
|
|
||||||
// thread t2([](){
|
|
||||||
// Curl rest;
|
|
||||||
// cout << rest.get("https://reqres.in/api/users/2") << endl;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// t1.join();
|
|
||||||
// t2.join();
|
|
||||||
|
|
||||||
// vector<future<string>> debx_responses;
|
|
||||||
|
|
||||||
// for (uint i=0; i<4; i++) {
|
|
||||||
// debx_responses.push_back(async(launch::async, [&](){
|
|
||||||
// Curl rest;
|
|
||||||
// // rest.timeout(6000);
|
|
||||||
// rest.sslverifyoff().httpv(HTTP2);
|
|
||||||
// return rest.get("https://lab-it.ddns.net");
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (uint i=0; i<4; i++) {
|
|
||||||
// // cout << debx_responses[i].get() << endl << endl;
|
|
||||||
// debx_responses[i].get();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user