1
Updated for curl 7.9.1 on November 2, 2001
6
\___|\___/|_| \_\_____|
10
The project is split in two. The library and the client. The client part uses
11
the library, but the library is designed to allow other applications to use
14
The largest amount of code and complexity is in the library part.
18
All changes to the sources are committed to the CVS repository as soon as
19
they're somewhat verified to work. Changes shall be commited as independently
20
as possible so that individual changes can be easier spotted and tracked
23
Tagging shall be used extensively, and by the time we release new archives we
24
should tag the sources with a name similar to the released version number.
29
There are a few differences in how to program curl the unix way compared to
30
the Windows way. The four perhaps most notable details are:
32
1. Different function names for socket operations.
34
In curl, this is solved with defines and macros, so that the source looks
35
the same at all places except for the header file that defines them. The
36
macros in use are sclose(), sread() and swrite().
38
2. Windows requires a couple of init calls for the socket stuff.
40
Those must be made by the application that uses libcurl, in curl that means
41
src/main.c has some code #ifdef'ed to do just that.
43
3. The file descriptors for network communication and file operations are
44
not easily interchangable as in unix.
46
We avoid this by not trying any funny tricks on file descriptors.
48
4. When writing data to stdout, Windows makes end-of-lines the DOS way, thus
49
destroying binary data, although you do want that conversion if it is
50
text coming through... (sigh)
52
We set stdout to binary under windows
54
Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All
55
conditionals that deal with features *should* instead be in the format
56
'#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts,
57
we maintain two config-win32.h files (one in lib/ and one in src/) that are
58
supposed to look exactly as a config.h file would have looked like on a
61
Generally speaking: always remember that this will be compiled on dozens of
62
operating systems. Don't walk on the edge.
67
There are plenty of entry points to the library, namely each publicly defined
68
function that libcurl offers to applications. All of those functions are
69
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
70
put in the lib/easy.c file.
72
curl_global_init_() and curl_global_cleanup() should be called by the
73
application to initialize and clean up global stuff in the library. As of
74
today, it can handle the global SSL initing if SSL is enabled and it can init
75
the socket layer on windows machines. libcurl itself has no "global" scope.
77
All printf()-style functions use the supplied clones in lib/mprintf.c. This
78
makes sure we stay absolutely platform independent.
80
curl_easy_init() allocates an internal struct and makes some initializations.
81
The returned handle does not reveal internals. This is the 'SessionHandle'
82
struct which works as an "anchor" struct for all curl_easy functions. All
83
connections performed will get connect-specific data allocated that should be
84
used for things related to particular connections/requests.
86
curl_easy_setopt() takes three arguments, where the option stuff must be
87
passed in pairs: the parameter-ID and the parameter-value. The list of
88
options is documented in the man page. This function mainly sets things in
89
the 'SessionHandle' struct.
91
curl_easy_perform() does a whole lot of things:
93
It starts off in the lib/easy.c file by calling Curl_perform() and the main
94
work then continues in lib/url.c. The flow continues with a call to
95
Curl_connect() to connect to the remote site.
99
... analyzes the URL, it separates the different components and connects to
100
the remote host. This may involve using a proxy and/or using SSL. The
101
Curl_gethost() function in lib/hostip.c is used for looking up host names.
103
When Curl_connect is done, we are connected to the remote site. Then it is
104
time to tell the server to get a document/file. Curl_do() arranges this.
106
This function makes sure there's an allocated and initiated 'connectdata'
107
struct that is used for this particular connection only (although there may
108
be several requests performed on the same connect). A bunch of things are
109
inited/inherited from the SessionHandle struct.
113
Curl_do() makes sure the proper protocol-specific function is called. The
114
functions are named after the protocols they handle. Curl_ftp(),
115
Curl_http(), Curl_dict(), etc. They all reside in their respective files
116
(ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
119
The protocol-specific functions of course deal with protocol-specific
120
negotiations and setup. They have access to the Curl_sendf() (from
121
lib/sendf.c) function to send printf-style formatted data to the remote
122
host and when they're ready to make the actual file transfer they call the
123
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
126
Starting in 7.9.1, if this DO function fails and the connection is being
127
re-used, libcurl will then close this connection, setup a new connection
128
and re-issue the DO request on that. This is because there is no way to be
129
perfectly sure that we have discovered a dead connection before the DO
130
function and thus we might wrongly be re-using a connection that was closed
135
Curl_perform() then calls Transfer() in lib/transfer.c that performs
136
the entire file transfer.
138
During transfer, the progress functions in lib/progress.c are called at a
139
frequent interval (or at the user's choice, a specified callback might get
140
called). The speedcheck functions in lib/speedcheck.c are also used to
141
verify that the transfer is as fast as required.
145
Called after a transfer is done. This function takes care of everything
146
that has to be done after a transfer. This function attempts to leave
147
matters in a state so that Curl_do() should be possible to call again on
148
the same connection (in a persistent connection case). It might also soon
149
be closed with Curl_disconnect().
153
When doing normal connections and transfers, no one ever tries to close any
154
connections so this is not normally called when curl_easy_perform() is
155
used. This function is only used when we are certain that no more transfers
156
is going to be made on the connection. It can be also closed by force, or
157
it can be called to make sure that libcurl doesn't keep too many
158
connections alive at the same time (there's a default amount of 5 but that
159
can be changed with the CURLOPT_MAXCONNECTS option).
161
This function cleans up all resources that are associated with a single
164
Curl_perform() is the function that does the main "connect - do - transfer -
165
done" loop. It loops if there's a Location: to follow.
167
When completed, the curl_easy_cleanup() should be called to free up used
168
resources. It runs Curl_disconnect() on all open connectons.
170
A quick roundup on internal function sequences (many of these call
171
protocol-specific function-pointers):
173
curl_connect - connects to a remote site and does initial connect fluff
174
This also checks for an existing connection to the requested site and uses
175
that one if it is possible.
177
curl_do - starts a transfer
178
curl_transfer() - transfers data
179
curl_done - ends a transfer
181
curl_disconnect - disconnects from a remote site. This is called when the
182
disconnect is really requested, which doesn't necessarily have to be
183
exactly after curl_done in case we want to keep the connection open for
188
HTTP offers a lot and is the protocol in curl that uses the most lines of
189
code. There is a special file (lib/formdata.c) that offers all the multipart
192
base64-functions for user+password stuff (and more) is in (lib/base64.c) and
193
all functions for parsing and sending cookies are found in (lib/cookie.c).
195
HTTPS uses in almost every means the same procedure as HTTP, with only two
196
exceptions: the connect procedure is different and the function used to read
197
or write from the socket is different, although the latter fact is hidden in
198
the source by the use of curl_read() for reading and curl_write() for writing
199
data to the remote server.
201
http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
204
An interesting detail with the HTTP(S) request, is the add_buffer() series of
205
functions we use. They append data to one single buffer, and when the
206
building is done the entire request is sent off in one single write. This is
207
done this way to overcome problems with flawed firewalls and lame servers.
211
The Curl_if2ip() function can be used for getting the IP number of a
212
specified network interface, and it resides in lib/if2ip.c.
214
Curl_ftpsendf() is used for sending FTP commands to the remote server. It was
215
made a separate function to prevent us programmers from forgetting that they
216
must be CRLF terminated. They must also be sent in one single write() to make
217
firewalls and similar happy.
221
The kerberos support is mainly in lib/krb4.c and lib/security.c.
225
Telnet is implemented in lib/telnet.c.
229
The file:// protocol is dealt with in lib/file.c.
233
Everything LDAP is in lib/ldap.c.
237
URL encoding and decoding, called escaping and unescaping in the source code,
238
is found in lib/escape.c.
240
While transfering data in Transfer() a few functions might get
241
used. curl_getdate() in lib/getdate.c is for HTTP date comparisons (and
244
lib/getenv.c offers curl_getenv() which is for reading environment variables
245
in a neat platform independent way. That's used in the client, but also in
246
lib/url.c when checking the proxy environment variables. Note that contrary
247
to the normal unix getenv(), this returns an allocated buffer that must be
250
lib/netrc.c holds the .netrc parser
252
lib/timeval.c features replacement functions for systems that don't have
253
gettimeofday() and a few support functions for timeval convertions.
255
A function named curl_version() that returns the full curl version string is
256
found in lib/version.c.
258
If authentication is requested but no password is given, a getpass_r() clone
259
exists in lib/getpass.c. libcurl offers a custom callback that can be used
260
instead of this, but it doesn't change much to us.
262
Persistent Connections
263
======================
265
The persistent connection support in libcurl requires some considerations on
266
how to do things inside of the library.
268
o The 'SessionHandle' struct returned in the curl_easy_init() call must never
269
hold connection-oriented data. It is meant to hold the root data as well as
270
all the options etc that the library-user may choose.
271
o The 'SessionHandle' struct holds the "connection cache" (an array of
272
pointers to 'connectdata' structs). There's one connectdata struct
273
allocated for each connection that libcurl knows about.
274
o This also enables the 'curl handle' to be reused on subsequent transfers,
275
something that was illegal before libcurl 7.7.
276
o When we are about to perform a transfer with curl_easy_perform(), we first
277
check for an already existing connection in the cache that we can use,
278
otherwise we create a new one and add to the cache. If the cache is full
279
already when we add a new connection, we close one of the present ones. We
280
select which one to close dependent on the close policy that may have been
282
o When the transfer operation is complete, we try to leave the connection
283
open. Particular options may tell us not to, and protocols may signal
284
closure on connections and then we don't keep it open of course.
285
o When curl_easy_cleanup() is called, we close all still opened connections.
287
You do realize that the curl handle must be re-used in order for the
288
persistent connections to work.
293
All symbols used internally in libcurl must use a 'Curl_' prefix if they're
294
used in more than a single file. Single-file symbols must be made static.
295
Public ("exported") symbols must use a 'curl_' prefix. (There are exceptions,
296
but they are to be changed to follow this pattern in future versions.)
298
Return Codes and Informationals
299
===============================
301
I've made things simple. Almost every function in libcurl returns a CURLcode,
302
that must be CURLE_OK if everything is OK or otherwise a suitable error code
303
as the curl/curl.h include file defines. The very spot that detects an error
304
must use the Curl_failf() function to set the human-readable error
307
In aiding the user to understand what's happening and to debug curl usage, we
308
must supply a fair amount of informational messages by using the Curl_infof()
309
function. Those messages are only displayed when the user explicitly asks for
310
them. They are best used when revealing information that isn't otherwise
316
main() resides in src/main.c together with most of the client code.
318
src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
319
display the complete "manual" and the src/urlglob.c file holds the functions
320
used for the URL-"globbing" support. Globbing in the sense that the {} and []
321
expansion stuff is there.
323
The client mostly messes around to setup its 'config' struct properly, then
324
it calls the curl_easy_*() functions of the library and when it gets back
325
control after the curl_easy_perform() it cleans up the library, checks status
328
When the operation is done, the ourWriteOut() function in src/writeout.c may
329
be called to report about the operation. That function is using the
330
curl_easy_getinfo() function to extract useful information from the curl
333
Recent versions may loop and do all this several times if many URLs were
334
specified on the command line or config file.
339
The file lib/memdebug.c contains debug-versions of a few functions. Functions
340
such as malloc, free, fopen, fclose, etc that somehow deal with resources
341
that might give us problems if we "leak" them. The functions in the memdebug
342
system do nothing fancy, they do their normal function and then log
343
information about what they just did. The logged data can then be analyzed
344
after a complete session,
346
memanalyze.pl is the perl script present only present in CVS (not part of the
347
release archives) that analyzes a log file generated by the memdebug
348
system. It detects if resources are allocated but never freed and other kinds
349
of errors related to resource management.
351
Use -DMALLOCDEBUG when compiling to enable memory debugging, this is also
352
switched on by running configure with --enable-debug.
357
Since November 2000, a test suite has evolved. It is placed in its own
358
subdirectory directly off the root in the curl archive tree, and it contains
359
a bunch of scripts and a lot of test case data.
361
The main test script is runtests.pl that will invoke the two servers
362
httpserver.pl and ftpserver.pl before all the test cases are performed. The
363
test suite currently only runs on unix-like platforms.
365
You'll find a complete description of the test case data files in the
368
The test suite automatically detects if curl was built with the memory
369
debugging enabled, and if it was it will detect memory leaks too.
374
There's no magic to this. When you consider everything stable enough to be
375
released, run the 'maketgz' script (using 'make distcheck' will give you a
376
pretty good view on the status of the current sources). maketgz prompts for
377
version number of the client and the library before it creates a release
378
archive. maketgz uses 'make dist' for the actual archive building, why you
379
need to fill in the Makefile.am files properly for which files that should
380
be included in the release archives.