From 89249f1297fb4ad115914885fbf2ff61e5a4e79a Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 18 Nov 2022 16:38:03 +0100 Subject: [PATCH] add Http::fetch(...) methods --- winixd/utils/http.cpp | 167 ++++++++++++++++++++++++++++-------------- winixd/utils/http.h | 22 +++++- 2 files changed, 132 insertions(+), 57 deletions(-) diff --git a/winixd/utils/http.cpp b/winixd/utils/http.cpp index 57b951f..c0652de 100644 --- a/winixd/utils/http.cpp +++ b/winixd/utils/http.cpp @@ -73,7 +73,6 @@ Http & Http::begin() debug_info = nullptr; follow_location = true; verify_ssl_cert = true; - use_post_method = true; return *this; } @@ -226,15 +225,55 @@ Http & Http::add_bearer_token(const std::wstring & token) } -bool Http::get(const wchar_t * url, std::wstring & out, bool clear_str) +bool Http::fetch(Method method, const wchar_t * url, const std::string * in, pt::WTextStream & out, bool clear_stream) { std::string url_ascii; pt::TextStream out_stream; + if( clear_stream ) + { + out.clear(); + } + pt::wide_to_utf8(url, url_ascii); - bool status = fetch_internal(url_ascii.c_str(), nullptr, out_stream); - pt::utf8_to_wide(out_stream, out, clear_str); + bool status = fetch_internal(method, url_ascii.c_str(), in, out_stream); + out << out_stream; + + return status; +} + + +bool Http::fetch(Method method, const std::wstring & url, const std::string * in, pt::WTextStream & out, bool clear_stream) +{ + return fetch(method, url.c_str(), in, out, clear_stream); +} + + +bool Http::fetch(Method method, const wchar_t * url, pt::WTextStream * in, pt::WTextStream & out, bool clear_stream) +{ + if( in ) + { + std::string in_ascii; + in->to_str(in_ascii); + + return fetch(method, url, &in_ascii, out, clear_stream); + } + else + { + const std::string * in = nullptr; + return fetch(method, url, in, out, clear_stream); + } +} + + + +bool Http::get(const wchar_t * url, std::wstring & out, bool clear_str) +{ + const std::string * in = nullptr; + pt::WTextStream out_stream; + bool status = fetch(Method::method_get, url, in, out_stream, false); + out_stream.to_str(out, clear_str); return status; } @@ -256,14 +295,8 @@ bool Http::get(const pt::WTextStream & url, std::wstring & out, bool clear_str) bool Http::get(const wchar_t * url, pt::WTextStream & out, bool clear_stream) { - std::string url_ascii; - pt::TextStream out_stream; - - pt::wide_to_utf8(url, url_ascii); - bool status = fetch_internal(url_ascii.c_str(), nullptr, out_stream); - out << out_stream; - - return status; + const std::string * in = nullptr; + return fetch(Method::method_get, url, in, out, clear_stream); } @@ -282,68 +315,39 @@ bool Http::get(const pt::WTextStream & url, pt::WTextStream & out, bool clear_st } -bool Http::post_put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream) -{ - std::string url_ascii; - pt::TextStream out_stream; - - if( clear_stream ) - { - out.clear(); - } - - pt::wide_to_utf8(url, url_ascii); - - bool status = fetch_internal(url_ascii.c_str(), &in, out_stream); - out << out_stream; - - return status; -} - - bool Http::post(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream) { - use_post_method = true; - return post_put(url, in, out, clear_stream); + return fetch(Method::method_post, url, &in, out, clear_stream); } bool Http::post(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream) { - use_post_method = true; - return post_put(url.c_str(), in, out, clear_stream); + return fetch(Method::method_post, url, &in, out, clear_stream); } bool Http::post(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream) { - std::string in_ascii; - in.to_str(in_ascii); - use_post_method = true; - return post_put(url, in_ascii, out, clear_stream); + return fetch(Method::method_post, url, &in, out, clear_stream); } bool Http::put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream) { - use_post_method = false; - return post_put(url, in, out, clear_stream); + return fetch(Method::method_put, url, &in, out, clear_stream); } bool Http::put(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream) { - use_post_method = false; - return post_put(url.c_str(), in, out, clear_stream); + return fetch(Method::method_put, url, &in, out, clear_stream); } bool Http::put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream) { - std::string in_ascii; - in.to_str(in_ascii); - use_post_method = false; - return post_put(url, in_ascii, out, clear_stream); + return fetch(Method::method_put, url, &in, out, clear_stream); } @@ -492,7 +496,7 @@ void Http::use_debug_mode(bool debug, pt::Space * debug_info) // in can be pointer to const char * -bool Http::fetch_internal(const char * url, const std::string * in, pt::TextStream & out) +bool Http::fetch_internal(Method method, const char * url, const std::string * in, pt::TextStream & out) { bool status = false; initialize_curl_if_needed(); @@ -514,18 +518,14 @@ bool Http::fetch_internal(const char * url, const std::string * in, pt::TextStre read_function_input = in; // can be null read_function_index = 0; + put_method(method); + if( read_function_input ) { curl_easy_setopt(curl, CURLOPT_READFUNCTION, fetch_read_function); curl_easy_setopt(curl, CURLOPT_READDATA, this); curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, fetch_seek_function); curl_easy_setopt(curl, CURLOPT_SEEKDATA, this); - - if( use_post_method ) - curl_easy_setopt(curl, CURLOPT_POST, 1); - else - curl_easy_setopt(curl, CURLOPT_PUT, 1); - curl_off_t size = read_function_input->size(); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, size); } @@ -597,6 +597,38 @@ bool Http::fetch_internal(const char * url, const std::string * in, pt::TextStre } +void Http::put_method(Method & method) +{ + // we don't put 'get' here + + switch(method) + { + case Method::method_post: + curl_easy_setopt(curl, CURLOPT_POST, 1); + break; + + case Method::method_put: + curl_easy_setopt(curl, CURLOPT_PUT, 1); + break; + + case Method::method_patch: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH"); + break; + + case Method::method_delete: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + break; + + case Method::method_options: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS"); + break; + + default: + break; + } +} + + size_t Http::fetch_read_function(char * ptr, size_t size, size_t nmemb, void * userdata) { size_t len = 0; @@ -950,6 +982,33 @@ int Http::debug_function(CURL * handle, curl_infotype type, char * data, size_t } +const wchar_t * Http::method_to_str(Http::Method method) +{ + switch(method) + { + case method_get: + return L"GET"; + + case method_post: + return L"POST"; + + case method_put: + return L"PUT"; + + case method_patch: + return L"PATCH"; + + case method_delete: + return L"DELETE"; + + case method_options: + return L"OPTIONS"; + + default: + return L""; + } +} + } diff --git a/winixd/utils/http.h b/winixd/utils/http.h index 99b5817..c0e4466 100644 --- a/winixd/utils/http.h +++ b/winixd/utils/http.h @@ -54,6 +54,14 @@ public: static const long HTTP_STATUS_301_Moved_Permanently = 301; static const long HTTP_STATUS_302_Found = 302; + enum Method { + method_get, + method_post, + method_put, + method_patch, + method_delete, + method_options, + }; Http(); ~Http(); @@ -157,6 +165,14 @@ public: */ void verify_ssl(bool verify); + /* + * in can be a null pointer + * in such a case a body payload is not sent + */ + bool fetch(Method method, const wchar_t * url, const std::string * in, pt::WTextStream & out, bool clear_stream = true); + bool fetch(Method method, const std::wstring & url, const std::string * in, pt::WTextStream & out, bool clear_stream = true); + bool fetch(Method method, const wchar_t * url, pt::WTextStream * in, pt::WTextStream & out, bool clear_stream = true); + bool get(const wchar_t * url, std::wstring & out, bool clear_str = true); bool get(const std::wstring & url, std::wstring & out, bool clear_str = true); bool get(const pt::WTextStream & url, std::wstring & out, bool clear_str = true); @@ -178,6 +194,7 @@ public: */ long get_status(); + static const wchar_t * method_to_str(Method method); private: @@ -200,7 +217,6 @@ private: pt::Space * debug_info; bool follow_location; bool verify_ssl_cert; - bool use_post_method; /* if false then use put method - used only when calling post() or put() methods */ std::wstring temp_header; std::string temp_header_ascii; @@ -208,8 +224,8 @@ private: std::wstring temp_header_value; std::string temp_header_value_ascii; - bool post_put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream); - bool fetch_internal(const char * url, const std::string * in, pt::TextStream & out); + bool fetch_internal(Method method, const char * url, const std::string * in, pt::TextStream & out); + void put_method(Method & method); static size_t fetch_read_function(char * ptr, size_t size, size_t nmemb, void * userdata); static int fetch_seek_set(Http * http, curl_off_t offset); static int fetch_seek_cur(Http * http, curl_off_t offset);