add Http::fetch(...) methods

This commit is contained in:
Tomasz Sowa 2022-11-18 16:38:03 +01:00
parent 2bd56c87e4
commit 89249f1297
2 changed files with 132 additions and 57 deletions

View File

@ -73,7 +73,6 @@ Http & Http::begin()
debug_info = nullptr; debug_info = nullptr;
follow_location = true; follow_location = true;
verify_ssl_cert = true; verify_ssl_cert = true;
use_post_method = true;
return *this; 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; std::string url_ascii;
pt::TextStream out_stream; pt::TextStream out_stream;
if( clear_stream )
{
out.clear();
}
pt::wide_to_utf8(url, url_ascii); pt::wide_to_utf8(url, url_ascii);
bool status = fetch_internal(url_ascii.c_str(), nullptr, out_stream); bool status = fetch_internal(method, url_ascii.c_str(), in, out_stream);
pt::utf8_to_wide(out_stream, out, clear_str); 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; 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) bool Http::get(const wchar_t * url, pt::WTextStream & out, bool clear_stream)
{ {
std::string url_ascii; const std::string * in = nullptr;
pt::TextStream out_stream; return fetch(Method::method_get, url, in, out, clear_stream);
pt::wide_to_utf8(url, url_ascii);
bool status = fetch_internal(url_ascii.c_str(), nullptr, out_stream);
out << out_stream;
return status;
} }
@ -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) bool Http::post(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream)
{ {
use_post_method = true; return fetch(Method::method_post, url, &in, out, clear_stream);
return post_put(url, in, out, clear_stream);
} }
bool Http::post(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream) bool Http::post(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream)
{ {
use_post_method = true; return fetch(Method::method_post, url, &in, out, clear_stream);
return post_put(url.c_str(), in, out, clear_stream);
} }
bool Http::post(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream) bool Http::post(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream)
{ {
std::string in_ascii; return fetch(Method::method_post, url, &in, out, clear_stream);
in.to_str(in_ascii);
use_post_method = true;
return post_put(url, in_ascii, out, clear_stream);
} }
bool Http::put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream) bool Http::put(const wchar_t * url, const std::string & in, pt::WTextStream & out, bool clear_stream)
{ {
use_post_method = false; return fetch(Method::method_put, url, &in, out, clear_stream);
return post_put(url, in, out, clear_stream);
} }
bool Http::put(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream) bool Http::put(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream)
{ {
use_post_method = false; return fetch(Method::method_put, url, &in, out, clear_stream);
return post_put(url.c_str(), in, out, clear_stream);
} }
bool Http::put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream) bool Http::put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream)
{ {
std::string in_ascii; return fetch(Method::method_put, url, &in, out, clear_stream);
in.to_str(in_ascii);
use_post_method = false;
return post_put(url, in_ascii, 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 * // 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; bool status = false;
initialize_curl_if_needed(); 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_input = in; // can be null
read_function_index = 0; read_function_index = 0;
put_method(method);
if( read_function_input ) if( read_function_input )
{ {
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fetch_read_function); curl_easy_setopt(curl, CURLOPT_READFUNCTION, fetch_read_function);
curl_easy_setopt(curl, CURLOPT_READDATA, this); curl_easy_setopt(curl, CURLOPT_READDATA, this);
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, fetch_seek_function); curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, fetch_seek_function);
curl_easy_setopt(curl, CURLOPT_SEEKDATA, this); 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_off_t size = read_function_input->size();
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, 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 Http::fetch_read_function(char * ptr, size_t size, size_t nmemb, void * userdata)
{ {
size_t len = 0; 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"";
}
}
} }

View File

@ -54,6 +54,14 @@ public:
static const long HTTP_STATUS_301_Moved_Permanently = 301; static const long HTTP_STATUS_301_Moved_Permanently = 301;
static const long HTTP_STATUS_302_Found = 302; static const long HTTP_STATUS_302_Found = 302;
enum Method {
method_get,
method_post,
method_put,
method_patch,
method_delete,
method_options,
};
Http(); Http();
~Http(); ~Http();
@ -157,6 +165,14 @@ public:
*/ */
void verify_ssl(bool verify); 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 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 std::wstring & url, std::wstring & out, bool clear_str = true);
bool get(const pt::WTextStream & 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(); long get_status();
static const wchar_t * method_to_str(Method method);
private: private:
@ -200,7 +217,6 @@ private:
pt::Space * debug_info; pt::Space * debug_info;
bool follow_location; bool follow_location;
bool verify_ssl_cert; 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::wstring temp_header;
std::string temp_header_ascii; std::string temp_header_ascii;
@ -208,8 +224,8 @@ private:
std::wstring temp_header_value; std::wstring temp_header_value;
std::string temp_header_value_ascii; 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(Method method, const char * url, const std::string * in, pt::TextStream & out);
bool fetch_internal(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 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_set(Http * http, curl_off_t offset);
static int fetch_seek_cur(Http * http, curl_off_t offset); static int fetch_seek_cur(Http * http, curl_off_t offset);