1 Updated for curl 7.7 on March 13, 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 / 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 All printf()-style functions use the supplied clones in lib/mprintf.c. This
73 makes sure we stay absolutely platform independent.
75 curl_easy_init() allocates an internal struct and makes some initializations.
76 The returned handle does not revail internals.
78 curl_easy_setopt() takes a three arguments, where the option stuff must be
79 passed in pairs, the parameter-ID and the parameter-value. The list of
80 options is documented in the man page.
82 curl_easy_perform() does a whole lot of things:
84 It starts off in the lib/easy.c file by calling curl_transfer(), but the main
85 work is lib/url.c. The function first analyzes the URL, it separates the
86 different components and connects to the remote host. This may involve using
87 a proxy and/or using SSL. The Curl_gethost() function in lib/hostip.c is used
88 for looking up host names.
90 When connected, the proper protocol-specific function is called. The
91 functions are named after the protocols they handle. Curl_ftp(), Curl_http(),
92 Curl_dict(), etc. They all reside in their respective files (ftp.c, http.c
95 The protocol-specific functions of course deal with protocol-specific
96 negotiations and setup. They have access to the Curl_sendf() (from
97 lib/sendf.c) function to send printf-style formatted data to the remote host
98 and when they're ready to make the actual file transfer they call the
99 Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
100 returns. Curl_perform() then calls Transfer() in lib/transfer.c that performs
101 the entire file transfer. Curl_perform() is what does the main "connect - do
102 - transfer - done" loop. It loops if there's a Location: to follow.
104 During transfer, the progress functions in lib/progress.c are called at a
105 frequent interval (or at the user's choice, a specified callback might get
106 called). The speedcheck functions in lib/speedcheck.c are also used to verify
107 that the transfer is as fast as required.
109 When completed, the curl_easy_cleanup() should be called to free up used
112 A quick roundup on internal function sequences (many of these call
113 protocol-specific function-pointers):
115 curl_connect - connects to a remote site and does initial connect fluff
116 This also checks for an existing connection to the requested site and uses
117 that one if it is possible.
119 curl_do - starts a transfer
120 curl_transfer() - transfers data
121 curl_done - ends a transfer
123 curl_disconnect - disconnects from a remote site. This is called when the
124 disconnect is really requested, which doesn't necessarily have to be
125 exactly after curl_done in case we want to keep the connection open for
130 HTTP offers a lot and is the protocol in curl that uses the most lines of
131 code. There is a special file (lib/formdata.c) that offers all the multipart
134 base64-functions for user+password stuff (and more) is in (lib/base64.c) and
135 all functions for parsing and sending cookies are found in (lib/cookie.c).
137 HTTPS uses in almost every means the same procedure as HTTP, with only two
138 exceptions: the connect procedure is different and the function used to read
139 or write from the socket is different, although the latter fact is hidden in
140 the source by the use of curl_read() for reading and curl_write() for writing
141 data to the remote server.
143 http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
146 An interesting detail with the HTTP(S) request, is the add_buffer() series of
147 functions we use. They append data to one single buffer, and when the
148 building is done the entire request is sent off in one single write. This is
149 done this way to overcome problems with flawed firewalls and lame servers.
153 The Curl_if2ip() function can be used for getting the IP number of a
154 specified network interface, and it resides in lib/if2ip.c.
156 Curl_ftpsendf() is used for sending FTP commands to the remote server. It was
157 made a separate function to prevent us programmers from forgetting that they
158 must be CRLF terminated. They must also be sent in one single write() to make
159 firewalls and similar happy.
163 The kerberos support is mainly in lib/krb4.c and lib/security.c.
167 Telnet is implemented in lib/telnet.c.
171 The file:// protocol is dealt with in lib/file.c.
175 Everything LDAP is in lib/ldap.c.
179 URL encoding and decoding, called escaping and unescaping in the source code,
180 is found in lib/escape.c.
182 While transfering data in Transfer() a few functions might get
183 used. curl_getdate() in lib/getdate.c is for HTTP date comparisons (and
186 lib/getenv.c offers curl_getenv() which is for reading environment variables
187 in a neat platform independent way. That's used in the client, but also in
188 lib/url.c when checking the proxy environment variables. Note that contrary
189 to the normal unix getenv(), this returns an allocated buffer that must be
192 lib/netrc.c holds the .netrc parser
194 lib/timeval.c features replacement functions for systems that don't have
195 gettimeofday() and a few support functions for timeval convertions.
197 A function named curl_version() that returns the full curl version string is
198 found in lib/version.c.
200 If authentication is requested but no password is given, a getpass_r() clone
201 exists in lib/getpass.c. libcurl offers a custom callback that can be used
202 instead of this, but it doesn't change much to us.
204 Persistent Connections
205 ======================
207 With curl 7.7, we added persistent connection support to libcurl which has
208 introduced a somewhat different treatmeant of things inside of libcurl.
210 o The 'UrlData' struct returned in the curl_easy_init() call must never
211 hold connection-oriented data. It is meant to hold the root data as well
212 as all the options etc that the library-user may choose.
213 o The 'UrlData' struct holds the cache array of pointers to 'connectdata'
214 structs. There's one connectdata struct for each connection that libcurl
216 o This also enables the 'curl handle' to be reused on subsequent transfers,
217 something that was illegal in pre-7.7 versions.
218 o When we are about to perform a transfer with curl_easy_perform(), we first
219 check for an already existing connection in the cache that we can use,
220 otherwise we create a new one and add to the cache. If the cache is full
221 already when we add a new connection, we close one of the present ones. We
222 select which one to close dependent on the close policy that may have been
224 o When the tranfer operation is complete, we try to leave the connection open.
225 Particular options may tell us not to, and protocols may signal closure on
226 connections and then we don't keep it open of course.
227 o When curl_easy_cleanup() is called, we close all still opened connections.
229 You do realize that the curl handle must be re-used in order for the
230 persistent connections to work.
235 All symbols used internally in libcurl must use a 'Curl_' prefix if they're
236 used in more than a single file. Single-file symbols must be made
237 static. Public (exported) symbols must use a 'curl_' prefix. (There are
238 exceptions, but they are destined to be changed to follow this pattern in the
241 Return Codes and Informationals
242 ===============================
244 I've made things simple. Almost every function in libcurl returns a CURLcode,
245 that must be CURLE_OK if everything is OK or otherwise a suitable error code
246 as the curl/curl.h include file defines. The very spot that detects an error
247 must use the Curl_failf() function to set the human-readable error
250 In aiding the user to understand what's happening and to debug curl usage, we
251 must supply a fair amount of informational messages by using the Curl_infof()
252 function. Those messages are only displayed when the user explicitly asks for
253 them. They are best used when revealing information that isn't otherwise
259 main() resides in src/main.c together with most of the client code.
260 src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
261 display the complete "manual" and the src/urlglob.c file holds the functions
262 used for the URL-"globbing" support. Globbing in the sense that the {} and []
263 expansion stuff is there.
265 The client mostly messes around to setup its 'config' struct properly, then
266 it calls the curl_easy_*() functions of the library and when it gets back
267 control after the curl_easy_perform() it cleans up the library, checks status
270 When the operation is done, the ourWriteOut() function in src/writeout.c may
271 be called to report about the operation. That function is using the
272 curl_easy_getinfo() function to extract useful information from the curl
275 Recent versions may loop and do all that several times if many URLs were
276 specified on the command line or config file.
281 The file named lib/memdebug.c contains debug-versions of a few
282 functions. Functions such as malloc, free, fopen, fclose, etc that somehow
283 deal with resources that might give us problems if we "leak" them. The
284 functions in the memdebug system do nothing fancy, they do their normal
285 function and then log information about what they just did. The logged data
286 can then be analyzed after a complete session,
288 memanalyze.pl is a perl script present only present in CVS (not part of the
289 release archives) that analyzes a log file generated by the memdebug
290 system. It detects if resources are allocated but never freed and other kinds
291 of errors related to resource management.
293 Use -DMALLOCDEBUG when compiling to enable memory debugging.
298 Since November 2000, a test suite has evolved. It is placed in its own
299 subdirectory directly off the root in the curl archive tree, and it contains
300 a bunch of scripts and a lot of test case data.
302 The main test script is runtests.pl that will invoke the two servers
303 httpserver.pl and ftpserver.pl before all the test cases are performed. The
304 test suite currently only runs on unix-like platforms.
306 You'll find a complete description of the test case data files in the
309 The test suite automatically detects if curl was built with the memory
310 debugging enabled, and if it was it will detect memory leaks too.
315 There's no magic to this. When you consider everything stable enough to be
316 released, run the 'maketgz' script (using 'make distcheck' will give you a
317 pretty good view on the status of the current sources). maketgz prompts for
318 version number of the client and the library before it creates a release
319 archive. maketgz uses 'make dist' for the actual archive building, why you
320 need to fill in the Makefile.am files properly for which files that should
321 be included in the release archives.