Git init
[external/curl.git] / docs / INTERNALS
1                                   _   _ ____  _
2                               ___| | | |  _ \| |
3                              / __| | | | |_) | |
4                             | (__| |_| |  _ <| |___
5                              \___|\___/|_| \_\_____|
6
7 INTERNALS
8
9  The project is split in two. The library and the client. The client part uses
10  the library, but the library is designed to allow other applications to use
11  it.
12
13  The largest amount of code and complexity is in the library part.
14
15 GIT
16 ===
17  All changes to the sources are committed to the git repository as soon as
18  they're somewhat verified to work. Changes shall be commited as independently
19  as possible so that individual changes can be easier spotted and tracked
20  afterwards.
21
22  Tagging shall be used extensively, and by the time we release new archives we
23  should tag the sources with a name similar to the released version number.
24
25 Portability
26 ===========
27
28  We write curl and libcurl to compile with C89 compilers.  On 32bit and up
29  machines. Most of libcurl assumes more or less POSIX compliance but that's
30  not a requirement.
31
32  We write libcurl to build and work with lots of third party tools, and we
33  want it to remain functional and buildable with these and later versions
34  (older versions may still work but is not what we work hard to maintain):
35
36  OpenSSL      0.9.6
37  GnuTLS       1.2
38  zlib         1.1.4
39  libssh2      0.16
40  c-ares       1.6.0
41  libidn       0.4.1
42  *yassl       1.4.0 (http://curl.haxx.se/mail/lib-2008-02/0093.html)
43  openldap     2.0
44  MIT krb5 lib 1.2.4
45  qsossl       V5R2M0
46  NSS          3.11.x
47  Heimdal      ?
48
49  * = only partly functional, but that's due to bugs in the third party lib, not
50      because of libcurl code
51
52  On systems where configure runs, we aim at working on them all - if they have
53  a suitable C compiler. On systems that don't run configure, we strive to keep
54  curl running fine on:
55
56  Windows      98
57  AS/400       V5R2M0
58  Symbian      9.1
59  Windows CE   ?
60  TPF          ?
61
62  When writing code (mostly for generating stuff included in release tarballs)
63  we use a few "build tools" and we make sure that we remain functional with
64  these versions:
65
66  GNU Libtool  1.4.2
67  GNU Autoconf 2.57
68  GNU Automake 1.7 (we currently avoid 1.10 due to Solaris-related bugs)
69  GNU M4       1.4
70  perl         4
71  roffit       0.5
72  groff        ? (any version that supports "groff -Tps -man [in] [out]")
73  ps2pdf (gs)  ?
74
75 Windows vs Unix
76 ===============
77
78  There are a few differences in how to program curl the unix way compared to
79  the Windows way. The four perhaps most notable details are:
80
81  1. Different function names for socket operations.
82
83    In curl, this is solved with defines and macros, so that the source looks
84    the same at all places except for the header file that defines them. The
85    macros in use are sclose(), sread() and swrite().
86
87  2. Windows requires a couple of init calls for the socket stuff.
88
89    That's taken care of by the curl_global_init() call, but if other libs also
90    do it etc there might be reasons for applications to alter that behaviour.
91
92  3. The file descriptors for network communication and file operations are
93     not easily interchangable as in unix.
94
95    We avoid this by not trying any funny tricks on file descriptors.
96
97  4. When writing data to stdout, Windows makes end-of-lines the DOS way, thus
98     destroying binary data, although you do want that conversion if it is
99     text coming through... (sigh)
100
101    We set stdout to binary under windows
102
103  Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All
104  conditionals that deal with features *should* instead be in the format
105  '#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts,
106  we maintain two curl_config-win32.h files (one in lib/ and one in src/) that
107  are supposed to look exactly as a curl_config.h file would have looked like on
108  a Windows machine!
109
110  Generally speaking: always remember that this will be compiled on dozens of
111  operating systems. Don't walk on the edge.
112
113 Library
114 =======
115
116  There are plenty of entry points to the library, namely each publicly defined
117  function that libcurl offers to applications. All of those functions are
118  rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
119  put in the lib/easy.c file.
120
121  curl_global_init_() and curl_global_cleanup() should be called by the
122  application to initialize and clean up global stuff in the library. As of
123  today, it can handle the global SSL initing if SSL is enabled and it can init
124  the socket layer on windows machines. libcurl itself has no "global" scope.
125
126  All printf()-style functions use the supplied clones in lib/mprintf.c. This
127  makes sure we stay absolutely platform independent.
128
129  curl_easy_init() allocates an internal struct and makes some initializations.
130  The returned handle does not reveal internals. This is the 'SessionHandle'
131  struct which works as an "anchor" struct for all curl_easy functions. All
132  connections performed will get connect-specific data allocated that should be
133  used for things related to particular connections/requests.
134
135  curl_easy_setopt() takes three arguments, where the option stuff must be
136  passed in pairs: the parameter-ID and the parameter-value. The list of
137  options is documented in the man page. This function mainly sets things in
138  the 'SessionHandle' struct.
139
140  curl_easy_perform() does a whole lot of things:
141
142  It starts off in the lib/easy.c file by calling Curl_perform() and the main
143  work then continues in lib/url.c. The flow continues with a call to
144  Curl_connect() to connect to the remote site.
145
146  o Curl_connect()
147
148    ... analyzes the URL, it separates the different components and connects to
149    the remote host. This may involve using a proxy and/or using SSL. The
150    Curl_resolv() function in lib/hostip.c is used for looking up host names
151    (it does then use the proper underlying method, which may vary between
152    platforms and builds).
153
154    When Curl_connect is done, we are connected to the remote site. Then it is
155    time to tell the server to get a document/file. Curl_do() arranges this.
156
157    This function makes sure there's an allocated and initiated 'connectdata'
158    struct that is used for this particular connection only (although there may
159    be several requests performed on the same connect). A bunch of things are
160    inited/inherited from the SessionHandle struct.
161
162  o Curl_do()
163
164    Curl_do() makes sure the proper protocol-specific function is called. The
165    functions are named after the protocols they handle. Curl_ftp(),
166    Curl_http(), Curl_dict(), etc. They all reside in their respective files
167    (ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
168    Curl_ftp().
169
170    The protocol-specific functions of course deal with protocol-specific
171    negotiations and setup. They have access to the Curl_sendf() (from
172    lib/sendf.c) function to send printf-style formatted data to the remote
173    host and when they're ready to make the actual file transfer they call the
174    Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
175    returns.
176
177    If this DO function fails and the connection is being re-used, libcurl will
178    then close this connection, setup a new connection and re-issue the DO
179    request on that. This is because there is no way to be perfectly sure that
180    we have discovered a dead connection before the DO function and thus we
181    might wrongly be re-using a connection that was closed by the remote peer.
182
183    Some time during the DO function, the Curl_setup_transfer() function must
184    be called with some basic info about the upcoming transfer: what socket(s)
185    to read/write and the expected file tranfer sizes (if known).
186
187  o Transfer()
188
189    Curl_perform() then calls Transfer() in lib/transfer.c that performs the
190    entire file transfer.
191
192    During transfer, the progress functions in lib/progress.c are called at a
193    frequent interval (or at the user's choice, a specified callback might get
194    called). The speedcheck functions in lib/speedcheck.c are also used to
195    verify that the transfer is as fast as required.
196
197  o Curl_done()
198
199    Called after a transfer is done. This function takes care of everything
200    that has to be done after a transfer. This function attempts to leave
201    matters in a state so that Curl_do() should be possible to call again on
202    the same connection (in a persistent connection case). It might also soon
203    be closed with Curl_disconnect().
204
205  o Curl_disconnect()
206
207    When doing normal connections and transfers, no one ever tries to close any
208    connections so this is not normally called when curl_easy_perform() is
209    used. This function is only used when we are certain that no more transfers
210    is going to be made on the connection. It can be also closed by force, or
211    it can be called to make sure that libcurl doesn't keep too many
212    connections alive at the same time (there's a default amount of 5 but that
213    can be changed with the CURLOPT_MAXCONNECTS option).
214
215    This function cleans up all resources that are associated with a single
216    connection.
217
218  Curl_perform() is the function that does the main "connect - do - transfer -
219  done" loop. It loops if there's a Location: to follow.
220
221  When completed, the curl_easy_cleanup() should be called to free up used
222  resources. It runs Curl_disconnect() on all open connectons.
223
224  A quick roundup on internal function sequences (many of these call
225  protocol-specific function-pointers):
226
227   curl_connect - connects to a remote site and does initial connect fluff
228    This also checks for an existing connection to the requested site and uses
229    that one if it is possible.
230
231    curl_do - starts a transfer
232     curl_transfer() - transfers data
233    curl_done - ends a transfer
234
235   curl_disconnect - disconnects from a remote site. This is called when the
236    disconnect is really requested, which doesn't necessarily have to be
237    exactly after curl_done in case we want to keep the connection open for
238    a while.
239
240  HTTP(S)
241
242  HTTP offers a lot and is the protocol in curl that uses the most lines of
243  code. There is a special file (lib/formdata.c) that offers all the multipart
244  post functions.
245
246  base64-functions for user+password stuff (and more) is in (lib/base64.c) and
247  all functions for parsing and sending cookies are found in (lib/cookie.c).
248
249  HTTPS uses in almost every means the same procedure as HTTP, with only two
250  exceptions: the connect procedure is different and the function used to read
251  or write from the socket is different, although the latter fact is hidden in
252  the source by the use of curl_read() for reading and curl_write() for writing
253  data to the remote server.
254
255  http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
256  encoding.
257
258  An interesting detail with the HTTP(S) request, is the add_buffer() series of
259  functions we use. They append data to one single buffer, and when the
260  building is done the entire request is sent off in one single write. This is
261  done this way to overcome problems with flawed firewalls and lame servers.
262
263  FTP
264
265  The Curl_if2ip() function can be used for getting the IP number of a
266  specified network interface, and it resides in lib/if2ip.c.
267
268  Curl_ftpsendf() is used for sending FTP commands to the remote server. It was
269  made a separate function to prevent us programmers from forgetting that they
270  must be CRLF terminated. They must also be sent in one single write() to make
271  firewalls and similar happy.
272
273  Kerberos
274
275  The kerberos support is mainly in lib/krb4.c and lib/security.c.
276
277  TELNET
278
279  Telnet is implemented in lib/telnet.c.
280
281  FILE
282
283  The file:// protocol is dealt with in lib/file.c.
284
285  LDAP
286
287  Everything LDAP is in lib/ldap.c.
288
289  GENERAL
290
291  URL encoding and decoding, called escaping and unescaping in the source code,
292  is found in lib/escape.c.
293
294  While transfering data in Transfer() a few functions might get used.
295  curl_getdate() in lib/parsedate.c is for HTTP date comparisons (and more).
296
297  lib/getenv.c offers curl_getenv() which is for reading environment variables
298  in a neat platform independent way. That's used in the client, but also in
299  lib/url.c when checking the proxy environment variables. Note that contrary
300  to the normal unix getenv(), this returns an allocated buffer that must be
301  free()ed after use.
302
303  lib/netrc.c holds the .netrc parser
304
305  lib/timeval.c features replacement functions for systems that don't have
306  gettimeofday() and a few support functions for timeval convertions.
307
308  A function named curl_version() that returns the full curl version string is
309  found in lib/version.c.
310
311 Persistent Connections
312 ======================
313
314  The persistent connection support in libcurl requires some considerations on
315  how to do things inside of the library.
316
317  o The 'SessionHandle' struct returned in the curl_easy_init() call must never
318    hold connection-oriented data. It is meant to hold the root data as well as
319    all the options etc that the library-user may choose.
320  o The 'SessionHandle' struct holds the "connection cache" (an array of
321    pointers to 'connectdata' structs). There's one connectdata struct
322    allocated for each connection that libcurl knows about. Note that when you
323    use the multi interface, the multi handle will hold the connection cache
324    and not the particular easy handle. This of course to allow all easy handles
325    in a multi stack to be able to share and re-use connections.
326  o This enables the 'curl handle' to be reused on subsequent transfers.
327  o When we are about to perform a transfer with curl_easy_perform(), we first
328    check for an already existing connection in the cache that we can use,
329    otherwise we create a new one and add to the cache. If the cache is full
330    already when we add a new connection, we close one of the present ones. We
331    select which one to close dependent on the close policy that may have been
332    previously set.
333  o When the transfer operation is complete, we try to leave the connection
334    open. Particular options may tell us not to, and protocols may signal
335    closure on connections and then we don't keep it open of course.
336  o When curl_easy_cleanup() is called, we close all still opened connections,
337    unless of course the multi interface "owns" the connections.
338
339  You do realize that the curl handle must be re-used in order for the
340  persistent connections to work.
341
342 multi interface/non-blocking
343 ============================
344
345  We make an effort to provide a non-blocking interface to the library, the
346  multi interface. To make that interface work as good as possible, no
347  low-level functions within libcurl must be written to work in a blocking
348  manner.
349
350  One of the primary reasons we introduced c-ares support was to allow the name
351  resolve phase to be perfectly non-blocking as well.
352
353  The ultimate goal is to provide the easy interface simply by wrapping the
354  multi interface functions and thus treat everything internally as the multi
355  interface is the single interface we have.
356
357  The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
358  and adjust the code to allow non-blocking operations even on multi-stage
359  protocols. The DICT, LDAP and TELNET are crappy examples and they are subject
360  for rewrite in the future to better fit the libcurl protocol family.
361
362 SSL libraries
363 =============
364
365  Originally libcurl supported SSLeay for SSL/TLS transports, but that was then
366  extended to its successor OpenSSL but has since also been extended to several
367  other SSL/TLS libraries and we expect and hope to further extend the support
368  in future libcurl versions.
369
370  To deal with this internally in the best way possible, we have a generic SSL
371  function API as provided by the sslgen.[ch] system, and they are the only SSL
372  functions we must use from within libcurl. sslgen is then crafted to use the
373  appropriate lower-level function calls to whatever SSL library that is in
374  use.
375
376 Library Symbols
377 ===============
378
379  All symbols used internally in libcurl must use a 'Curl_' prefix if they're
380  used in more than a single file. Single-file symbols must be made static.
381  Public ("exported") symbols must use a 'curl_' prefix. (There are exceptions,
382  but they are to be changed to follow this pattern in future versions.)
383
384 Return Codes and Informationals
385 ===============================
386
387  I've made things simple. Almost every function in libcurl returns a CURLcode,
388  that must be CURLE_OK if everything is OK or otherwise a suitable error code
389  as the curl/curl.h include file defines. The very spot that detects an error
390  must use the Curl_failf() function to set the human-readable error
391  description.
392
393  In aiding the user to understand what's happening and to debug curl usage, we
394  must supply a fair amount of informational messages by using the Curl_infof()
395  function. Those messages are only displayed when the user explicitly asks for
396  them. They are best used when revealing information that isn't otherwise
397  obvious.
398
399 API/ABI
400 =======
401
402  We make an effort to not export or show internals or how internals work, as
403  that makes it easier to keep a solid API/ABI over time. See docs/libcurl/ABI
404  for our promise to users.
405
406 Client
407 ======
408
409  main() resides in src/main.c together with most of the client code.
410
411  src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
412  display the complete "manual" and the src/urlglob.c file holds the functions
413  used for the URL-"globbing" support. Globbing in the sense that the {} and []
414  expansion stuff is there.
415
416  The client mostly messes around to setup its 'config' struct properly, then
417  it calls the curl_easy_*() functions of the library and when it gets back
418  control after the curl_easy_perform() it cleans up the library, checks status
419  and exits.
420
421  When the operation is done, the ourWriteOut() function in src/writeout.c may
422  be called to report about the operation. That function is using the
423  curl_easy_getinfo() function to extract useful information from the curl
424  session.
425
426  Recent versions may loop and do all this several times if many URLs were
427  specified on the command line or config file.
428
429 Memory Debugging
430 ================
431
432  The file lib/memdebug.c contains debug-versions of a few functions. Functions
433  such as malloc, free, fopen, fclose, etc that somehow deal with resources
434  that might give us problems if we "leak" them. The functions in the memdebug
435  system do nothing fancy, they do their normal function and then log
436  information about what they just did. The logged data can then be analyzed
437  after a complete session,
438
439  memanalyze.pl is the perl script present in tests/ that analyzes a log file
440  generated by the memory tracking system. It detects if resources are
441  allocated but never freed and other kinds of errors related to resource
442  management.
443
444  Internally, definition of preprocessor symbol DEBUGBUILD restricts code which
445  is only compiled for debug enabled builds. And symbol CURLDEBUG is used to
446  differentiate code which is _only_ used for memory tracking/debugging.
447
448  Use -DCURLDEBUG when compiling to enable memory debugging, this is also
449  switched on by running configure with --enable-curldebug. Use -DDEBUGBUILD
450  when compiling to enable a debug build or run configure with --enable-debug.
451
452  curl --version will list 'Debug' feature for debug enabled builds, and
453  will list 'TrackMemory' feature for curl debug memory tracking capable
454  builds. These features are independent and can be controlled when running
455  the configure script. When --enable-debug is given both features will be
456  enabled, unless some restriction prevents memory tracking from being used.
457
458 Test Suite
459 ==========
460
461  Since November 2000, a test suite has evolved. It is placed in its own
462  subdirectory directly off the root in the curl archive tree, and it contains
463  a bunch of scripts and a lot of test case data.
464
465  The main test script is runtests.pl that will invoke the two servers
466  httpserver.pl and ftpserver.pl before all the test cases are performed. The
467  test suite currently only runs on unix-like platforms.
468
469  You'll find a complete description of the test case data files in the
470  tests/README file.
471
472  The test suite automatically detects if curl was built with the memory
473  debugging enabled, and if it was it will detect memory leaks too.
474
475 Building Releases
476 =================
477
478  There's no magic to this. When you consider everything stable enough to be
479  released, run the 'maketgz' script (using 'make distcheck' will give you a
480  pretty good view on the status of the current sources). maketgz prompts for
481  version number of the client and the library before it creates a release
482  archive. maketgz uses 'make dist' for the actual archive building, why you
483  need to fill in the Makefile.am files properly for which files that should
484  be included in the release archives.
485
486  NOTE: you need to have curl checked out from git to be able to do a proper
487  release build. The release tarballs do not have everything setup in order to
488  do releases properly.