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