aboutsummaryrefslogtreecommitdiff
path: root/docs/libcurl
diff options
context:
space:
mode:
Diffstat (limited to 'docs/libcurl')
-rw-r--r--docs/libcurl/curl_easy_cleanup.326
-rw-r--r--docs/libcurl/curl_easy_init.325
-rw-r--r--docs/libcurl/curl_easy_setopt.323
-rw-r--r--docs/libcurl/curl_easy_strerror.39
-rw-r--r--docs/libcurl/curl_free.34
-rw-r--r--docs/libcurl/curl_multi_add_handle.328
-rw-r--r--docs/libcurl/curl_multi_assign.34
-rw-r--r--docs/libcurl/curl_multi_perform.36
-rw-r--r--docs/libcurl/curl_multi_remove_handle.317
-rw-r--r--docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.398
-rw-r--r--docs/libcurl/opts/CURLOPT_ERRORBUFFER.317
-rw-r--r--docs/libcurl/opts/CURLOPT_PROTOCOLS.32
12 files changed, 189 insertions, 70 deletions
diff --git a/docs/libcurl/curl_easy_cleanup.3 b/docs/libcurl/curl_easy_cleanup.3
index d8a3f9fcf..8d8375b62 100644
--- a/docs/libcurl/curl_easy_cleanup.3
+++ b/docs/libcurl/curl_easy_cleanup.3
@@ -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
.\" * 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"
.SH NAME
-curl_easy_cleanup - End a libcurl easy session
+curl_easy_cleanup - End a libcurl easy handle
.SH SYNOPSIS
.B #include <curl/curl.h>
.BI "void curl_easy_cleanup(CURL *" handle ");"
-
.SH DESCRIPTION
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
-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
-has kept open until now. Don't call this function if you intend to transfer
-more files.
+This might close all connections this handle has used and possibly has kept
+open until now - unless it was attached to a multi handle while doing the
+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
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
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
-returned, are illegal. This kills the handle and all memory associated with
-it!
+Any use of the \fBhandle\fP after this function has been called and have
+returned, is illegal. \fIcurl_easy_cleanup(3)\fP kills the handle and all
+memory associated with it!
-With libcurl versions prior to 7.17.: when you've called this, you can safely
-remove all the strings you've previously told libcurl to use, as it won't use
-them anymore now.
+For libcurl versions before 7.17,: after you've called this function, you can
+safely remove all the strings you've previously told libcurl to use, as it
+won't use them anymore now.
.SH RETURN VALUE
None
.SH "SEE ALSO"
diff --git a/docs/libcurl/curl_easy_init.3 b/docs/libcurl/curl_easy_init.3
index 837ba32a5..f85abdd31 100644
--- a/docs/libcurl/curl_easy_init.3
+++ b/docs/libcurl/curl_easy_init.3
@@ -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
.\" * 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>
.BI "CURL *curl_easy_init( );"
-
.SH DESCRIPTION
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
-initializes curl and this call \fBMUST\fP have a corresponding call to
+handle that you must use as input to other functions in the easy
+interface. This call \fBMUST\fP have a corresponding call to
\fIcurl_easy_cleanup(3)\fP when the operation is complete.
-If you did not already call \fIcurl_global_init(3)\fP,
-\fIcurl_easy_init(3)\fP does it automatically.
-This may be lethal in multi-threaded cases, since \fIcurl_global_init(3)\fP is
-not thread-safe, and it may result in resource problems because there is
-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.
+If you did not already call \fIcurl_global_init(3)\fP, \fIcurl_easy_init(3)\fP
+does it automatically. This may be lethal in multi-threaded cases, since
+\fIcurl_global_init(3)\fP is not thread-safe, and it may result in resource
+problems because there is 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.
.SH RETURN VALUE
If this function returns NULL, something went wrong and you cannot use the
other curl functions.
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 17871dd5f..bfdb8a9ee 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -28,14 +28,14 @@ curl_easy_setopt \- set options for a curl easy handle
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
.SH DESCRIPTION
-curl_easy_setopt() is used to tell libcurl how to behave. By using the
-appropriate options to \fIcurl_easy_setopt\fP, you can change libcurl's
-behavior. All options are set with the \fIoption\fP followed by a
-\fIparameter\fP. That parameter can be a \fBlong\fP, a \fBfunction pointer\fP,
-an \fBobject pointer\fP or a \fBcurl_off_t\fP, depending on what the specific
-option expects. Read this manual carefully as bad input values may cause
-libcurl to behave badly! You can only set one option in each function call. A
-typical application uses many curl_easy_setopt() calls in the setup phase.
+\fIcurl_easy_setopt(3)\fP is used to tell libcurl how to behave. By setting
+the appropriate options, the application can change libcurl's behavior. All
+options are set with an \fIoption\fP followed by a \fIparameter\fP. That
+parameter can be a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject
+pointer\fP or a \fBcurl_off_t\fP, depending on what the specific option
+expects. Read this manual carefully as bad input values may cause libcurl to
+behave badly! You can only set one option in each function call. A typical
+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
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;
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
-\fICURLOPT_POSTFIELDS(3)\fP, but the alternative that copies the string
+after \fIcurl_easy_setopt(3)\fP returns. The only exception to this rule is
+really \fICURLOPT_POSTFIELDS(3)\fP, but the alternative that copies the string
\fICURLOPT_COPYPOSTFIELDS(3)\fP has some usage characteristics you need to
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
\fICURLE_NOT_BUILT_IN\fP.
.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), "
diff --git a/docs/libcurl/curl_easy_strerror.3 b/docs/libcurl/curl_easy_strerror.3
index a26c9c5db..557d46768 100644
--- a/docs/libcurl/curl_easy_strerror.3
+++ b/docs/libcurl/curl_easy_strerror.3
@@ -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
.\" * 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);
.SH DESCRIPTION
-The curl_easy_strerror() function returns a string describing the CURLcode
-error code passed in the argument \fIerrornum\fP.
+The \fIcurl_easy_strerror(3)\fP function returns a string describing the
+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
This function was added in libcurl 7.12.0
.SH RETURN VALUE
diff --git a/docs/libcurl/curl_free.3 b/docs/libcurl/curl_free.3
index a908808d6..9e5570fa4 100644
--- a/docs/libcurl/curl_free.3
+++ b/docs/libcurl/curl_free.3
@@ -29,7 +29,7 @@ curl_free - reclaim memory that has been obtained through a libcurl call
.ad
.SH DESCRIPTION
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.
.SH "SEE ALSO"
-.BR curl_unescape "(3)"
+.BR curl_easy_unescape "(3), " curl_easy_escape "(3) "
diff --git a/docs/libcurl/curl_multi_add_handle.3 b/docs/libcurl/curl_multi_add_handle.3
index 31c422ec3..253b864bb 100644
--- a/docs/libcurl/curl_multi_add_handle.3
+++ b/docs/libcurl/curl_multi_add_handle.3
@@ -29,30 +29,35 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad
.SH DESCRIPTION
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,
-libcurl now initiates the connection associated with the specified
-\fIeasy_handle\fP.
+this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
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
-from the multi stack again, it is perfectly fine to use it with the easy
-interface again.
+use \fIcurl_easy_perform(3)\fP on that handle. After having removed the easy
+handle from the multi stack again, it is perfectly fine to use it with the
+easy interface again.
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
use the DNS cache that is shared between all easy handles within the multi
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
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
for an updated timer so that your main event loop will get the activity on
this handle to get started.
-The easy handle will remain added until you remove it again with
-\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
-multi stack before you terminate first the easy handle and then the multi
-handle:
+The easy handle will remain added to the multi handle until you remove it
+again with \fIcurl_multi_remove_handle(3)\fP - even when a transfer with that
+specific easy handle is completed.
+
+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
@@ -62,4 +67,5 @@ handle:
.SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code.
.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) "
diff --git a/docs/libcurl/curl_multi_assign.3 b/docs/libcurl/curl_multi_assign.3
index 6c0bbae81..0a2378de3 100644
--- a/docs/libcurl/curl_multi_assign.3
+++ b/docs/libcurl/curl_multi_assign.3
@@ -21,7 +21,7 @@
.\" **************************************************************************
.TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
.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
#include <curl/curl.h>
@@ -30,7 +30,7 @@ CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd,
.SH DESCRIPTION
This function creates an association in the multi handle between the given
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
callbacks for the specific \fIsockfd\fP socket.
diff --git a/docs/libcurl/curl_multi_perform.3 b/docs/libcurl/curl_multi_perform.3
index 304197b1a..d85dc46bc 100644
--- a/docs/libcurl/curl_multi_perform.3
+++ b/docs/libcurl/curl_multi_perform.3
@@ -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
.\" * 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
or a timeout has elapsed, the application should call this function to
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
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
@@ -53,7 +53,7 @@ there is no longer any transfers in progress.
CURLMcode type, general libcurl multi interface error code.
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
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
diff --git a/docs/libcurl/curl_multi_remove_handle.3 b/docs/libcurl/curl_multi_remove_handle.3
index ad6d2bac8..1c2165b63 100644
--- a/docs/libcurl/curl_multi_remove_handle.3
+++ b/docs/libcurl/curl_multi_remove_handle.3
@@ -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
.\" * 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);
.ad
.SH DESCRIPTION
-Removes a given easy_handle from the multi_handle. This will make the
-specified easy handle be removed from this multi handle's control.
+Removes a given \fIeasy_handle\fI from the \fImulti_handle\fI. This will make
+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
-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
-in progress involving that easy handle. All other easy handles and transfers
-will remain unaffected.
+Removing an easy handle while being used is perfectly legal and will
+effectively halt the transfer in progress involving that easy handle. All
+other easy handles and transfers will remain unaffected.
.SH RETURN VALUE
CURLMcode type, general libcurl multi interface error code.
.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) "
diff --git a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3 b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
index 984e39402..6c4721b7d 100644
--- a/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
+++ b/docs/libcurl/opts/CURLOPT_DEBUGFUNCTION.3
@@ -79,7 +79,103 @@ NULL
.SH PROTOCOLS
All
.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
Always
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3 b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3
index d74372376..577202cfc 100644
--- a/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3
+++ b/docs/libcurl/opts/CURLOPT_ERRORBUFFER.3
@@ -48,10 +48,25 @@ NULL
.SH PROTOCOLS
All
.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
Always
.SH RETURN VALUE
Returns CURLE_OK
.SH "SEE ALSO"
.BR CURLOPT_DEBUGFUNCTION "(3), " CURLOPT_VERBOSE "(3), "
+.BR curl_easy_strerror "(3), " curl_multi_strerror "(3), "
+.BR curl_share_strerror "(3) "
diff --git a/docs/libcurl/opts/CURLOPT_PROTOCOLS.3 b/docs/libcurl/opts/CURLOPT_PROTOCOLS.3
index f3c63a9f6..c5bbc28eb 100644
--- a/docs/libcurl/opts/CURLOPT_PROTOCOLS.3
+++ b/docs/libcurl/opts/CURLOPT_PROTOCOLS.3
@@ -88,4 +88,4 @@ Added in 7.19.4
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
-.BR CURLOPT_REDIR_PROTOCOLS "(3), "
+.BR CURLOPT_REDIR_PROTOCOLS "(3), " CURLOPT_URL "(3), "