Compare commits

..

5 Commits
v0.2 ... dev

Author SHA1 Message Date
marcelb
beaddd239b Comments, README 2024-01-08 18:47:06 +01:00
marcelb
dc26ed563f Enable chose http version, get response headers, http and curl status code 2023-11-30 19:47:26 +01:00
marcelb
16440a9c71 Add option to disable SSL validate 2023-11-29 22:31:46 +01:00
marcelb
58fe5f1673 Add option to disable SSL validate 2023-11-29 22:30:47 +01:00
marcelb
d7728c5b23 Return missing 2023-11-29 22:08:13 +01:00
5 changed files with 184 additions and 37 deletions

View File

@ -1,3 +1,59 @@
# cppurl
C++ libcurl framework # Rest client library, using libcurl
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.

View File

@ -3,60 +3,102 @@
#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; 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;
/** /**
* Postavi zaglavlje s ključem i vrijednošću * Set header with key and value
* Novi pozivi ne brišu stara zaglavlja, ponovljena se prepišu * New calls do not delete old headers, repeated ones are overwritten
*/ */
Curl& header(const string& key, const string& value); Curl& header(const string& key, const string& value);
/** /**
* Postavi zaglavlja iz mape * Set headers from folder
* Ponovan poziv prepisat će ona zaglavlja koja postoje * The redial will overwrite those headers that exist
*/ */
Curl& header(const map<string, string> &_headers); Curl& header(const map<string, string> &_headers);
/** /**
* Postavi u zaglavlje User-Agent * Set in User-Agent header
*/ */
Curl& useragent(const string& useragent_); Curl& useragent(const string& useragent_);
/** /**
* Postavi vrijeme isteka zahtjeva * Set request timeout
*/ */
Curl& timeout(const long _timeout); Curl& timeout(const long _timeout);
/** /**
* Izvršiv HTTP GET zahtjev * Disable certificate validation for SSL connections
* Vraća string HTTP tjela */
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);
/** /**
* Obriši spremljeno zaglavlje * Clear saved headers
*/ */
Curl& clearheader(); Curl& clearheader();
/** /**
* Obrši trenutnog User-Agent -a * Clear the current User-Agent
*/ */
Curl& clearuseragent(); Curl& clearuseragent();

View File

@ -3,11 +3,26 @@
using namespace marcelb; using namespace marcelb;
static size_t marcelb::WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { static size_t marcelb::bodyCallback(void *contents, size_t size, size_t nmemb, void *body_ptr) {
((std::string*)userp)->append((char*)contents, size * nmemb); ((string*)body_ptr)->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;
@ -28,13 +43,23 @@ Curl& marcelb::Curl::useragent(const string& useragent_) {
Curl& marcelb::Curl::timeout(const long timeout_) { Curl& marcelb::Curl::timeout(const long timeout_) {
_timeout = 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();
readBuffer.clear(); body.clear();
if(curl) { if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, req.c_str()); curl_easy_setopt(curl, CURLOPT_URL, req.c_str());
@ -47,13 +72,27 @@ string marcelb::Curl::get(const string& req){
if (_timeout > 0) { if (_timeout > 0) {
curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS , _timeout); curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS , _timeout);
} }
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); if (_sslverifyoff) {
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, _sslverifyoff ? 0 : 1);
res = curl_easy_perform(curl); 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 readBuffer; return body;
} }
Curl& marcelb::Curl::clearheader() { Curl& marcelb::Curl::clearheader() {

BIN
test/test

Binary file not shown.

View File

@ -11,10 +11,18 @@ using namespace marcelb;
int main () { int main () {
// Curl rest; Curl rest;
// string header_value = "jebiga"; string header_value = "3849f438uf9uedu8ejweoijwejd09230";
// rest.header("API", header_value); rest.header("API", header_value).timeout(700)
// cout << rest.get("https://reqres.in/api/users/2") << endl; .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) {
cout << header.first << " " << header.second << endl;
}
// vector<thread> thr; // vector<thread> thr;
@ -47,19 +55,21 @@ int main () {
// t1.join(); // t1.join();
// t2.join(); // t2.join();
vector<future<string>> debx_responses; // vector<future<string>> debx_responses;
for (uint i=0; i<4; i++) { // for (uint i=0; i<4; i++) {
debx_responses.push_back(async(launch::async, [&](){ // debx_responses.push_back(async(launch::async, [&](){
Curl rest; // Curl rest;
rest.timeout(600); // // rest.timeout(6000);
return rest.get("https://reqres.iin/api/users/2"); // rest.sslverifyoff().httpv(HTTP2);
})); // return rest.get("https://lab-it.ddns.net");
} // }));
// }
for (uint i=0; i<4; i++) { // for (uint i=0; i<4; i++) {
cout << debx_responses[i].get() << endl << endl; // // cout << debx_responses[i].get() << endl << endl;
} // debx_responses[i].get();
// }
} }