docs: edited lots of libcurl docs for clarity

This commit is contained in:
Daniel Stenberg 2014-10-21 10:26:40 +02:00
parent c857bb68ec
commit 7b82b07fba
12 changed files with 189 additions and 70 deletions

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -22,20 +22,20 @@
.\" .\"
.TH curl_easy_cleanup 3 "22 aug 2007" "libcurl 7.17.0" "libcurl Manual" .TH curl_easy_cleanup 3 "22 aug 2007" "libcurl 7.17.0" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_cleanup - End a libcurl easy session curl_easy_cleanup - End a libcurl easy handle
.SH SYNOPSIS .SH SYNOPSIS
.B #include <curl/curl.h> .B #include <curl/curl.h>
.BI "void curl_easy_cleanup(CURL *" handle ");" .BI "void curl_easy_cleanup(CURL *" handle ");"
.SH DESCRIPTION .SH DESCRIPTION
This function must be the last function to call for an easy session. It is the This function must be the last function to call for an easy session. It is the
opposite of the \fIcurl_easy_init(3)\fP function and must be called with the opposite of the \fIcurl_easy_init(3)\fP function and must be called with the
same \fIhandle\fP as input that the curl_easy_init call returned. same \fIhandle\fP as input that a \fIcurl_easy_init(3)\fP call returned.
This will effectively close all connections this handle has used and possibly This might close all connections this handle has used and possibly has kept
has kept open until now. Don't call this function if you intend to transfer open until now - unless it was attached to a multi handle while doing the
more files. transfers. Don't call this function if you intend to transfer more files,
re-using handles is a key to good performance with libcurl.
Occasionally you may get your progress callback or header callback called from Occasionally you may get your progress callback or header callback called from
within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using
@ -43,13 +43,13 @@ within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using
connection and the protocol is of a kind that requires a command/response connection and the protocol is of a kind that requires a command/response
sequence before disconnect. Examples of such protocols are FTP, POP3 and IMAP. sequence before disconnect. Examples of such protocols are FTP, POP3 and IMAP.
Any uses of the \fBhandle\fP after this function has been called and have Any use of the \fBhandle\fP after this function has been called and have
returned, are illegal. This kills the handle and all memory associated with returned, is illegal. \fIcurl_easy_cleanup(3)\fP kills the handle and all
it! memory associated with it!
With libcurl versions prior to 7.17.: when you've called this, you can safely For libcurl versions before 7.17,: after you've called this function, you can
remove all the strings you've previously told libcurl to use, as it won't use safely remove all the strings you've previously told libcurl to use, as it
them anymore now. won't use them anymore now.
.SH RETURN VALUE .SH RETURN VALUE
None None
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -26,24 +26,21 @@ curl_easy_init - Start a libcurl easy session
.B #include <curl/curl.h> .B #include <curl/curl.h>
.BI "CURL *curl_easy_init( );" .BI "CURL *curl_easy_init( );"
.SH DESCRIPTION .SH DESCRIPTION
This function must be the first function to call, and it returns a CURL easy This function must be the first function to call, and it returns a CURL easy
handle that you must use as input to other easy-functions. curl_easy_init handle that you must use as input to other functions in the easy
initializes curl and this call \fBMUST\fP have a corresponding call to interface. This call \fBMUST\fP have a corresponding call to
\fIcurl_easy_cleanup(3)\fP when the operation is complete. \fIcurl_easy_cleanup(3)\fP when the operation is complete.
If you did not already call \fIcurl_global_init(3)\fP, If you did not already call \fIcurl_global_init(3)\fP, \fIcurl_easy_init(3)\fP
\fIcurl_easy_init(3)\fP does it automatically. does it automatically. This may be lethal in multi-threaded cases, since
This may be lethal in multi-threaded cases, since \fIcurl_global_init(3)\fP is \fIcurl_global_init(3)\fP is not thread-safe, and it may result in resource
not thread-safe, and it may result in resource problems because there is problems because there is no corresponding cleanup.
no corresponding cleanup.
You are strongly advised to not allow this automatic behaviour, by
calling \fIcurl_global_init(3)\fP yourself properly.
See the description in \fBlibcurl\fP(3) of global environment
requirements for details of how to use this function.
You are strongly advised to not allow this automatic behaviour, by calling
\fIcurl_global_init(3)\fP yourself properly. See the description in
\fBlibcurl\fP(3) of global environment requirements for details of how to use
this function.
.SH RETURN VALUE .SH RETURN VALUE
If this function returns NULL, something went wrong and you cannot use the If this function returns NULL, something went wrong and you cannot use the
other curl functions. other curl functions.

View File

@ -28,14 +28,14 @@ curl_easy_setopt \- set options for a curl easy handle
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter); CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
.SH DESCRIPTION .SH DESCRIPTION
curl_easy_setopt() is used to tell libcurl how to behave. By using the \fIcurl_easy_setopt(3)\fP is used to tell libcurl how to behave. By setting
appropriate options to \fIcurl_easy_setopt\fP, you can change libcurl's the appropriate options, the application can change libcurl's behavior. All
behavior. All options are set with the \fIoption\fP followed by a options are set with an \fIoption\fP followed by a \fIparameter\fP. That
\fIparameter\fP. That parameter can be a \fBlong\fP, a \fBfunction pointer\fP, parameter can be a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject
an \fBobject pointer\fP or a \fBcurl_off_t\fP, depending on what the specific pointer\fP or a \fBcurl_off_t\fP, depending on what the specific option
option expects. Read this manual carefully as bad input values may cause expects. Read this manual carefully as bad input values may cause libcurl to
libcurl to behave badly! You can only set one option in each function call. A behave badly! You can only set one option in each function call. A typical
typical application uses many curl_easy_setopt() calls in the setup phase. application uses many \fIcurl_easy_setopt(3)\fP calls in the setup phase.
Options set with this function call are valid for all forthcoming transfers Options set with this function call are valid for all forthcoming transfers
performed using this \fIhandle\fP. The options are not in any way reset performed using this \fIhandle\fP. The options are not in any way reset
@ -45,8 +45,8 @@ options back to internal default with \fIcurl_easy_reset(3)\fP.
Strings passed to libcurl as 'char *' arguments, are copied by the library; Strings passed to libcurl as 'char *' arguments, are copied by the library;
thus the string storage associated to the pointer argument may be overwritten thus the string storage associated to the pointer argument may be overwritten
after curl_easy_setopt() returns. The only exception to this rule is really after \fIcurl_easy_setopt(3)\fP returns. The only exception to this rule is
\fICURLOPT_POSTFIELDS(3)\fP, but the alternative that copies the string really \fICURLOPT_POSTFIELDS(3)\fP, but the alternative that copies the string
\fICURLOPT_COPYPOSTFIELDS(3)\fP has some usage characteristics you need to \fICURLOPT_COPYPOSTFIELDS(3)\fP has some usage characteristics you need to
read up on. read up on.
@ -498,4 +498,5 @@ version, this function will return \fICURLE_UNKNOWN_OPTION\fP. If support for
the option was disabled at compile-time, it will return the option was disabled at compile-time, it will return
\fICURLE_NOT_BUILT_IN\fP. \fICURLE_NOT_BUILT_IN\fP.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_easy_init "(3), " curl_easy_cleanup "(3), " curl_easy_reset "(3)" .BR curl_easy_init "(3), " curl_easy_cleanup "(3), " curl_easy_reset "(3), "
.BR curl_multi_setopt "(3), "

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -27,8 +27,11 @@ curl_easy_strerror - return string describing error code
const char *curl_easy_strerror(CURLcode errornum); const char *curl_easy_strerror(CURLcode errornum);
.SH DESCRIPTION .SH DESCRIPTION
The curl_easy_strerror() function returns a string describing the CURLcode The \fIcurl_easy_strerror(3)\fP function returns a string describing the
error code passed in the argument \fIerrornum\fP. CURLcode error code passed in the argument \fIerrornum\fP.
Typically applications also appreciate \fICURLOPT_ERRORBUFFER(3)\fP for more
specific error descriptions generated at run-time.
.SH AVAILABILITY .SH AVAILABILITY
This function was added in libcurl 7.12.0 This function was added in libcurl 7.12.0
.SH RETURN VALUE .SH RETURN VALUE

View File

@ -29,7 +29,7 @@ curl_free - reclaim memory that has been obtained through a libcurl call
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
curl_free reclaims memory that has been obtained through a libcurl call. Use curl_free reclaims memory that has been obtained through a libcurl call. Use
curl_free() instead of free() to avoid anomalies that can result from \fIcurl_free(3)\fP instead of free() to avoid anomalies that can result from
differences in memory management between your application and libcurl. differences in memory management between your application and libcurl.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_unescape "(3)" .BR curl_easy_unescape "(3), " curl_easy_escape "(3) "

View File

@ -29,30 +29,35 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
Adds a standard easy handle to the multi stack. This function call will make Adds a standard easy handle to the multi stack. This function call will make
this \fImulti_handle\fP control the specified \fIeasy_handle\fP. Furthermore, this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
libcurl now initiates the connection associated with the specified
\fIeasy_handle\fP.
While an easy handle is added to a multi stack, you can not and you must not While an easy handle is added to a multi stack, you can not and you must not
use \fIcurl_easy_perform(3)\fP on that handle. After having removed the handle use \fIcurl_easy_perform(3)\fP on that handle. After having removed the easy
from the multi stack again, it is perfectly fine to use it with the easy handle from the multi stack again, it is perfectly fine to use it with the
interface again. easy interface again.
If the easy handle is not set to use a shared (\fICURLOPT_SHARE(3)\fP) or If the easy handle is not set to use a shared (\fICURLOPT_SHARE(3)\fP) or
global DNS cache (\fICURLOPT_DNS_USE_GLOBAL_CACHE(3)\fP), it will be made to global DNS cache (\fICURLOPT_DNS_USE_GLOBAL_CACHE(3)\fP), it will be made to
use the DNS cache that is shared between all easy handles within the multi use the DNS cache that is shared between all easy handles within the multi
handle when \fIcurl_multi_add_handle(3)\fP is called. handle when \fIcurl_multi_add_handle(3)\fP is called.
When an easy interface is added to a multi handle, it will use a shared
connection cache owned by the multi handle. Removing and adding new easy
handles will not affect the pool of connections or the ability to do
connection re-use.
If you have CURLMOPT_TIMERFUNCTION set in the multi handle (and you really If you have CURLMOPT_TIMERFUNCTION set in the multi handle (and you really
should if you're working event-based with \fIcurl_multi_socket_action(3)\fP should if you're working event-based with \fIcurl_multi_socket_action(3)\fP
and friends), that callback will be called from within this function to ask and friends), that callback will be called from within this function to ask
for an updated timer so that your main event loop will get the activity on for an updated timer so that your main event loop will get the activity on
this handle to get started. this handle to get started.
The easy handle will remain added until you remove it again with The easy handle will remain added to the multi handle until you remove it
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the again with \fIcurl_multi_remove_handle(3)\fP - even when a transfer with that
multi stack before you terminate first the easy handle and then the multi specific easy handle is completed.
handle:
You should remove the easy handle from the multi stack before you terminate
first the easy handle and then the multi handle:
1 - \fIcurl_multi_remove_handle(3)\fP 1 - \fIcurl_multi_remove_handle(3)\fP
@ -62,4 +67,5 @@ handle:
.SH RETURN VALUE .SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" .BR curl_multi_cleanup "(3)," curl_multi_init "(3), "
.BR curl_multi_setopt "(3), " curl_multi_socket_action "(3) "

View File

@ -21,7 +21,7 @@
.\" ************************************************************************** .\" **************************************************************************
.TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual" .TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
.SH NAME .SH NAME
curl_multi_assign \- set data to association with an internal socket curl_multi_assign \- set data to associate with an internal socket
.SH SYNOPSIS .SH SYNOPSIS
#include <curl/curl.h> #include <curl/curl.h>
@ -30,7 +30,7 @@ CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd,
.SH DESCRIPTION .SH DESCRIPTION
This function creates an association in the multi handle between the given This function creates an association in the multi handle between the given
socket and a private pointer of the application. This is designed for socket and a private pointer of the application. This is designed for
\fIcurl_multi_socket(3)\fP uses. \fIcurl_multi_socket_action(3)\fP uses.
When set, the \fIsockptr\fP pointer will be passed to all future socket When set, the \fIsockptr\fP pointer will be passed to all future socket
callbacks for the specific \fIsockfd\fP socket. callbacks for the specific \fIsockfd\fP socket.

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -34,7 +34,7 @@ in an non-blocking fashion.
When an application has found out there's data available for the multi_handle When an application has found out there's data available for the multi_handle
or a timeout has elapsed, the application should call this function to or a timeout has elapsed, the application should call this function to
read/write whatever there is to read or write right now etc. read/write whatever there is to read or write right now etc.
curl_multi_perform() returns as soon as the reads/writes are done. This \fIcurl_multi_perform(3)\fP returns as soon as the reads/writes are done. This
function does not require that there actually is any data available for function does not require that there actually is any data available for
reading or that data can be written, it can be called just in case. It will reading or that data can be written, it can be called just in case. It will
write the number of handles that still transfer data in the second argument's write the number of handles that still transfer data in the second argument's
@ -53,7 +53,7 @@ there is no longer any transfers in progress.
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this
basically means that you should call \fIcurl_multi_perform\fP again, before basically means that you should call \fIcurl_multi_perform(3)\fP again, before
you select() on more actions. You don't have to do it immediately, but the you select() on more actions. You don't have to do it immediately, but the
return code means that libcurl may have more data available to return or that return code means that libcurl may have more data available to return or that
there may be more data to send off before it is "satisfied". Do note that there may be more data to send off before it is "satisfied". Do note that

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * .\" *
.\" * This software is licensed as described in the file COPYING, which .\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms .\" * you should have received as part of this distribution. The terms
@ -28,16 +28,17 @@ curl_multi_remove_handle - remove an easy handle from a multi session
CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle); CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle);
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
Removes a given easy_handle from the multi_handle. This will make the Removes a given \fIeasy_handle\fI from the \fImulti_handle\fI. This will make
specified easy handle be removed from this multi handle's control. the specified easy handle be removed from this multi handle's control.
When the easy handle has been removed from a multi stack, it is again When the easy handle has been removed from a multi stack, it is again
perfectly legal to invoke \fIcurl_easy_perform()\fP on this easy handle. perfectly legal to invoke \fIcurl_easy_perform(3)\fP on this easy handle.
Removing an easy handle while being used, will effectively halt the transfer Removing an easy handle while being used is perfectly legal and will
in progress involving that easy handle. All other easy handles and transfers effectively halt the transfer in progress involving that easy handle. All
will remain unaffected. other easy handles and transfers will remain unaffected.
.SH RETURN VALUE .SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code. CURLMcode type, general libcurl multi interface error code.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_multi_cleanup "(3)," curl_multi_init "(3)" .BR curl_multi_cleanup "(3)," curl_multi_init "(3), "
.BR curl_multi_add_handle "(3) "

View File

@ -79,7 +79,103 @@ NULL
.SH PROTOCOLS .SH PROTOCOLS
All All
.SH EXAMPLE .SH EXAMPLE
http://curl.haxx.se/libcurl/c/debug.html .nf
static
void dump(const char *text,
FILE *stream, unsigned char *ptr, size_t size)
{
size_t i;
size_t c;
unsigned int width=0x10;
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
text, (long)size, (long)size);
for(i=0; i<size; i+= width) {
fprintf(stream, "%4.4lx: ", (long)i);
/* show hex to the left */
for(c = 0; c < width; c++) {
if(i+c < size)
fprintf(stream, "%02x ", ptr[i+c]);
else
fputs(" ", stream);
}
/* show data on the right */
for(c = 0; (c < width) && (i+c < size); c++)
fputc(ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.', stream);
fputc('\n', stream); /* newline */
}
}
static
int my_trace(CURL *handle, curl_infotype type,
char *data, size_t size,
void *userp)
{
const char *text;
(void)handle; /* prevent compiler warning */
switch (type) {
case CURLINFO_TEXT:
fprintf(stderr, "== Info: %s", data);
default: /* in case a new one is introduced to shock us */
return 0;
case CURLINFO_HEADER_OUT:
text = "=> Send header";
break;
case CURLINFO_DATA_OUT:
text = "=> Send data";
break;
case CURLINFO_SSL_DATA_OUT:
text = "=> Send SSL data";
break;
case CURLINFO_HEADER_IN:
text = "<= Recv header";
break;
case CURLINFO_DATA_IN:
text = "<= Recv data";
break;
case CURLINFO_SSL_DATA_IN:
text = "<= Recv SSL data";
break;
}
dump(text, stderr, (unsigned char *)data, size);
return 0;
}
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
/* the DEBUGFUNCTION has no effect until we enable VERBOSE */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
.fi
.SH AVAILABILITY .SH AVAILABILITY
Always Always
.SH RETURN VALUE .SH RETURN VALUE

View File

@ -48,10 +48,25 @@ NULL
.SH PROTOCOLS .SH PROTOCOLS
All All
.SH EXAMPLE .SH EXAMPLE
TODO .nf
curl = curl_easy_init();
if(curl) {
char error[CURL_ERROR_SIZE]
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* provide a buffer to store errors in */
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
/* Perform the request */
curl_easy_perform(curl);
}
.fi
.SH AVAILABILITY .SH AVAILABILITY
Always Always
.SH RETURN VALUE .SH RETURN VALUE
Returns CURLE_OK Returns CURLE_OK
.SH "SEE ALSO" .SH "SEE ALSO"
.BR CURLOPT_DEBUGFUNCTION "(3), " CURLOPT_VERBOSE "(3), " .BR CURLOPT_DEBUGFUNCTION "(3), " CURLOPT_VERBOSE "(3), "
.BR curl_easy_strerror "(3), " curl_multi_strerror "(3), "
.BR curl_share_strerror "(3) "

View File

@ -88,4 +88,4 @@ Added in 7.19.4
.SH RETURN VALUE .SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not. Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR CURLOPT_REDIR_PROTOCOLS "(3), " .BR CURLOPT_REDIR_PROTOCOLS "(3), " CURLOPT_URL "(3), "