\fI marked \fP more function calls etc.

This commit is contained in:
Daniel Stenberg 2005-01-22 22:43:04 +00:00
parent 95656cd7f3
commit 53143910a1
1 changed files with 89 additions and 87 deletions

View File

@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___ .\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____| .\" * \___|\___/|_| \_\_____|
.\" * .\" *
.\" * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. .\" * Copyright (C) 1998 - 2005, 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
@ -21,7 +21,7 @@
.\" * $Id$ .\" * $Id$
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH libcurl-tutorial 3 "18 Jun 2004" "libcurl" "libcurl programming" .TH libcurl-tutorial 3 "22 Jan 2005" "libcurl" "libcurl programming"
.SH NAME .SH NAME
libcurl-tutorial \- libcurl programming tutorial libcurl-tutorial \- libcurl programming tutorial
.SH "Objective" .SH "Objective"
@ -94,9 +94,9 @@ use the library. Once for your program's entire life time. This is done using
curl_global_init() curl_global_init()
and it takes one parameter which is a bit pattern that tells libcurl what to and it takes one parameter which is a bit pattern that tells libcurl what to
initialize. Using CURL_GLOBAL_ALL will make it initialize all known internal initialize. Using \fICURL_GLOBAL_ALL\fP will make it initialize all known
sub modules, and might be a good default option. The current two bits that internal sub modules, and might be a good default option. The current two bits
are specified are: that are specified are:
.RS .RS
.IP "CURL_GLOBAL_WIN32" .IP "CURL_GLOBAL_WIN32"
which only does anything on Windows machines. When used on which only does anything on Windows machines. When used on
@ -113,17 +113,19 @@ application so if your program or another library already does this, this
bit should not be needed. bit should not be needed.
.RE .RE
libcurl has a default protection mechanism that detects if curl_global_init() libcurl has a default protection mechanism that detects if
hasn't been called by the time curl_easy_perform() is called and if that is \fIcurl_global_init(3)\fP hasn't been called by the time
the case, libcurl runs the function itself with a guessed bit pattern. Please \fIcurl_easy_perform(3)\fP is called and if that is the case, libcurl runs the
note that depending solely on this is not considered nice nor very good. function itself with a guessed bit pattern. Please note that depending solely
on this is not considered nice nor very good.
When the program no longer uses libcurl, it should call curl_global_cleanup(), When the program no longer uses libcurl, it should call
which is the opposite of the init call. It will then do the reversed \fIcurl_global_cleanup(3)\fP, which is the opposite of the init call. It will
operations to cleanup the resources the curl_global_init() call initialized. then do the reversed operations to cleanup the resources the
\fIcurl_global_init(3)\fP call initialized.
Repeated calls to curl_global_init() and curl_global_cleanup() should be Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP
avoided. They should only be called once each. should be avoided. They should only be called once each.
.SH "Features libcurl Provides" .SH "Features libcurl Provides"
It is considered best-practice to determine libcurl features run-time rather It is considered best-practice to determine libcurl features run-time rather
@ -153,17 +155,18 @@ It returns an easy handle. Using that you proceed to the next step: setting
up your preferred actions. A handle is just a logic entity for the upcoming up your preferred actions. A handle is just a logic entity for the upcoming
transfer or series of transfers. transfer or series of transfers.
You set properties and options for this handle using curl_easy_setopt(). They You set properties and options for this handle using
control how the subsequent transfer or transfers will be made. Options remain \fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or
set in the handle until set again to something different. Alas, multiple transfers will be made. Options remain set in the handle until set again to
requests using the same handle will use the same options. something different. Alas, multiple requests using the same handle will use
the same options.
Many of the options you set in libcurl are "strings", pointers to data Many of the options you set in libcurl are "strings", pointers to data
terminated with a zero byte. Keep in mind that when you set strings with terminated with a zero byte. Keep in mind that when you set strings with
curl_easy_setopt(), libcurl will not copy the data. It will merely point to \fIcurl_easy_setopt(3)\fP, libcurl will not copy the data. It will merely
the data. You MUST make sure that the data remains available for libcurl to point to the data. You MUST make sure that the data remains available for
use until finished or until you use the same option again to point to libcurl to use until finished or until you use the same option again to point
something else. to something else.
One of the most basic properties to set in the handle is the URL. You set One of the most basic properties to set in the handle is the URL. You set
your preferred URL to transfer with CURLOPT_URL in a manner similar to: your preferred URL to transfer with CURLOPT_URL in a manner similar to:
@ -188,11 +191,11 @@ similar to this:
You can control what data your function get in the forth argument by setting You can control what data your function get in the forth argument by setting
another property: another property:
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct); curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
Using that property, you can easily pass local data between your application Using that property, you can easily pass local data between your application
and the function that gets invoked by libcurl. libcurl itself won't touch the and the function that gets invoked by libcurl. libcurl itself won't touch the
data you pass with CURLOPT_WRITEDATA. data you pass with \fICURLOPT_WRITEDATA\fP.
libcurl offers its own default internal callback that'll take care of the data libcurl offers its own default internal callback that'll take care of the data
if you don't set the callback with \fICURLOPT_WRITEFUNCTION\fP. It will then if you don't set the callback with \fICURLOPT_WRITEFUNCTION\fP. It will then
@ -219,14 +222,13 @@ of them later. Let's instead continue to the actual transfer:
success = curl_easy_perform(easyhandle); success = curl_easy_perform(easyhandle);
The \fIcurl_easy_perform(3)\fP will connect to the remote site, do the \fIcurl_easy_perform(3)\fP will connect to the remote site, do the necessary
necessary commands and receive the transfer. Whenever it receives data, it commands and receive the transfer. Whenever it receives data, it calls the
calls the callback function we previously set. The function may get one byte callback function we previously set. The function may get one byte at a time,
at a time, or it may get many kilobytes at once. libcurl delivers as much as or it may get many kilobytes at once. libcurl delivers as much as possible as
possible as often as possible. Your callback function should return the number often as possible. Your callback function should return the number of bytes it
of bytes it "took care of". If that is not the exact same amount of bytes that \&"took care of". If that is not the exact same amount of bytes that was
was passed to it, libcurl will abort the operation and return with an error passed to it, libcurl will abort the operation and return with an error code.
code.
When the transfer is complete, the function returns a return code that informs When the transfer is complete, the function returns a return code that informs
you if it succeeded in its mission or not. If a return code isn't enough for you if it succeeded in its mission or not. If a return code isn't enough for
@ -240,12 +242,12 @@ previous
.SH "Multi-threading Issues" .SH "Multi-threading Issues"
libcurl is completely thread safe, except for two issues: signals and alarm libcurl is completely thread safe, except for two issues: signals and alarm
handlers. Signals are needed for a SIGPIPE handler, and the alarm() Bacall handlers. Signals are needed for a SIGPIPE handler, and the alarm() call is
is used to catch timeouts (mostly during ENS lookup). used to deal with timeouts (during DNS lookup).
If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
then of course using OpenSSL multi-threaded and it has itself a few then of course using OpenSSL multi-threaded and it has itself a few
requirements on this. Basilio, you need to provide one or two functions to requirements on this. Basically, you need to provide one or two functions to
allow it to function properly. For all details, see this: allow it to function properly. For all details, see this:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
@ -326,12 +328,12 @@ CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]:
curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size); curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
.fi .fi
When you call curl_easy_perform() this time, it'll perform all the necessary When you call \fIcurl_easy_perform(3)\fP this time, it'll perform all the
operations and when it has invoked the upload it'll call your supplied necessary operations and when it has invoked the upload it'll call your
callback to get the data to upload. The program should return as much data as supplied callback to get the data to upload. The program should return as much
possible in every invoke, as that is likely to make the upload perform as data as possible in every invoke, as that is likely to make the upload perform
fast as possible. The callback should return the number of bytes it wrote in as fast as possible. The callback should return the number of bytes it wrote
the buffer. Returning 0 will signal the end of the upload. in the buffer. Returning 0 will signal the end of the upload.
.SH "Passwords" .SH "Passwords"
Many protocols use or even require that user name and password are provided Many protocols use or even require that user name and password are provided
@ -470,15 +472,14 @@ then passing that list to libcurl.
While the simple examples above cover the majority of all cases where HTTP While the simple examples above cover the majority of all cases where HTTP
POST operations are required, they don't do multi-part formposts. Multi-part POST operations are required, they don't do multi-part formposts. Multi-part
formposts were introduced as a better way to post (possibly large) binary formposts were introduced as a better way to post (possibly large) binary data
data and was first documented in the RFC1867. They're called multi-part and was first documented in the RFC1867. They're called multi-part because
because they're built by a chain of parts, each being a single unit. Each they're built by a chain of parts, each being a single unit. Each part has its
part has its own name and contents. You can in fact create and post a own name and contents. You can in fact create and post a multi-part formpost
multi-part formpost with the regular libcurl POST support described above, but with the regular libcurl POST support described above, but that would require
that would require that you build a formpost yourself and provide to that you build a formpost yourself and provide to libcurl. To make that
libcurl. To make that easier, libcurl provides curl_formadd(). Using this easier, libcurl provides \fIcurl_formadd(3)\fP. Using this function, you add
function, you add parts to the form. When you're done adding parts, you post parts to the form. When you're done adding parts, you post the whole form.
the whole form.
The following example sets two simple text parts with plain textual contents, The following example sets two simple text parts with plain textual contents,
and then a file with binary contents and upload the whole thing. and then a file with binary contents and upload the whole thing.
@ -531,10 +532,10 @@ post handle:
.fi .fi
Since all options on an easyhandle are "sticky", they remain the same until Since all options on an easyhandle are "sticky", they remain the same until
changed even if you do call curl_easy_perform(), you may need to tell curl to changed even if you do call \fIcurl_easy_perform(3)\fP, you may need to tell
go back to a plain GET request if you intend to do such a one as your next curl to go back to a plain GET request if you intend to do such a one as your
request. You force an easyhandle to back to GET by using the CURLOPT_HTTPGET next request. You force an easyhandle to back to GET by using the
option: CURLOPT_HTTPGET option:
curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, TRUE); curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, TRUE);
@ -723,7 +724,7 @@ Mozilla javascript engine in the past.
Re-cycling the same easy handle several times when doing multiple requests is Re-cycling the same easy handle several times when doing multiple requests is
the way to go. the way to go.
After each single curl_easy_perform() operation, libcurl will keep the After each single \fIcurl_easy_perform(3)\fP operation, libcurl will keep the
connection alive and open. A subsequent request using the same easy handle to connection alive and open. A subsequent request using the same easy handle to
the same host might just be able to use the already open connection! This the same host might just be able to use the already open connection! This
reduces network impact a lot. reduces network impact a lot.
@ -907,8 +908,8 @@ A little example that deletes a given file before an operation:
.fi .fi
If you would instead want this operation (or chain of operations) to happen If you would instead want this operation (or chain of operations) to happen
_after_ the data transfer took place the option to curl_easy_setopt() would _after_ the data transfer took place the option to \fIcurl_easy_setopt(3)\fP
instead be called CURLOPT_POSTQUOTE and used the exact same way. would instead be called CURLOPT_POSTQUOTE and used the exact same way.
The custom FTP command will be issued to the server in the same order they are The custom FTP command will be issued to the server in the same order they are
added to the list, and if a command gets an error code returned back from the added to the list, and if a command gets an error code returned back from the
@ -977,9 +978,9 @@ The perhaps most advanced cookie operation libcurl offers, is saving the
entire internal cookie state back into a Netscape/Mozilla formatted cookie entire internal cookie state back into a Netscape/Mozilla formatted cookie
file. We call that the cookie-jar. When you set a file name with file. We call that the cookie-jar. When you set a file name with
CURLOPT_COOKIEJAR, that file name will be created and all received cookies CURLOPT_COOKIEJAR, that file name will be created and all received cookies
will be stored in it when curl_easy_cleanup() is called. This enabled cookies will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enabled
to get passed on properly between multiple handles without any information cookies to get passed on properly between multiple handles without any
getting lost. information getting lost.
.SH "FTP Peculiarities We Need" .SH "FTP Peculiarities We Need"
@ -1107,46 +1108,47 @@ 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 in to multiple transfers at the same time, by adding up multiple easy handles in to
a "multi stack". a "multi stack".
You create the easy handles you want and you set all the options just like You create the easy handles you want and you set all the options just like you
you have been told above, and then you create a multi handle with have been told above, and then you create a multi handle with
curl_multi_init() and add all those easy handles to that multi handle with \fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle
curl_multi_add_handle(). with \fIcurl_multi_add_handle(3)\fP.
When you've added the handles you have for the moment (you can still add new 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 call curl_multi_perform(). ones at any time), you start the transfers by call
\fIcurl_multi_perform(3)\fP.
curl_multi_perform() is asynchronous. It will only execute as little as \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 possible and then return back control to your program. It is designed to never
never block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again soon,
soon, as that is a signal that it still has local data to send or remote data as that is a signal that it still has local data to send or remote data to
to receive. receive.
The best usage of this interface is when you do a select() on all possible 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 file descriptors or sockets to know when to call libcurl again. This also
makes it easy for you to wait and respond to actions on your own makes it easy for you to wait and respond to actions on your own application's
application's sockets/handles. You figure out what to select() for by using sockets/handles. You figure out what to select() for by using
curl_multi_fdset(), that fills in a set of fd_set variables for you with the \fIcurl_multi_fdset(3)\fP, that fills in a set of fd_set variables for you
particular file descriptors libcurl uses for the moment. with the particular file descriptors libcurl uses for the moment.
When you then call select(), it'll return when one of the file handles signal When you then call select(), it'll return when one of the file handles signal
action and you then call curl_multi_perform() to allow libcurl to do what it action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
wants to do. Take note that libcurl does also feature some time-out code so what it wants to do. Take note that libcurl does also feature some time-out
we advice you to never use very long timeouts on select() before you call code so we advice you to never use very long timeouts on select() before you
curl_multi_perform(), which thus should be called unconditionally every now call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally
and then even if none of its file descriptors have signaled ready. Another every now and then even if none of its file descriptors have signaled
precaution you should use: always call curl_multi_fdset() immediately before ready. Another precaution you should use: always call
the select() call since the current set of file descriptors may change when \fIcurl_multi_fdset(3)\fP immediately before the select() call since the
calling a curl function. current set of file descriptors may change when calling a curl function.
If you want to stop the transfer of one of the easy handles in the stack, you If you want to stop the transfer of one of the easy handles in the stack, you
can use curl_multi_remove_handle() to remove individual easy can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy
handles. Remember that easy handles should be curl_easy_cleanup()ed. handles. Remember that easy handles should be \fIcurl_easy_cleanup(3)\fPed.
When a transfer within the multi stack has finished, the counter of running When a transfer within the multi stack has finished, the counter of running
transfers (as filled in by curl_multi_perform()) will decrease. When the transfers (as filled in by \fIcurl_multi_perform(3)\fP) will decrease. When
number reaches zero, all transfers are done. the number reaches zero, all transfers are done.
curl_multi_info_read() can be used to get information about completed \fIcurl_multi_info_read(3)\fP can be used to get information about completed
transfers. It then returns the CURLcode for each easy transfer, to allow you transfers. It then returns the CURLcode for each easy transfer, to allow you
to figure out success on each individual transfer. to figure out success on each individual transfer.