From 3ef73d9a88fcea534f6a1d667e456fdc74fb7b9b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 19 Sep 2014 15:07:58 +0200 Subject: [PATCH] libcurl docs: improvements all over --- docs/libcurl/curl_easy_duphandle.3 | 7 ++- docs/libcurl/curl_easy_reset.3 | 5 +- docs/libcurl/libcurl-easy.3 | 18 +++++-- docs/libcurl/libcurl-multi.3 | 69 ++++++++++++++++++------- docs/libcurl/libcurl-tutorial.3 | 83 +++++++++++++++++------------- 5 files changed, 119 insertions(+), 63 deletions(-) diff --git a/docs/libcurl/curl_easy_duphandle.3 b/docs/libcurl/curl_easy_duphandle.3 index e53ced48b1c8a2..080723a1b98298 100644 --- a/docs/libcurl/curl_easy_duphandle.3 +++ b/docs/libcurl/curl_easy_duphandle.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -19,7 +19,7 @@ .\" * KIND, either express or implied. .\" * .\" ************************************************************************** -.TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual" +.TH curl_easy_duphandle 3 "19 Sep 2014" "libcurl" "libcurl Manual" .SH NAME curl_easy_duphandle - Clone a libcurl session handle .SH SYNOPSIS @@ -47,5 +47,4 @@ in a synchronous way, the input handle may not be in use when cloned. If this function returns NULL, something went wrong and no valid handle was returned. .SH "SEE ALSO" -.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3) - +.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)" diff --git a/docs/libcurl/curl_easy_reset.3 b/docs/libcurl/curl_easy_reset.3 index 592d3ed5c81d51..cb69bddfba4f87 100644 --- a/docs/libcurl/curl_easy_reset.3 +++ b/docs/libcurl/curl_easy_reset.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -39,5 +39,6 @@ This function was added in libcurl 7.12.1 .SH RETURN VALUE Nothing .SH "SEE ALSO" -.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3) +.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)," +.BR curl_easy_duphandle "(3)" diff --git a/docs/libcurl/libcurl-easy.3 b/docs/libcurl/libcurl-easy.3 index 698a4ce720f7f0..9144002c3256a2 100644 --- a/docs/libcurl/libcurl-easy.3 +++ b/docs/libcurl/libcurl-easy.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -19,7 +19,7 @@ .\" * KIND, either express or implied. .\" * .\" ************************************************************************** -.TH libcurl 3 "12 Aug 2003" "libcurl 7.10.7" "libcurl easy interface" +.TH libcurl 3 "19 Sep 2014" "libcurl" "libcurl easy interface" .SH NAME libcurl-easy \- easy interface overview .SH DESCRIPTION @@ -33,6 +33,17 @@ without a specified URL as you may have figured out yourself). You might want to set some callbacks as well that will be called from the library when data is available etc. \fIcurl_easy_setopt(3)\fP is used for all this. +\fICURLOPT_URL(3)\fP is only option you really must set, as otherwise there +can be no transfer. Another commonly used option is \fICURLOPT_VERBOSE(3)\fP +that will help you see what libcurl is doing under the hood, very useful when +debugging for example. The \fIcurl_easy_setopt(3)\fP man page has a full index +of the over 200 available options. + +If you at any point would like to blank all previously set options for a +single easy handle, you can call \fIcurl_easy_reset(3)\fP and you can also +make a clone of an easy handle (with all its set options) using +\fIcurl_easy_duphandle(3)\fP. + When all is setup, you tell libcurl to perform the transfer using \fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't return until it is done (successfully or not). @@ -42,4 +53,5 @@ transfer, or if you're done, cleanup the session by calling \fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't cleanup immediately, but instead run ahead and perform other transfers using the same easy handle. - +.SH "SEE ALSO" +.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)" diff --git a/docs/libcurl/libcurl-multi.3 b/docs/libcurl/libcurl-multi.3 index 2af02996192fd0..2d46d3a0eeafdb 100644 --- a/docs/libcurl/libcurl-multi.3 +++ b/docs/libcurl/libcurl-multi.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -20,7 +20,7 @@ .\" * .\" ************************************************************************** .\" -.TH libcurl-multi 3 "3 Feb 2007" "libcurl 7.16.0" "libcurl multi interface" +.TH libcurl-multi 3 "19 Sep 2014" "libcurl" "libcurl multi interface" .SH NAME libcurl-multi \- how to use the multi interface .SH DESCRIPTION @@ -43,18 +43,28 @@ complicated for the application. 3. Enable the application to wait for action on its own file descriptors and curl's file descriptors simultaneous easily. + +4. Enable event-based handling and scaling transfers up to and beyond +thousands of parallel connections. .SH "ONE MULTI HANDLE MANY EASY HANDLES" To use the multi interface, you must first create a 'multi handle' with \fIcurl_multi_init(3)\fP. This handle is then used as input to all further curl_multi_* functions. -Each single transfer is built up with an easy handle. You must create them, -and setup the appropriate options for each easy handle, as outlined in the -\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP. +With a multi handle and the multi interface you can do any amount of +simultaneous transfers in parallel. Each single transfer is built up around an +easy handle. You must create the easy handles you need, and setup the +appropriate options for each easy handle, as outlined in the \fIlibcurl(3)\fP +man page, using \fIcurl_easy_setopt(3)\fP. + +There are two flavours of the multi interface, the select() oriented one and +the event based one we called multi_socket. You will benefit from reading +through the description of both versions to full understand how they work and +differentiate. We start out with the select() oriented version. -When the easy handle is setup for a transfer, then instead of using -\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers), -you should instead add the easy handle to the multi handle using +When an easy handle is setup for a transfer, then instead of using +\fIcurl_easy_perform(3)\fP like when using the easy interface for transfers, +you should add the easy handle to the multi handle with \fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a \'multi stack\' because of the fact that it may hold a large amount of easy handles. @@ -71,7 +81,8 @@ application drive. You drive the transfers by invoking anything available to transfer. It'll use the callbacks and everything else you have setup in the individual easy handles. It'll transfer data on all current transfers in the multi stack that are ready to transfer anything. It -may be all, it may be none. +may be all, it may be none. When there's nothing more to do for now, it +returns back to the calling application. Your application can acquire knowledge from libcurl when it would like to get invoked to transfer data, so that you don't have to busy-loop and call that @@ -80,7 +91,9 @@ interface using which you can extract fd_sets from libcurl to use in select() or poll() calls in order to get to know when the transfers in the multi stack might need attention. This also makes it very easy for your program to wait for input on your own private file descriptors at the same time or perhaps -timeout every now and then, should you want that. +timeout every now and then, should you want that. \fIcurl_multi_timeout(3)\fP +also helps you with providing a suitable timeout period for your select() +call. \fIcurl_multi_perform(3)\fP stores the number of still running transfers in one of its input arguments, and by reading that you can figure out when all @@ -121,21 +134,39 @@ using large numbers of simultaneous connections. When using this API, you add easy handles to the multi handle just as with the normal multi interface. Then you also set two callbacks with the CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to -\fIcurl_multi_setopt(3)\fP. - -The API is then designed to inform your application about which sockets -libcurl is currently using and for what activities (read and/or write) on -those sockets your application is expected to wait for. - -Your application must then make sure to receive all sockets informed about in -the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given -activity on them. When a socket has the given activity, you call +\fIcurl_multi_setopt(3)\fP. They are two callback functions that libcurl will +call with information about what sockets to wait for, and for what activity, +and what the curret timeout time is - if that expires libcurl should be +notified. + +The multi_socket API is designed to inform your application about which +sockets libcurl is currently using and for what activities (read and/or write) +on those sockets your application is expected to wait for. + +Your application must make sure to receive all sockets informed about in the +CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given activity +on them. When a socket has the given activity, you call \fIcurl_multi_socket_action(3)\fP specifying which socket and action there are. The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that timeout expires, your application should call the \fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout. + +This API is typically used with an event-driven underlying functionality (like +libevent, libev, kqueue, epoll or similar) which which the application +"subscribes" on socket changes. This allows applications and libcurl to much +better scale upward and beyond thousands of simultaneous transfers without +losing performance. + +When you've added your initial set of handles, you call +\fIcurl_multi_socket_action(3)\fP with CURL_SOCKET_TIMEOUT set in the sockfd +argument, and you'll get callbacks call that sets you up and you then continue +to call \fIcurl_multi_socket_action(3)\fP accordingly when you get activity on +the sockets you've been asked to wait on, or if the timeout timer expires. + +You can poll \fIcurl_multi_info_read(3)\fP to see if any transfer has +completed, as it then has a message saying so. .SH "BLOCKING" A few areas in the code are still using blocking code, even when used from the multi interface. While we certainly want and intend for these to get fixed in diff --git a/docs/libcurl/libcurl-tutorial.3 b/docs/libcurl/libcurl-tutorial.3 index bc09215369ff77..73744fb41e8e4a 100644 --- a/docs/libcurl/libcurl-tutorial.3 +++ b/docs/libcurl/libcurl-tutorial.3 @@ -20,7 +20,7 @@ .\" * .\" ************************************************************************** .\" -.TH libcurl-tutorial 3 "2 Aug 2014" "libcurl" "libcurl programming" +.TH libcurl-tutorial 3 "19 Sep 2014" "libcurl" "libcurl programming" .SH NAME libcurl-tutorial \- libcurl programming tutorial .SH "Objective" @@ -137,15 +137,17 @@ rather than at build-time (if possible of course). By calling struct, your program can figure out exactly what the currently running libcurl supports. -.SH "Handle the Easy libcurl" +.SH "Two Interfaces" libcurl first introduced the so called easy interface. All operations in the -easy interface are prefixed with 'curl_easy'. - -Recent libcurl versions also offer the multi interface. More about that -interface, what it is targeted for and how to use it is detailed in a separate -chapter further down. You still need to understand the easy interface first, -so please continue reading for better understanding. - +easy interface are prefixed with 'curl_easy'. The easy interface lets you do +single transfers with a synchronous and blocking function call. + +libcurl also offers another interface that allows multiple simultaneous +transfers in a single thread, the so called multi interface. More about that +interface is detailed in a separate chapter further down. You still need to +understand the easy interface first, so please continue reading for better +understanding. +.SH "Handle the Easy libcurl" To use the easy interface, you must first create yourself an easy handle. You need one handle for each easy session you want to perform. Basically, you should use one handle for every thread you plan to use for transferring. You @@ -162,13 +164,18 @@ transfer or series of transfers. You set properties and options for this handle using \fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or transfers will be made. Options remain set in the handle until set again to -something different. Alas, multiple requests using the same handle will use -the same options. +something different. They are sticky. Multiple requests using the same handle +will use the same options. + +If you at any point would like to blank all previously set options for a +single easy handle, you can call \fIcurl_easy_reset(3)\fP and you can also +make a clone of an easy handle (with all its set options) using +\fIcurl_easy_duphandle(3)\fP. Many of the options you set in libcurl are "strings", pointers to data terminated with a zero byte. When you set strings with -\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't -need to be kept around in your application after being set[4]. +\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't need +to be kept around in your application after being set[4]. One of the most basic properties to set in the handle is the URL. You set your preferred URL to transfer with \fICURLOPT_URL(3)\fP in a manner similar to: @@ -1295,39 +1302,44 @@ To avoid this problem, you must of course use your common sense. Often, you can just edit out the sensitive data or just search/replace your true information with faked data. -.SH "Multiple Transfers Using the multi Interface" - +.SH "The multi Interface" The easy interface as described in detail in this document is a synchronous interface that transfers one file at a time and doesn't return until it is done. The multi interface, on the other hand, allows your program to transfer -multiple files in both directions at the same time, without forcing you -to use multiple threads. The name might make it seem that the multi -interface is for multi-threaded programs, but the truth is almost the -reverse. The multi interface can allow a single-threaded application -to perform the same kinds of multiple, simultaneous transfers that -multi-threaded programs can perform. It allows many of the benefits -of multi-threaded transfers without the complexity of managing and -synchronizing many threads. +multiple files in both directions at the same time, without forcing you to use +multiple threads. The name might make it seem that the multi interface is for +multi-threaded programs, but the truth is almost the reverse. The multi +interface allows a single-threaded application to perform the same kinds of +multiple, simultaneous transfers that multi-threaded programs can perform. It +allows many of the benefits of multi-threaded transfers without the complexity +of managing and synchronizing many threads. + +To complicate matters somewhat more, there are even two versions of the multi +interface. The event based one, also called multi_socket and the "normal one" +designed for using with select(). See the libcurl-multi.3 man page for details +on the multi_socket event based API, this description here is for the select() +oriented one. To use this interface, you are better off if you first understand the basics of how to use the easy interface. The multi interface is simply a way to make multiple transfers at the same time by adding up multiple easy handles into a "multi stack". -You create the easy handles you want and you set all the options just like you -have been told above, and then you create a multi handle with -\fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle -with \fIcurl_multi_add_handle(3)\fP. +You create the easy handles you want, one for each concurrent transfer, and +you set all the options just like you learned above, and then you create a +multi handle with \fIcurl_multi_init(3)\fP and add all those easy handles to +that multi handle with \fIcurl_multi_add_handle(3)\fP. When you've added the handles you have for the moment (you can still add new ones at any time), you start the transfers by calling \fIcurl_multi_perform(3)\fP. -\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as -possible and then return back control to your program. It is designed to never -block. +\fIcurl_multi_perform(3)\fP is asynchronous. It will only perform what can be +done now and then return back control to your program. It is designed to never +block. You need to keep calling the function until all transfers are +completed. The best usage of this interface is when you do a select() on all possible file descriptors or sockets to know when to call libcurl again. This also @@ -1340,11 +1352,12 @@ When you then call select(), it'll return when one of the file handles signal action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do what it wants to do. Take note that libcurl does also feature some time-out code so we advise you to never use very long timeouts on select() before you -call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally -every now and then even if none of its file descriptors have signaled -ready. Another precaution you should use: always call -\fIcurl_multi_fdset(3)\fP immediately before the select() call since the -current set of file descriptors may change when calling a curl function. +call \fIcurl_multi_perform(3)\fP again. \fIcurl_multi_timeout(3)\fP is +provided to help you get a suitable timeout period. + +Another precaution you should use: always call \fIcurl_multi_fdset(3)\fP +immediately before the select() call since the current set of file descriptors +may change in any curl function invoke. If you want to stop the transfer of one of the easy handles in the stack, you can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy