diff --git a/lib/cppurl.hpp b/lib/cppurl.hpp index 1bd13ce..5c79323 100644 --- a/lib/cppurl.hpp +++ b/lib/cppurl.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,19 +11,28 @@ namespace marcelb { using namespace std; -static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp); +static size_t bodyCallback(void *contents, size_t size, size_t nmemb, void *body_ptr); +static size_t headerCallback(char* buffer, size_t size, size_t nitems, void* header_ptr); +enum http_version { DEFAULT, HTTP1_0, HTTP1_1, HTTP2, HTTP2TLS, HTTP2PK, HTTP3 = 30}; class Curl { + // input CURL *curl; CURLcode res; - string readBuffer; struct curl_slist *headers = NULL; string _useragent; long _timeout = 0; - bool _sslvalidate = true; + bool _sslverifyoff = false; + http_version _protocol_v = DEFAULT; public: + // output + CURLcode curlStatus; + long httpStatus; + map responseHeader; + string body; + /** * Postavi zaglavlje s ključem i vrijednošću * Novi pozivi ne brišu stara zaglavlja, ponovljena se prepišu @@ -50,7 +60,14 @@ class Curl { * Omogući/onemogući validaciju certifikata kod SSL veza */ - Curl& sslvalidate(const bool sslvalidate_); + Curl& sslverifyoff(); + + /** + * Postavi verziju HTTP protokola + * HTTP1_0 - HTTP1_1 - HTTP2 - HTTP2TLS - HTTP2PK - HTTP3 + */ + + Curl& httpv(const http_version protocol_v); /** * Izvršiv HTTP GET zahtjev diff --git a/src/cppurl.cpp b/src/cppurl.cpp index 5fad449..3609fc5 100644 --- a/src/cppurl.cpp +++ b/src/cppurl.cpp @@ -3,11 +3,26 @@ using namespace marcelb; -static size_t marcelb::WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { - ((std::string*)userp)->append((char*)contents, size * nmemb); +static size_t marcelb::bodyCallback(void *contents, size_t size, size_t nmemb, void *body_ptr) { + ((string*)body_ptr)->append((char*)contents, 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*)header_ptr)->insert(make_pair(key, value)); + } + + return nitems * size; +} + + Curl& marcelb::Curl::header(const string& key, const string& value) { headers = curl_slist_append(headers, string(key + ": " + value).c_str()); return *this; @@ -31,15 +46,20 @@ Curl& marcelb::Curl::timeout(const long timeout_) { return *this; } -Curl& marcelb::Curl::sslvalidate(const bool sslvalidate_) { - _sslvalidate = sslvalidate_; +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){ curl = curl_easy_init(); - readBuffer.clear(); + body.clear(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, req.c_str()); @@ -52,17 +72,27 @@ string marcelb::Curl::get(const string& req){ if (_timeout > 0) { curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS , _timeout); } - if (!_sslvalidate) { - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, _sslvalidate ? 1 : 0); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, _sslvalidate ? 1 : 0); + 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_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); - res = curl_easy_perform(curl); curl_easy_cleanup(curl); } - return readBuffer; + return body; } Curl& marcelb::Curl::clearheader() { diff --git a/test/test b/test/test index 7d6dbaf..1dc0ef3 100755 Binary files a/test/test and b/test/test differ diff --git a/test/test.cpp b/test/test.cpp index 06cc09e..c5e654c 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -11,10 +11,17 @@ using namespace marcelb; int main () { - // Curl rest; - // string header_value = "jebiga"; - // rest.header("API", header_value); - // cout << rest.get("https://reqres.in/api/users/2") << endl; + Curl rest; + string header_value = "jebiga"; + rest.header("API", header_value); + 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 thr; @@ -47,20 +54,21 @@ int main () { // t1.join(); // t2.join(); - vector> debx_responses; + // vector> debx_responses; - for (uint i=0; i<4; i++) { - debx_responses.push_back(async(launch::async, [&](){ - Curl rest; - // rest.timeout(6000); - rest.sslvalidate(false); - return rest.get("https://lab-it.ddns.net"); - })); - } + // 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; - } + // for (uint i=0; i<4; i++) { + // // cout << debx_responses[i].get() << endl << endl; + // debx_responses[i].get(); + // } } \ No newline at end of file