persistent is spelled with an 'e', not an 'a'
[platform/upstream/curl.git] / docs / INTERNALS
1                                        Updated for curl 7.7 on March 13, 2001
2                                   _   _ ____  _     
3                               ___| | | |  _ \| |    
4                              / __| | | | |_) | |    
5                             | (__| |_| |  _ <| |___ 
6                              \___|\___/|_| \_\_____|
7
8 INTERNALS
9
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
12  it.
13
14  The largest amount of code and complexity is in the library part.
15
16 CVS
17 ===
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
21  afterwards.
22
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.
25
26 Windows vs Unix
27 ===============
28
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:
31
32  1. Different function names for socket operations.
33
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().
37
38  2. Windows requires a couple of init calls for the socket stuff.
39
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.
42
43  3. The file descriptors for network communication and file operations are
44     not easily interchangable as in unix.
45
46    We avoid this by not trying any funny tricks on file descriptors.
47
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)
51
52    We set stdout to binary under windows
53
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
59  Windows machine!
60
61  Generally speaking: always remember that this will be compiled on dozens of
62  operating systems. Don't walk on the edge.
63
64 Library
65 =======
66
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.
71
72  All printf()-style functions use the supplied clones in lib/mprintf.c. This
73  makes sure we stay absolutely platform independent.
74
75  curl_easy_init() allocates an internal struct and makes some initializations.
76  The returned handle does not revail internals.
77
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.
81
82  curl_easy_perform() does a whole lot of things:
83
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.
89
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
93  and dict.c).
94
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.
103
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.
108
109  When completed, the curl_easy_cleanup() should be called to free up used
110  resources.
111
112  A quick roundup on internal function sequences (many of these call
113  protocol-specific function-pointers):
114
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.
118
119    curl_do - starts a transfer
120     curl_transfer() - transfers data
121    curl_done - ends a transfer
122
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
126    a while.
127
128  HTTP(S)
129
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
132  post functions.
133
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).
136
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.
142
143  http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
144  encoding.
145
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.
150
151  FTP
152
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.
155
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.
160
161  Kerberos
162
163  The kerberos support is mainly in lib/krb4.c and lib/security.c.
164
165  TELNET
166
167  Telnet is implemented in lib/telnet.c.
168
169  FILE
170
171  The file:// protocol is dealt with in lib/file.c.
172
173  LDAP
174
175  Everything LDAP is in lib/ldap.c.
176
177  GENERAL
178
179  URL encoding and decoding, called escaping and unescaping in the source code,
180  is found in lib/escape.c.
181
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
184  more).
185
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
190  free()ed after use.
191
192  lib/netrc.c holds the .netrc parser
193
194  lib/timeval.c features replacement functions for systems that don't have
195  gettimeofday() and a few support functions for timeval convertions.
196  
197  A function named curl_version() that returns the full curl version string is
198  found in lib/version.c.
199
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.
203
204 Persistent Connections
205 ======================
206
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.
209
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
215    knows about.
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
223    previously set.
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.
228
229  You do realize that the curl handle must be re-used in order for the
230  persistent connections to work.
231
232 Library Symbols
233 ===============
234  
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
239  future.)
240
241 Return Codes and Informationals
242 ===============================
243
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
248  description.
249
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
254  obvious.
255
256 Client
257 ======
258
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.
264
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
268  and exits.
269
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
273  session.
274
275  Recent versions may loop and do all that several times if many URLs were
276  specified on the command line or config file.
277
278 Memory Debugging
279 ================
280
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,
287
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.
292
293  Use -DMALLOCDEBUG when compiling to enable memory debugging.
294
295 Test Suite
296 ==========
297
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.
301
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.
305
306  You'll find a complete description of the test case data files in the
307  tests/README file.
308
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.
311
312 Building Releases
313 =================
314
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.
322