INTERNALS 16 KB

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