curl-cpp
static c++17 wrapper for curl with -fno-exceptions support
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Protected Member Functions | List of all members
curl::Easy_ref_t Class Reference
Collaboration diagram for curl::Easy_ref_t:
Collaboration graph

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
 

Detailed Description

Examples
curl_easy_get.cc, curl_multi_poll.cc, curl_multi_poll2.cc, curl_multi_socket_action_epoll.cc, curl_multi_socket_action_event.cc, curl_multi_socket_action_uv.cc, and curl_share.cc.

Definition at line 53 of file curl_easy.hpp.

Member Typedef Documentation

◆ writeback_t

using curl::Easy_ref_t::writeback_t = std::size_t (*)(char *buffer, std::size_t _, std::size_t size, void *userp)
Parameters
buffernot null-terminated
sizeat 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.

◆ readback_t

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.

Returns
bytes writen to the buffer.
0 to signal end-of-file to the library and cause it to stop the current transfer.
CURL_READFUNC_ABORT (requires curl_t::has_readfunc_abort_support()) to stop immediately, result code::aborted_by_callback.
If curl_t::has_pause_support() == true, and CURL_READFUNC_PAUSE is returned, it would cause reading from this connection to pause. See curl_easy_pause for further details.
Bugs: when doing TFTP uploads, you must return the exact amount of data that the callback wants, or it will be considered the final packet by the server end and the transfer will end there.

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.

Member Enumeration Documentation

◆ header_option

Enumerator
unspecified 

If unspecified is passed to set_http_header, then the previous header_option (or default) will be used.

If curl_t::has_header_option_support() == false, then it is default to unified.

Before 7.42.1, default is unified. After 7.42.1, default is separate.

unified 

The following options only take effect when curl_t::has_header_option_support() == true.

Definition at line 447 of file curl_easy.hpp.

447  {
458  unspecified,
463  unified, // header specified with set_http_header will also be used for proxy
464  separate, // reverse of unified
465  };

◆ code

Precondition
curl_t::has_protocol(protocol you use in url)
Exceptions
NotSupported_error,std::bad_allocor any exception defined in this class

Definition at line 551 of file curl_easy.hpp.

551  {
552  ok = 0,
553  unsupported_protocol,
554  url_malformat,
555  cannot_resolve_proxy,
556  cannot_resolve_host,
557  cannot_connect, // Cannot connect to host or proxy
558  remote_access_denied,
559  writeback_error,
560  upload_failure, // Failed starting the upload
561  timedout,
562  aborted_by_callback, // If readback return CURL_READFUNC_ABORT.
563  too_many_redirects,
564  ssl_pinned_pubkey_mismatch,
565  };

◆ PauseOptions

Enumerator
recv 

Pause receiving data.
There will be no data received on this connection until this function is called again without this bit set.
Thus, the writeback won't be called.

send 

Pause sending data.
There will be no data sent on this connection until this function is called again without this bit set.
Thus, the readback won't be called/the data registered with request_post won't be copied.

all 

Convenience define that pauses both directions.

cont 

Convenience define that unpauses both directions.

Definition at line 572 of file curl_easy.hpp.

572  {
579  recv = 1 << 0,
586  send = 1 << 2, // Make value of pause_send the same as stock libcurl
590  all = recv | send,
594  cont = 0,
595  };

Member Function Documentation

◆ set_verbose()

void curl::Easy_ref_t::set_verbose ( FILE *  stderr_stream_arg)
noexcept
Parameters
stderr_stream_argif not null, enable verbose mode and print them onto stderr_stream_arg.

Definition at line 64 of file curl_easy.cc.

65 {
66  if (stderr_stream_arg) {
67  curl_easy_setopt(curl_easy, CURLOPT_STDERR, stderr_stream_arg);
68  curl_easy_setopt(curl_easy, CURLOPT_VERBOSE, 1L);
69  }
70 }

◆ get_error_buffer_size()

std::size_t curl::Easy_ref_t::get_error_buffer_size ( )
staticnoexcept

Minimum length for error buffer.

Definition at line 71 of file curl_easy.cc.

72 {
73  return CURL_ERROR_SIZE;
74 }

◆ set_error_buffer()

void curl::Easy_ref_t::set_error_buffer ( char *  error_buffer)
noexcept
Parameters
buffereither 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.

76 {
77  curl_easy_setopt(curl_easy, CURLOPT_ERRORBUFFER, error_buffer);
78 }

◆ set_private()

void curl::Easy_ref_t::set_private ( void *  userp)
noexcept
Precondition
curl_t::has_private_ptr_support()
Parameters
userpany user-defined pointer. Default to nullptr.

Definition at line 80 of file curl_easy.cc.

81 {
82  curl_easy_setopt(curl_easy, CURLOPT_PRIVATE, userp);
83 }

◆ get_private()

void * curl::Easy_ref_t::get_private ( ) const
noexcept
Precondition
curl_t::has_private_ptr_support()
Returns
pointer set via set_private or nullptr if not set at all.

Definition at line 84 of file curl_easy.cc.

85 {
86  char *userp;
87  curl_easy_getinfo(curl_easy, CURLINFO_PRIVATE, &userp);
88  return userp;
89 }

◆ set_writeback()

void curl::Easy_ref_t::set_writeback ( writeback_t  writeback,
void *  userp 
)
noexcept

By default, writeback == std::fwrite, userp == stdout

Definition at line 91 of file curl_easy.cc.

92 {
93  curl_easy_setopt(curl_easy, CURLOPT_WRITEFUNCTION, writeback);
94  curl_easy_setopt(curl_easy, CURLOPT_WRITEDATA, userp);
95 }
Here is the caller graph for this function:

◆ set_url() [1/2]

void curl::Easy_ref_t::set_url ( const Url_ref_t url)
noexcept
Precondition
curl_t::has_CURLU()
Parameters
urlcontent of it must not be changed during call to perform(), but can be changed once it is finished.
Examples
curl_easy_get.cc.

Definition at line 97 of file curl_easy.cc.

98 {
99  curl_easy_setopt(curl_easy, CURLOPT_CURLU, url.url);
100 }

◆ set_url() [2/2]

auto curl::Easy_ref_t::set_url ( const char *  url) -> Ret_except<void, std::bad_alloc>
noexcept
Parameters
urlwould be dupped, thus it can be freed up after this function call.

Definition at line 101 of file curl_easy.cc.

102 {
103  CHECK_OOM(curl_easy_setopt(curl_easy, CURLOPT_URL, url));
104  return {};
105 }

◆ pin_publickey()

auto curl::Easy_ref_t::pin_publickey ( const char *  pubkey) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
Precondition
url set to use TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc && curl_t::has_protocol(protolcol)
Parameters
pubkeynull-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.
Returns
note that whether this is supported depend on:
  • ssl lib
  • libcurl version
  • whether pubkey is a path to file or sha256.

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.

109 {
110  auto result = curl_easy_setopt(curl_easy, CURLOPT_PINNEDPUBLICKEY, pubkey);
111  if (result == CURLE_OUT_OF_MEMORY)
112  return {std::bad_alloc{}};
113  else if (result == CURLE_UNKNOWN_OPTION)
114  return {curl::NotBuiltIn_error{"pining public key is not supported by this version of libcurl "
115  "on this specific ssl version"}};
116  else
117  return {};
118 }

◆ set_cookie()

auto curl::Easy_ref_t::set_cookie ( const char *  cookies) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
cookiesnull-terminated string, in format "name1=content1; name2=content2;"
This string will be strdup-ed and override previous call.
This is defaulted to nullptr.
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

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.

122 {
123  auto code = curl_easy_setopt(curl_easy, CURLOPT_COOKIE, cookies);
124  if (code == CURLE_UNKNOWN_OPTION)
125  return curl::NotBuiltIn_error{"cookies not supported"};
126  else if (code == CURLE_OUT_OF_MEMORY)
127  return {std::bad_alloc{}};
128 
129  return {};
130 }

◆ set_cookiefile()

auto curl::Easy_ref_t::set_cookiefile ( const char *  cookie_filename) -> Ret_except<void, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
cookie_filenamenull-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.
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

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.

133 {
134  if (curl_easy_setopt(curl_easy, CURLOPT_COOKIEFILE, cookie_filename) == CURLE_UNKNOWN_OPTION)
135  return {curl::NotBuiltIn_error{"cookies not supported"}};
136  return {};
137 }

◆ set_cookiejar()

auto curl::Easy_ref_t::set_cookiejar ( const char *  cookie_filename) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
cookie_filenamenull-terminated string;
"-" write cookies to stdout;
Does not have to keep around after this call.
This is default to nullptr.
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

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.

140 {
141  auto code = curl_easy_setopt(curl_easy, CURLOPT_COOKIEJAR, cookie_filename);
142  if (code == CURLE_UNKNOWN_OPTION)
143  return {curl::NotBuiltIn_error{"cookies not supported"}};
144  else if (code == CURLE_OUT_OF_MEMORY)
145  return {std::bad_alloc{}};
146 
147  return {};
148 }

◆ set_cookielist()

auto curl::Easy_ref_t::set_cookielist ( const char *  cookie) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
cookie_filenamenull-terminte string for the filename of the cookie file;
Does not have to keep around after this call.
This is default to nullptr.
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

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.

151 {
152  auto code = curl_easy_setopt(curl_easy, CURLOPT_COOKIELIST, cookie);
153  if (code == CURLE_UNKNOWN_OPTION)
154  return {curl::NotBuiltIn_error{"cookies not supported"}};
155  else if (code == CURLE_OUT_OF_MEMORY)
156  return {std::bad_alloc{}};
157 
158  return {};
159 }
Here is the caller graph for this function:

◆ start_new_cookie_session()

void curl::Easy_ref_t::start_new_cookie_session ( )
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")

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.

161 {
162  curl_easy_setopt(curl_easy, CURLOPT_COOKIESESSION, 1L);
163 }

◆ erase_all_cookies_in_mem()

auto curl::Easy_ref_t::erase_all_cookies_in_mem ( ) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http") && curl_t::has_erase_all_cookies_in_mem_support().
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

Definition at line 164 of file curl_easy.cc.

166 {
167  return set_cookielist("ALL");
168 }
Here is the call graph for this function:

◆ erase_all_session_cookies_in_mem()

auto curl::Easy_ref_t::erase_all_session_cookies_in_mem ( ) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http") && curl_t::has_erase_all_session_cookies_in_mem_support()
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

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.

171 {
172  return set_cookielist("SESS");
173 }
Here is the call graph for this function:

◆ flush_cookies_to_jar()

auto curl::Easy_ref_t::flush_cookies_to_jar ( ) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http") && curl_t::has_flush_cookies_to_jar()
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

writes all known cookies to the file specified by set_cookiejar.

Definition at line 174 of file curl_easy.cc.

176 {
177  return set_cookielist("FLUSH");
178 }
Here is the call graph for this function:

◆ reload_cookies_from_file()

auto curl::Easy_ref_t::reload_cookies_from_file ( ) -> Ret_except<void, std::bad_alloc, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http") && curl_t::has_reload_cookies_from_file()
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error.

loads all cookies from the files specified by set_cookiefile.

Definition at line 179 of file curl_easy.cc.

181 {
182  return set_cookielist("RELOAD");
183 }
Here is the call graph for this function:

◆ set_follow_location()

void curl::Easy_ref_t::set_follow_location ( long  redir)
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
redirset 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.

186 {
187  if (redir != 0) {
188  curl_easy_setopt(curl_easy, CURLOPT_FOLLOWLOCATION, 1L);
189  curl_easy_setopt(curl_easy, CURLOPT_MAXREDIRS, redir);
190  } else
191  curl_easy_setopt(curl_easy, CURLOPT_FOLLOWLOCATION, 0L);
192 }

◆ set_useragent()

auto curl::Easy_ref_t::set_useragent ( const char *  useragent) -> Ret_except<void, std::bad_alloc>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
useragentpass nullptr for no useragent (default)

Definition at line 194 of file curl_easy.cc.

195 {
196  CHECK_OOM(curl_easy_setopt(curl_easy, CURLOPT_USERAGENT, useragent));
197  return {};
198 }

◆ set_encoding()

auto curl::Easy_ref_t::set_encoding ( const char *  encoding) -> Ret_except<void, std::bad_alloc>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
encoding"" for enable all (default); nullptr for disable all (including auto decompression).

Definition at line 199 of file curl_easy.cc.

200 {
201  CHECK_OOM(curl_easy_setopt(curl_easy, CURLOPT_ACCEPT_ENCODING, encoding));
202  return {};
203 }

◆ set_interface()

auto curl::Easy_ref_t::set_interface ( const char *  value) -> Ret_except<void, std::bad_alloc>
noexcept
Parameters
valuecan 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.

206 {
207  CHECK_OOM(curl_easy_setopt(curl_easy, CURLOPT_INTERFACE, value));
208  return {};
209 }
Here is the caller graph for this function:

◆ set_ip_addr_only()

auto curl::Easy_ref_t::set_ip_addr_only ( const char *  ip_addr) -> Ret_except<void, std::bad_alloc>
noexcept
Precondition
curl_t::has_set_ip_addr_only_support()
Parameters
ip_addripv4/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.

211 {
219  constexpr const auto buffer_size = 5 + 46;
220  char buffer[buffer_size];
221  std::snprintf(buffer, buffer_size, "host!%s", ip_addr);
222 
223  return set_interface(buffer);
224 }
Here is the call graph for this function:

◆ set_timeout()

void curl::Easy_ref_t::set_timeout ( unsigned long  timeout)
noexcept
Parameters
timeoutin 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.

227 {
228  curl_easy_setopt(curl_easy, CURLOPT_TIMEOUT_MS, timeout);
229 }

◆ set_http_header()

void curl::Easy_ref_t::set_http_header ( const utils::slist l,
header_option  option = header_option::unspecified 
)
noexcept
Precondition
url is set to use http(s)
Parameters
lwill 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.

Parameters
optioncontrol 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.

232 {
233  curl_easy_setopt(curl_easy, CURLOPT_HTTPHEADER, static_cast<struct curl_slist*>(l.get_underlying_ptr()));
234  if (option != header_option::unspecified) {
235  long value;
236  if (option == header_option::separate)
237  value = CURLHEADER_SEPARATE;
238  else
239  value = CURLHEADER_UNIFIED;
240 
241  curl_easy_setopt(curl_easy, CURLOPT_HEADEROPT, value);
242  }
243 }
Here is the call graph for this function:

◆ set_nobody()

void curl::Easy_ref_t::set_nobody ( bool  enable)
noexcept
Parameters
enableif 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.

246 {
247  curl_easy_setopt(curl_easy, CURLOPT_NOBODY, enable);
248 }

◆ request_get()

void curl::Easy_ref_t::request_get ( )
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")

This is the default for http, and would also set_nobody(false).

Definition at line 250 of file curl_easy.cc.

251 {
252  curl_easy_setopt(curl_easy, CURLOPT_HTTPGET, 1L);
253 }
Here is the caller graph for this function:

◆ request_post() [1/2]

void curl::Easy_ref_t::request_post ( const void *  data,
std::size_t  len 
)
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
lenif 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.

255 {
256  curl_easy_setopt(curl_easy, CURLOPT_POSTFIELDSIZE_LARGE, len);
257  curl_easy_setopt(curl_easy, CURLOPT_POSTFIELDS, data);
258 }
Here is the caller graph for this function:

◆ request_post() [2/2]

void curl::Easy_ref_t::request_post ( readback_t  readback,
void *  userp,
std::size_t  len = -1 
)
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Parameters
lenoptional. Set to -1 means length of data is not known ahead of time.

Definition at line 259 of file curl_easy.cc.

260 {
261  request_post(nullptr, len);
262 
263  curl_easy_setopt(curl_easy, CURLOPT_READFUNCTION, readback);
264  curl_easy_setopt(curl_easy, CURLOPT_READDATA, userp);
265 }
Here is the call graph for this function:

◆ set_pause()

auto curl::Easy_ref_t::set_pause ( PauseOptions  option) -> Ret_except<code, std::bad_alloc, Exception>
noexcept
Precondition
curl_t::has_pause_support() and there's an ongoing transfer
Returns
If no exception is thrown, then it is either code::ok or code::writeback_error.

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.

Use of set_pause with multi_socket_action interface

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.

MEMORY USE

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.

279 {
280  int bitmask = 0;
281  if (option & PauseOptions::recv)
282  bitmask |= CURLPAUSE_RECV;
283  if (option & PauseOptions::send)
284  bitmask |= CURLPAUSE_SEND;
285 
286  auto result = curl_easy_pause(curl_easy, bitmask);
287  if (result == CURLE_WRITE_ERROR)
288  return {code::writeback_error};
289  else if (result == CURLE_OUT_OF_MEMORY)
290  return {std::bad_alloc{}};
291  else if (result != CURLE_OK)
292  return {Exception{result}};
293  else
294  return {code::ok};
295 }

◆ getinfo_sizeof_request()

std::size_t curl::Easy_ref_t::getinfo_sizeof_request ( ) const
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Returns
size of issued request headers in bytes, including headers sent in redirection.

Definition at line 304 of file curl_easy.cc.

305 {
306  long size;
307  curl_easy_getinfo(curl_easy, CURLINFO_REQUEST_SIZE, &size);
308  return size;
309 }

◆ getinfo_sizeof_uploaded()

std::size_t curl::Easy_ref_t::getinfo_sizeof_uploaded ( ) const
noexcept
Returns
in bytes

Definition at line 310 of file curl_easy.cc.

311 {
312  curl_off_t ul;
313  if (curl_easy_getinfo(curl_easy, CURLINFO_SIZE_UPLOAD_T, &ul)) {
314  double bytes;
315  curl_easy_getinfo(curl_easy, CURLINFO_SIZE_UPLOAD, &bytes);
316  return static_cast<std::size_t>(bytes);
317  }
318  return ul;
319 }

◆ getinfo_sizeof_response_header()

std::size_t curl::Easy_ref_t::getinfo_sizeof_response_header ( ) const
noexcept
Returns
in bytes

Definition at line 320 of file curl_easy.cc.

321 {
322  long size;
323  curl_easy_getinfo(curl_easy, CURLINFO_HEADER_SIZE, &size);
324  return size;
325 }

◆ getinfo_sizeof_response_body()

std::size_t curl::Easy_ref_t::getinfo_sizeof_response_body ( ) const
noexcept
Returns
in bytes, does not include response from redirection

Definition at line 326 of file curl_easy.cc.

327 {
328  curl_off_t dl;
329  if (curl_easy_getinfo(curl_easy, CURLINFO_SIZE_DOWNLOAD_T, &dl) == CURLE_UNKNOWN_OPTION) {
330  double bytes;
331  curl_easy_getinfo(curl_easy, CURLINFO_SIZE_DOWNLOAD, &bytes);
332  return static_cast<std::size_t>(bytes);
333  }
334  return dl;
335 }

◆ getinfo_transfer_time()

std::size_t curl::Easy_ref_t::getinfo_transfer_time ( ) const
noexcept
Returns
transfer time in ms

What transfer time really measures:

|
|--NAMELOOKUP
|--|--CONNECT
|--|--|--APPCONNECT
|--|--|--|--PRETRANSFER
|--|--|--|--|--STARTTRANSFER
|--|--|--|--|--|--transfer time
|--|--|--|--|--|--REDIRECT

Definition at line 336 of file curl_easy.cc.

337 {
338  curl_off_t total;
339  if (curl_easy_getinfo(curl_easy, CURLINFO_TOTAL_TIME_T, &total) == CURLE_UNKNOWN_OPTION) {
340  double seconds;
341  curl_easy_getinfo(curl_easy, CURLINFO_TOTAL_TIME, &seconds);
342  return static_cast<std::size_t>(seconds * 1000);
343  }
344  return total;
345 }

◆ getinfo_redirect_url()

auto curl::Easy_ref_t::getinfo_redirect_url ( ) const -> const char*
noexcept
Precondition
curl_t::has_redirect_url_support() && url is set to use http(s) && curl_t::has_protocol("http")
Returns
null-terminated string, freeing not required.
Would be freed up when corresponding curl::Easy_t is destroyed.
If not supported, would return nullptr.

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.

348 {
349  char *url = nullptr;
350  curl_easy_getinfo(curl_easy, CURLINFO_REDIRECT_URL, &url);
351  return url;
352 }

◆ getinfo_effective_url()

auto curl::Easy_ref_t::getinfo_effective_url ( ) const -> const char*
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http")
Returns
null-terminated string, freeing not required.
Would be freed up when corresponding curl::Easy_t is destroyed.
If not supported, would return nullptr.

It might be the url you set or the redirected actual url.

Definition at line 353 of file curl_easy.cc.

354 {
355  char *url = nullptr;
356  curl_easy_getinfo(curl_easy, CURLINFO_EFFECTIVE_URL, &url);
357  return url;
358 }

◆ getinfo_cookie_list()

auto curl::Easy_ref_t::getinfo_cookie_list ( ) const -> Ret_except<utils::slist, curl::NotBuiltIn_error>
noexcept
Precondition
url is set to use http(s) && curl_t::has_protocol("http") && curl_t::has_getinfo_cookie_list_support()
Returns
note that libcurl can be built with cookies disabled, thus this library can return exception curl::NotBuiltIn_error. If utils::slist is empty, it might be due to std::bad_alloc, or no cookie is present(cookie engine not enabled or no cookie has received).

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.

362 {
363  curl_slist *cookies = nullptr;
364  if (curl_easy_getinfo(curl_easy, CURLINFO_COOKIELIST, &cookies) == CURLE_UNKNOWN_OPTION)
365  return {curl::NotBuiltIn_error{"cookies not supported"}};
366 
367  return {utils::slist{cookies}};
368 }

◆ get_active_socket()

auto curl::Easy_ref_t::get_active_socket ( ) const -> curl_socket_t
noexcept
Precondition
curl_t::has_get_active_socket_support()
Returns
CURL_SOCKET_BAD if no valid socket or not supported

The return value can be used in Multi_t::multi_assign()

Definition at line 370 of file curl_easy.cc.

371 {
372  curl_socket_t socketfd = CURL_SOCKET_BAD;
373  curl_easy_getinfo(curl_easy, CURLINFO_ACTIVESOCKET, &socketfd);
374  return socketfd;
375 }

◆ set_readall_writeback()

template<class String >
auto curl::Easy_ref_t::set_readall_writeback ( String &  response)
inlinenoexcept

set_readall_callback() can be used for get or post.

Definition at line 729 of file curl_easy.hpp.

730  {
731  set_writeback([](char *buffer, std::size_t _, std::size_t size, void *ptr) {
732  auto &response = *static_cast<String*>(ptr);
733  response.append(buffer, buffer + size);
734  return size;
735  }, &response);
736  }
Here is the call graph for this function:

◆ set_read_writeback()

template<class String , class size_type >
auto curl::Easy_ref_t::set_read_writeback ( std::pair< String, size_type > &  arg)
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.

746  {
747  set_writeback([](char *buffer, std::size_t _, std::size_t size, void *ptr) {
748  auto &args = *static_cast<std::pair<String, size_type>*>(ptr);
749  auto &response = args.first;
750  auto &requested_len = args.second;
751 
752  auto str_size = response.size();
753  if (str_size < requested_len)
754  response.append(buffer, buffer + std::min(size, requested_len - str_size));
755 
756  return size;
757  }, &arg);
758  }
Here is the call graph for this function:

◆ setup_establish_connection_only()

void curl::Easy_ref_t::setup_establish_connection_only ( )
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.

378 {
379  request_get();
380  curl_easy_setopt(curl_easy, CURLOPT_NOBODY, 1);
381 }
Here is the call graph for this function:

The documentation for this class was generated from the following files:
curl::Easy_ref_t::PauseOptions::recv
@ recv
curl::Easy_ref_t::set_cookielist
auto set_cookielist(const char *cookie) noexcept -> Ret_except< void, std::bad_alloc, curl::NotBuiltIn_error >
Definition: curl_easy.cc:149
curl::Easy_ref_t::request_get
void request_get() noexcept
Definition: curl_easy.cc:250
curl::Easy_ref_t::request_post
void request_post(const void *data, std::size_t len) noexcept
Definition: curl_easy.cc:254
curl::Easy_ref_t::header_option::unspecified
@ unspecified
curl::Easy_ref_t::set_interface
auto set_interface(const char *value) noexcept -> Ret_except< void, std::bad_alloc >
Definition: curl_easy.cc:205
curl::NotBuiltIn_error
Definition: curl.hpp:25
curl::Easy_ref_t::code
code
Definition: curl_easy.hpp:551
curl::Easy_ref_t::set_writeback
void set_writeback(writeback_t writeback, void *userp) noexcept
Definition: curl_easy.cc:91
curl::Easy_ref_t::PauseOptions::send
@ send