curl-cpp
static c++17 wrapper for curl with -fno-exceptions support
|
Classes | |
class | Exception |
class | NotBuiltIn_error |
class | ProtocolInternal_error |
Public Types | |
enum | header_option { header_option::unspecified, header_option::unified, separate } |
enum | code { ok = 0, unsupported_protocol, url_malformat, cannot_resolve_proxy, cannot_resolve_host, cannot_connect, remote_access_denied, writeback_error, upload_failure, timedout, aborted_by_callback, too_many_redirects, ssl_pinned_pubkey_mismatch } |
enum | PauseOptions { PauseOptions::recv = 1 << 0, PauseOptions::send = 1 << 2, PauseOptions::all = recv | send, PauseOptions::cont = 0 } |
using | writeback_t = std::size_t(*)(char *buffer, std::size_t _, std::size_t size, void *userp) |
using | readback_t = std::size_t(*)(char *buffer, std::size_t size, std::size_t nitems, void *userp) |
using | perform_ret_t = Ret_except< code, std::bad_alloc, std::invalid_argument, std::length_error, Exception, Recursive_api_call_Exception, NotBuiltIn_error, ProtocolInternal_error > |
Public Member Functions | |
void | set_verbose (FILE *stderr_stream_arg) noexcept |
void | set_error_buffer (char *error_buffer) noexcept |
void | set_private (void *userp) noexcept |
void * | get_private () const noexcept |
void | set_writeback (writeback_t writeback, void *userp) noexcept |
void | set_url (const Url_ref_t &url) noexcept |
auto | set_url (const char *url) noexcept -> Ret_except< void, std::bad_alloc > |
auto | pin_publickey (const char *pubkey) -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | set_cookie (const char *cookies) noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | set_cookiefile (const char *cookie_filename) noexcept -> Ret_except< void, curl::NotBuiltIn_error > |
auto | set_cookiejar (const char *cookie_filename) noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | set_cookielist (const char *cookie) noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
void | start_new_cookie_session () noexcept |
auto | erase_all_cookies_in_mem () noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | erase_all_session_cookies_in_mem () noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | flush_cookies_to_jar () noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
auto | reload_cookies_from_file () noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error > |
void | set_follow_location (long redir) noexcept |
auto | set_useragent (const char *useragent) noexcept -> Ret_except< void, std::bad_alloc > |
auto | set_encoding (const char *encoding) noexcept -> Ret_except< void, std::bad_alloc > |
auto | set_interface (const char *value) noexcept -> Ret_except< void, std::bad_alloc > |
auto | set_ip_addr_only (const char *ip_addr) noexcept -> Ret_except< void, std::bad_alloc > |
void | set_timeout (unsigned long timeout) noexcept |
void | set_http_header (const utils::slist &l, header_option option=header_option::unspecified) noexcept |
void | set_nobody (bool enable) noexcept |
void | request_get () noexcept |
void | request_post (const void *data, std::size_t len) noexcept |
void | request_post (readback_t readback, void *userp, std::size_t len=-1) noexcept |
auto | perform () noexcept -> perform_ret_t |
auto | set_pause (PauseOptions option) noexcept -> Ret_except< code, std::bad_alloc, Exception > |
long | get_response_code () const noexcept |
std::size_t | getinfo_sizeof_request () const noexcept |
std::size_t | getinfo_sizeof_uploaded () const noexcept |
std::size_t | getinfo_sizeof_response_header () const noexcept |
std::size_t | getinfo_sizeof_response_body () const noexcept |
std::size_t | getinfo_transfer_time () const noexcept |
auto | getinfo_redirect_url () const noexcept -> const char * |
auto | getinfo_effective_url () const noexcept -> const char * |
auto | getinfo_cookie_list () const noexcept -> Ret_except< utils::slist, curl::NotBuiltIn_error > |
auto | get_active_socket () const noexcept -> curl_socket_t |
template<class String > | |
auto | set_readall_writeback (String &response) noexcept |
template<class String , class size_type > | |
auto | set_read_writeback (std::pair< String, size_type > &arg) noexcept |
void | setup_establish_connection_only () noexcept |
Static Public Member Functions | |
static std::size_t | get_error_buffer_size () noexcept |
Public Attributes | |
char * | curl_easy = nullptr |
friend | Multi_t |
Static Protected Member Functions | |
static auto | check_perform (long code, const char *fname) noexcept -> perform_ret_t |
Definition at line 53 of file curl_easy.hpp.
using curl::Easy_ref_t::writeback_t = std::size_t (*)(char *buffer, std::size_t _, std::size_t size, void *userp) |
buffer | not null-terminated |
size | at most CURL_MAX_WRITE_SIZE |
@ return if less than size, then it will singal an err cond to libcurl.
This will cause the transfer to get aborted and the libcurl function used will return code::writeback_error.
If curl_t::has_pause_support() == true, and CURL_WRITEFUNC_PAUSE is returned, it will cause transfer to be paused. See curl_easy_pause for more details.
It would be undefined behavior to call any easy member function in writeback.
Definition at line 145 of file curl_easy.hpp.
using curl::Easy_ref_t::readback_t = std::size_t (*)(char *buffer, std::size_t size, std::size_t nitems, void *userp) |
The length of buffer is size * nitems.
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the server expected it, like when you've said you will upload N bytes and you upload less than N bytes), you may experience that the server "hangs" waiting for the rest of the data that won't come.
Definition at line 539 of file curl_easy.hpp.
|
strong |
Definition at line 447 of file curl_easy.hpp.
|
strong |
NotSupported_error,std::bad_alloc | or any exception defined in this class |
Definition at line 551 of file curl_easy.hpp.
|
strong |
Definition at line 572 of file curl_easy.hpp.
|
noexcept |
stderr_stream_arg | if not null, enable verbose mode and print them onto stderr_stream_arg. |
Definition at line 64 of file curl_easy.cc.
|
staticnoexcept |
Minimum length for error buffer.
Definition at line 71 of file curl_easy.cc.
|
noexcept |
buffer | either nullptr to disable error buffer, or at least get_error_buffer_size() big. |
The error buffer must be kept around until call set_error_buffer again or curl::Easy_t is destroyed.
The error buffer is only set if ProtocolInternal_error is thrown.
Definition at line 75 of file curl_easy.cc.
|
noexcept |
userp | any user-defined pointer. Default to nullptr. |
Definition at line 80 of file curl_easy.cc.
|
noexcept |
Definition at line 84 of file curl_easy.cc.
|
noexcept |
By default, writeback == std::fwrite, userp == stdout
Definition at line 91 of file curl_easy.cc.
|
noexcept |
url | content of it must not be changed during call to perform(), but can be changed once it is finished. |
Definition at line 97 of file curl_easy.cc.
|
noexcept |
url | would be dupped, thus it can be freed up after this function call. |
Definition at line 101 of file curl_easy.cc.
auto curl::Easy_ref_t::pin_publickey | ( | const char * | pubkey | ) | -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error> |
pubkey | null-terminated string. The string can be the file name of your pinned public key. The file format expected is "PEM" or "DER". The string can also be any number of base64 encoded sha256 hashes preceded by "sha256//" and separated by ";". The application does not have to keep the string around after setting this option. |
When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and if it does not exactly match the public key provided to this option, curl will abort the connection before sending or receiving any data.
On mismatch, code::ssl_pinned_pubkey_mismatch is returned.
Definition at line 107 of file curl_easy.cc.
|
noexcept |
cookies | null-terminated string, in format "name1=content1; name2=content2;" This string will be strdup-ed and override previous call. This is defaulted to nullptr. |
This option sets the cookie header explicitly in the outgoing request(s).
If multiple requests are done due to authentication, followed redirections or similar, they will all get this cookie passed on.
The cookies set by this option are separate from the internal cookie storage held by the cookie engine and will not be modified by it.
If you enable the cookie engine and either you've imported a cookie of the same name (e.g. 'foo') or the server has set one, it will have no effect on the cookies you set here.
A request to the server will send both the 'foo' held by the cookie engine and the 'foo' held by this option.
To set a cookie that is instead held by the cookie engine and can be modified by the server use set_cookielist.
This option will not enable the cookie engine. Use set_cookiefile or set_cookiejar to enable parsing and sending cookies automatically.
Definition at line 120 of file curl_easy.cc.
|
noexcept |
cookie_filename | null-terminte string for the filename of the cookie file; "" to enable cookie engine without any initial cookies; "-" to read the cookie from stdin; Does not have to keep around after this call. This is default to nullptr. |
The cookie data can be in either the old Netscape / Mozilla cookie data format or just regular HTTP headers (Set-Cookie style) dumped to a file.
It enables the cookie engine, making libcurl parse response and send cookies on subsequent requests with this handle.
This function can be used with set_cookielist.
It only reads cookies right before a transfer is started.
To make libcurl write cookies to file, see set_cookiejar.
Exercise caution if you are using this option and multiple transfers may occur due to redirect:
If you use the Set-Cookie format: "name1=content1; name2=content2;" and don't specify a domain then the cookie is sent for any domain (even after redirects are followed) and cannot be modified by a server-set cookie.
If a server sets a cookie of the same name then both will be sent on a future transfer to that server, likely not what you intended. To address these issues set a domain in Set-Cookie HTTP header (doing that will include sub-domains) or use the Netscape format:
char *my_cookie = "example.com" // Hostname "\t" "FALSE" // Include subdomains "\t" "/" // Path "\t" "FALSE" // Secure "\t" "0" // Expiry in epoch time format. 0 == Session "\t" "foo" // Name "\t" "bar"; // Value
If you call this function multiple times, you just add more files to read. Subsequent files will add more cookies.
Definition at line 131 of file curl_easy.cc.
|
noexcept |
cookie_filename | null-terminated string; "-" write cookies to stdout; Does not have to keep around after this call. This is default to nullptr. |
This will make libcurl write all internally known cookies to the specified file when curl::Easy_t is destroyed.
If no cookies, then no file will be created.
Using this option also enables cookies for this session, so if you for example follow a location it will make matching cookies get sent accordingly.
Note that libcurl doesn't read any cookies from the cookie jar.
If you want to read cookies from a file, use set_cookiefile.
If the cookie jar file can't be created or written to, libcurl will not and cannot report an error for this.
Using set_verbose, set curl::stderr_stream to non-null before creating curl::Easy_t or CURLOPT_DEBUGFUNCTION will get a warning to display, but that is the only visible feedback you get about this possibly lethal situation.
Since 7.43.0 cookies that were imported in the Set-Cookie format without a domain name are not exported by this function.
Definition at line 138 of file curl_easy.cc.
|
noexcept |
cookie_filename | null-terminte string for the filename of the cookie file; Does not have to keep around after this call. This is default to nullptr. |
The cookie will be immediately loaded, and this function can be mixed with set_cookiefile.
Such a cookie can be either a single line in Netscape / Mozilla format or just regular HTTP-style header (Set-Cookie: ...) format.
This will also enable the cookie engine and adds that single cookie to the internal cookie store.
Exercise caution if you are using this option and multiple transfers may occur due to redirect:
If you use the Set-Cookie format: "name1=content1; name2=content2;" and don't specify a domain then the cookie is sent for any domain (even after redirects are followed) and cannot be modified by a server-set cookie.
If a server sets a cookie of the same name then both will be sent on a future transfer to that server, likely not what you intended. To address these issues set a domain in Set-Cookie HTTP header (doing that will include sub-domains) or use the Netscape format:
char *my_cookie = "example.com" // Hostname "\t" "FALSE" // Include subdomains "\t" "/" // Path "\t" "FALSE" // Secure "\t" "0" // Expiry in epoch time format. 0 == Session "\t" "foo" // Name "\t" "bar"; // Value
Definition at line 149 of file curl_easy.cc.
|
noexcept |
It will force libcurl to ignore all cookies it is about to load that are "session cookies" from the previous session.
Session cookies are cookies without expiry date and they are meant to be alive and existing for this "session" only.
A "session" is usually defined in browser land for as long as you have your browser up, more or less.
By default, libcurl always stores and loads all cookies, independent if they are session cookies or not.
NOTE that cookie support can be removed in compile time of libcurl, there is no guarantee this would work.
Definition at line 160 of file curl_easy.cc.
|
noexcept |
Definition at line 164 of file curl_easy.cc.
|
noexcept |
Session cookies are cookies without expiry date and they are meant to be alive and existing for this "session" only.
A "session" is usually defined in browser land for as long as you have your browser up, more or less.
Definition at line 169 of file curl_easy.cc.
|
noexcept |
writes all known cookies to the file specified by set_cookiejar.
Definition at line 174 of file curl_easy.cc.
|
noexcept |
loads all cookies from the files specified by set_cookiefile.
Definition at line 179 of file curl_easy.cc.
|
noexcept |
redir | set to 0 to disable redirection. set to -1 to allow infinite number of redirections. Other number enables redir number of redirections. |
Definition at line 185 of file curl_easy.cc.
|
noexcept |
useragent | pass nullptr for no useragent (default) |
Definition at line 194 of file curl_easy.cc.
|
noexcept |
encoding | "" for enable all (default); nullptr for disable all (including auto decompression). |
Definition at line 199 of file curl_easy.cc.
|
noexcept |
value | can be ipv4 or ipv6 address/hostname/interface. If it is nullptr, then set to whatever TCP stack find available (default). |
Definition at line 205 of file curl_easy.cc.
|
noexcept |
ip_addr | ipv4/ipv6 address If it is nullptr, then set to whatever TCP stack find available (default). |
46 is the maximum length for ipv6 address represented in string.
Information retrieved from here.
Definition at line 210 of file curl_easy.cc.
|
noexcept |
timeout | in milliseconds. Set to 0 to disable (default); should be less than std::numeric_limits<long>::max(). |
Definition at line 226 of file curl_easy.cc.
|
noexcept |
l | will not be copied, thus it is required to be kept around until another set_http_header is issued or this Easy_t is destroyed. |
Must not be CRLF-terminated.
option | control whether header set here will also sent to proxy |
Example:
Replace hedaer 'Accept:'
utils::slist l; l.push_back("Accept: deflate"); easy.set_http_header(l);
Remove header 'Accept:'
easy.set_http_header(utils::slist{});
Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers from being sent to hosts other than the first used one, unless specifically permitted with the CURLOPT_UNRESTRICTED_AUTH option.
Starting in 7.64.0, libcurl will specifically prevent "Cookie:" headers from being sent to hosts other than the first used one, unless specifically permitted with the CURLOPT_UNRESTRICTED_AUTH option.
Definition at line 231 of file curl_easy.cc.
|
noexcept |
enable | if true, then it would not request body data to be transfered; if false, then a normal request (default). |
Definition at line 245 of file curl_easy.cc.
|
noexcept |
This is the default for http, and would also set_nobody(false).
Definition at line 250 of file curl_easy.cc.
|
noexcept |
len | if set to -1, then libcurl would strlen(data) to determine its length. |
The data pointed to is NOT copied by the library: as a consequence, it must be preserved by the calling application until the associated transfer finishes.
Definition at line 254 of file curl_easy.cc.
|
noexcept |
len | optional. Set to -1 means length of data is not known ahead of time. |
Definition at line 259 of file curl_easy.cc.
|
noexcept |
The pausing of transfers does not work with protocols that work without network connectivity, like FILE://. Trying to pause such a transfer, in any direction, will cause problems in the worst case or an error in the best case.
Before libcurl 7.32.0, when a specific handle was unpaused with this function, there was no particular forced rechecking or similar of the socket's state, which made the continuation of the transfer get delayed until next multi-socket call invoke or even longer.
Alternatively, the user could forcibly call for example curl_multi_socket_all - with a rather hefty performance penalty.
Starting in libcurl 7.32.0, unpausing a transfer will schedule a timeout trigger for that handle 1 millisecond into the future, so that a curl_multi_socket_action( ... CURL_SOCKET_TIMEOUT) can be used immediately afterwards to get the transfer going again as desired.
If you use multi interface, you can use multi_socket_action to have a more in-detail control of pausing the easy.
When pausing a read by returning the magic return code from a write callback, the read data is already in libcurl's internal buffers so it'll have to keep it in an allocated buffer until the reading is again unpaused using this function.
If the downloaded data is compressed and is asked to get uncompressed automatically on download, libcurl will continue to uncompress the entire downloaded chunk and it will cache the data uncompressed. This has the side-effect that if you download something that is compressed a lot, it can result in a very large amount of data required to be allocated to be kept around during the pause.
This said, you should probably consider not using paused reading if you allow libcurl to uncompress data automatically.
Definition at line 278 of file curl_easy.cc.
|
noexcept |
Definition at line 304 of file curl_easy.cc.
|
noexcept |
Definition at line 310 of file curl_easy.cc.
|
noexcept |
Definition at line 320 of file curl_easy.cc.
|
noexcept |
Definition at line 326 of file curl_easy.cc.
|
noexcept |
What transfer time really measures:
| |--NAMELOOKUP |--|--CONNECT |--|--|--APPCONNECT |--|--|--|--PRETRANSFER |--|--|--|--|--STARTTRANSFER |--|--|--|--|--|--transfer time |--|--|--|--|--|--REDIRECT
Definition at line 336 of file curl_easy.cc.
|
noexcept |
If you disable redirection or CURLOPT_MAXREDIRS limit prevented a redirect to happen (since 7.54.1), a would-be redirect-to url is returned.
This function is only meaningful for http(s) protocol.
Definition at line 347 of file curl_easy.cc.
|
noexcept |
It might be the url you set or the redirected actual url.
Definition at line 353 of file curl_easy.cc.
|
noexcept |
Since 7.43.0 cookies that were imported in the Set-Cookie format without a domain name are not exported by this option.
Definition at line 360 of file curl_easy.cc.
|
noexcept |
The return value can be used in Multi_t::multi_assign()
Definition at line 370 of file curl_easy.cc.
|
inlinenoexcept |
set_readall_callback() can be used for get or post.
Definition at line 729 of file curl_easy.hpp.
|
inlinenoexcept |
set_read_callback() can be used for get or post.
This function will set writeback to only write arg.second bytes into arg.first.
Definition at line 745 of file curl_easy.hpp.
|
noexcept |
After this call, Easy_ref_t::perform/Multi_t::perform or multi_socket_action must be called to establish the connection.
To use the established connection, call set_nobody(false) or request_*() to disable nobody.
Example usage:
int main(int argc, char* argv[]) { curl::curl_t curl{nullptr}; auto easy = curl.create_easy(); assert(easy.p1 && easy.p2); auto easy_ref = curl::Easy_ref_t{easy}; easy_ref.set_url("https://www.google.com"); setup_establish_connection_only(); easy_ref.perform(); // Establish the connection request_get(); easy_ref.perform(); // Now result is writen to stdout. }
Definition at line 377 of file curl_easy.cc.