Compare commits

...

288 Commits

Author SHA1 Message Date
Daniel Stenberg
3654bd1b56 7.7.3 2001-05-07 11:12:03 +00:00
Daniel Stenberg
237edbc9d8 changed FILE * to void * in all callbacks 2001-05-07 10:51:23 +00:00
Daniel Stenberg
4127903183 Added multithread.c 2001-05-04 09:35:55 +00:00
Daniel Stenberg
2ffc20dc7c example using multiple threads to get URLs 2001-05-04 09:35:43 +00:00
Daniel Stenberg
a2a446cb2f updated contributors list 2001-05-04 08:46:11 +00:00
Daniel Stenberg
9304055df5 'FILE *' changed to 'void *' in all callback functions 2001-05-04 07:47:11 +00:00
Daniel Stenberg
53e0c1b1a6 fixed the link to the OS/2 Patch for OpenSSL 2001-05-04 06:17:01 +00:00
Daniel Stenberg
4efa1e8e4c corrected bad use of the CURLOPT_HTTPPOST header 2001-05-03 14:24:37 +00:00
Daniel Stenberg
ecba113125 Cris changes 2001-05-03 11:09:00 +00:00
Daniel Stenberg
350c536f6c Cris Bailiff's fix to disable chunked transfers on re-used persistent
connections.
2001-05-03 10:53:01 +00:00
Daniel Stenberg
a33eb9881c Cris Bailiff's fix to never attempt to get the body of a 304-reply! 2001-05-03 10:45:39 +00:00
Daniel Stenberg
bbe8aa073e buildconf added, Sterling Hughes added that file 2001-05-03 09:13:53 +00:00
Daniel Stenberg
14521b418e useful script to run after updating from CVS 2001-05-03 09:12:53 +00:00
Daniel Stenberg
73982c65d2 fixed the EXTRA_DIST line 2001-05-03 09:10:07 +00:00
Daniel Stenberg
2eb94acb95 When Content-Length:0 is received, we now bail now and return success
directly after all the headers are received!
2001-04-27 18:03:44 +00:00
Daniel Stenberg
6a80fb3482 bugs, fixes and updates 2001-04-27 14:48:04 +00:00
Daniel Stenberg
26d4c80049 clarified and updated 2001-04-27 14:46:17 +00:00
Daniel Stenberg
3974f30ed4 improved treatment of "Content-Length: 0", which is done by having
maxdownload set to -1 when not used
2001-04-27 08:02:10 +00:00
Daniel Stenberg
44c246dbf2 new 2001-04-27 07:58:26 +00:00
Daniel Stenberg
ef07903a51 Curl_GetFTPResponse() is rewritten to read all incoming data in large
chunks, which makes it a lot faster and will make ftps work better...
2001-04-26 10:29:24 +00:00
Daniel Stenberg
a7dc45997f split curl and libcurl into two strings in the initial display 2001-04-26 08:32:12 +00:00
Daniel Stenberg
583c2e2f09 connection re-using didn't work on non-default ports when not using proxy
until now
2001-04-25 21:24:27 +00:00
Daniel Stenberg
90cce2ae3a added some verbose summary output stuff 2001-04-24 21:47:01 +00:00
Daniel Stenberg
775dc07eb5 no name no test 2001-04-24 21:46:37 +00:00
Daniel Stenberg
a652db18bd include debugmem for memory leak detection 2001-04-24 21:41:29 +00:00
Daniel Stenberg
48f3feed59 SSL based tests 2001-04-24 21:11:34 +00:00
Daniel Stenberg
4ddb3fbbf4 new tests, new server invoke system 2001-04-24 21:09:53 +00:00
Daniel Stenberg
cc872ebc19 fixed 2001-04-24 21:09:27 +00:00
Daniel Stenberg
ba46006896 stunnel and diff are added requirements 2001-04-24 21:09:12 +00:00
Daniel Stenberg
0b7e0638a9 on albert chin's comment I remade the fix to set '\0' instead of 0 since
they're chars
2001-04-24 06:12:07 +00:00
Daniel Stenberg
be49b01952 libcurl.5 replaces LIBCURL as main libcurl overview document 2001-04-23 12:37:27 +00:00
Daniel Stenberg
8d0c1d5495 minor rephrasing 2001-04-23 12:36:02 +00:00
Daniel Stenberg
2769a9ab0b form post, not just form 2001-04-23 11:57:50 +00:00
Daniel Stenberg
8ea5b5bbd0 clarified and extended with an example 2001-04-23 11:55:25 +00:00
Daniel Stenberg
0ce49cb7ed Added comment about where to find the HTML versions of the man pages 2001-04-23 11:42:24 +00:00
Daniel Stenberg
d802dfe86a Added curl_mprintf and curl_strequal in the list of "useful functions" 2001-04-23 11:40:53 +00:00
Daniel Stenberg
aabc0c08a1 curl_printf became curl_mprintf 2001-04-23 08:30:22 +00:00
Daniel Stenberg
476addb9c1 curl_printf is curl_mprintf now 2001-04-23 08:29:56 +00:00
Daniel Stenberg
37d7a198d5 Added zero termination, as the OpenSSL version string was written without
it!
2001-04-23 07:54:12 +00:00
Daniel Stenberg
16fe0c9be3 curl 7.7.2 2001-04-23 07:34:55 +00:00
Daniel Stenberg
f88ff705a4 borland fixes, broken host: for persistent connections 2001-04-23 07:27:12 +00:00
Daniel Stenberg
e83550f511 persistent is spelled with an 'e', not an 'a' 2001-04-23 07:09:15 +00:00
Daniel Stenberg
fde31f0988 no need to copy the name when re-using the connection, we already have the
same name in that buffer from the URL parsing!
2001-04-23 06:11:08 +00:00
Daniel Stenberg
d3090ac3f9 Rosimildo da Silva corrected them to build a proper lib and to use options
for multi-threading compiling
2001-04-22 17:39:04 +00:00
Daniel Stenberg
2cf26d4fb7 copy the name properly when re-using a connection 2001-04-22 16:47:55 +00:00
Daniel Stenberg
f470a131a6 added missing (new) man pages 2001-04-22 15:50:12 +00:00
Daniel Stenberg
04b20b7ed2 old krb4 fix for strlcat() prototype 2001-04-22 15:49:17 +00:00
Daniel Stenberg
ff4f4abe4b brand new 2001-04-22 15:48:05 +00:00
Daniel Stenberg
f4703aee2f removed done entries 2001-04-22 15:47:20 +00:00
Daniel Stenberg
4c485994db updated and spell checked 2001-04-22 15:45:27 +00:00
Daniel Stenberg
a921ee7b52 spell checked 2001-04-22 15:44:33 +00:00
Daniel Stenberg
f6d4a25f68 updated with the Java stuff and so 2001-04-22 15:44:13 +00:00
Daniel Stenberg
2dfd2c642d Added an examples section with examples I made up for the web page 2001-04-20 14:45:15 +00:00
Daniel Stenberg
a2072a1fd0 This is LIBCURL turned into man page format! 2001-04-20 14:44:55 +00:00
Daniel Stenberg
03fea9722c Cris Bailiff's 1.1.5 changes: Add latest CURLOPT_ and CURLINFO_ constants to
the constants list
2001-04-20 11:03:40 +00:00
Daniel Stenberg
a44a8cef99 Cris Bailiff's 1.1.4 changes: Fix case where curl_slists such as 'HTTPHEADERS'
need to be re-set over persistant requests
2001-04-20 06:49:58 +00:00
Daniel Stenberg
97ad165a63 minor corrections 2001-04-20 06:05:33 +00:00
Daniel Stenberg
a508e73a8d SM's real name is now used where he's credited 2001-04-20 06:00:00 +00:00
Daniel Stenberg
32f966b239 A Linus Nielsen Feltzing-patch that removes the decimals from the size
outputs...
2001-04-19 11:24:29 +00:00
Daniel Stenberg
60a43561e2 fixed an nroff syntax mistake 2001-04-19 11:19:54 +00:00
Daniel Stenberg
a91b7d461d Added a brief description of curl-config, mentioned that curl_* functions are
the only public ones
2001-04-19 10:31:23 +00:00
Daniel Stenberg
8755c44d40 Albert Chin's patch posted to the mailing list 19 Apr 2001 2001-04-19 06:01:48 +00:00
Daniel Stenberg
5dd1cb0614 added an include to build on ultrix 2001-04-18 14:06:47 +00:00
Daniel Stenberg
b34bee45ca confirmed install on ultrix 4.3a 2001-04-18 14:06:12 +00:00
Daniel Stenberg
e22fb3e7bc works! 2001-04-18 14:05:44 +00:00
Daniel Stenberg
6ea51f3cd7 Last two days' changes, loadsa 2001-04-18 14:05:18 +00:00
Daniel Stenberg
8e9f0a73d0 Georg Horn's updates, this is _also_ called 1.1.3 ! ;-) 2001-04-18 13:41:04 +00:00
Daniel Stenberg
80fbcdf2f2 Added curl-config.1 2001-04-18 13:16:57 +00:00
Daniel Stenberg
0fd9f64287 brand new command, brand new docs! 2001-04-18 13:16:34 +00:00
Daniel Stenberg
b6175ec792 Added contributors 2001-04-18 11:53:19 +00:00
Daniel Stenberg
1ee7f92ce4 configure sets variables that curl-config uses to display what features
that have been built-in
2001-04-18 09:28:55 +00:00
Daniel Stenberg
3fd65fb7d8 Remade resume stuff to keep data in the connectdata struct instead of the
main handle struct to work with persistant connections
2001-04-18 07:25:11 +00:00
Daniel Stenberg
ebcafe73b3 Cris Bailiff's and Georg Horn's big improvements 2001-04-18 06:51:30 +00:00
Daniel Stenberg
8274bee963 init the speed index variable between transfers 2001-04-17 15:00:17 +00:00
Daniel Stenberg
60aa975610 Frederic Lepied's ftp download resume fix 2001-04-17 13:21:13 +00:00
Daniel Stenberg
28a9108257 more intial fixes 2001-04-17 12:37:38 +00:00
Daniel Stenberg
d1b0b08ba0 Added curl-config as a script that now gets installed 2001-04-17 12:33:02 +00:00
Daniel Stenberg
cc7fc20251 libcurl version, not curl version 2001-04-17 12:32:37 +00:00
Daniel Stenberg
5ab751f5d0 Generates curl-config now 2001-04-17 12:27:59 +00:00
Daniel Stenberg
fb1ce5fd5b tiny tool for outputting curl config variables 2001-04-17 12:23:06 +00:00
Daniel Stenberg
fd8ea204c0 use GMT for the conditional timed gets (reported by Phil Karn) 2001-04-17 07:28:49 +00:00
Daniel Stenberg
b86674174a Added text about curl.haxx.se not being a good test target for people's
libcurl experiments...
2001-04-12 11:13:28 +00:00
Daniel Stenberg
69994f0114 we must fix SSL when IPv6 is enabled, since we can still connect to ipv4
sites and then SSL works perfectly
2001-04-12 06:16:20 +00:00
Daniel Stenberg
879c6c5711 calling curl_easy_perform() with no URL set, now returns an error as
early as possible
2001-04-11 14:14:28 +00:00
Daniel Stenberg
18f044f19d we don't use the HTTP_PROXY environment variable in uppercase anymore, since
it might become a security problem (Bugs item #415391)
2001-04-11 14:13:52 +00:00
Daniel Stenberg
d7b54eb835 now it works 2001-04-11 13:45:55 +00:00
Daniel Stenberg
5eafb69bdb minor updates, still crashes 2001-04-11 10:06:28 +00:00
Daniel Stenberg
a086e99bae added Linux hints 2001-04-11 10:03:14 +00:00
Daniel Stenberg
62056a644f oops, missed the shut-off non-blocking fix 2001-04-11 06:59:00 +00:00
Daniel Stenberg
b2362bf51c interfaces, windows non-blocking connect, progress meter fix and more 2001-04-11 06:51:43 +00:00
Daniel Stenberg
022099266e SM made the connection timeout work for windows boxes! 2001-04-11 06:41:54 +00:00
Daniel Stenberg
870cea2aea initial silly README 2001-04-10 15:41:36 +00:00
Daniel Stenberg
04c10e021c C header to java converter 2001-04-10 15:30:01 +00:00
Daniel Stenberg
d712a4e800 initial java interface commit: IT DOES NOT WORK 2001-04-10 15:29:32 +00:00
Daniel Stenberg
d9f989c8c8 Added CURLOPT_HEADERFUNCTION description 2001-04-10 07:38:59 +00:00
Daniel Stenberg
90bb87b40e setopt() works with the new CURLOPT_HEADERFUNCTION: 2001-04-10 06:51:25 +00:00
Daniel Stenberg
025fa762f6 Added new CURLOPT_HEADERFUNCTION callback for writing headers only 2001-04-10 06:49:32 +00:00
Daniel Stenberg
ac510ab6a4 corrected by SM to build better with openssl 2001-04-09 05:56:39 +00:00
Daniel Stenberg
65b286ca35 SM's updates 2001-04-09 05:55:58 +00:00
Daniel Stenberg
cc5c53454a formfree() fix, version display fixed, curl_escape() fix 2001-04-07 18:39:18 +00:00
Daniel Stenberg
f7874cad29 Andrs Garca pointed out a mistake with CURLOPT_EGDSOCKET 2001-04-07 18:36:22 +00:00
Daniel Stenberg
84e71e1c50 Andrs Garca fixed curl_escape() 2001-04-07 18:35:28 +00:00
Daniel Stenberg
88bb054e1d show openssl 0.9.6a properly 2001-04-06 08:48:42 +00:00
Daniel Stenberg
b054fbaebd NULL argument crashes this in 7.7.1 and before 2001-04-06 05:57:23 +00:00
Daniel Stenberg
53e3c225ee curl_formfree() can be called with a NULL argument 2001-04-06 05:52:23 +00:00
Daniel Stenberg
50a53d4eec 7.7.1 commit 2001-04-04 06:23:43 +00:00
Daniel Stenberg
6bd1ed034a bugfixed the Location: following that must've been bad since the persistant
connections were introduced
2001-04-03 13:37:53 +00:00
Daniel Stenberg
fa491ed910 - disabling port on absolute redirects is wrong
- removed #ifdefed code
2001-04-03 13:18:41 +00:00
Daniel Stenberg
66a1e3df69 two crashes removed 2001-04-03 12:37:48 +00:00
Daniel Stenberg
28497e7ee4 better error checks for failure conditions (based on Puneet Pawaia's reports) 2001-04-03 10:20:23 +00:00
Daniel Stenberg
87c7f403a9 Puneet Pawaia pointed out the lack of http_chunks in several places. 2001-04-03 08:57:06 +00:00
Daniel Stenberg
1a2c3acb3b elaborated more in CURLOPT_HTTPHEADER section 2001-03-30 08:43:52 +00:00
Daniel Stenberg
b54d752783 ftps:// added and the perl interfaces changed 2001-03-29 11:25:29 +00:00
Daniel Stenberg
b1328430c9 ftps:// support added 2001-03-29 08:16:55 +00:00
Daniel Stenberg
34efa74a59 Georg Horn's and my fixes to make it compile with 7.7 2001-03-29 06:45:04 +00:00
Daniel Stenberg
794d08a728 Georg Horn set -Wall 2001-03-29 06:44:34 +00:00
Daniel Stenberg
0abc999c4d Georg Horn's updates 2001-03-29 06:43:46 +00:00
Daniel Stenberg
3e65062be2 make sure the alarm is off when returning from curl_easy_perform() 2001-03-27 21:24:46 +00:00
Daniel Stenberg
45ffb16c2a Added a line about the new makefile example 2001-03-27 09:10:53 +00:00
Daniel Stenberg
0b8b0b7c86 Added Makefile.example as an example makefile that can build the example
source files (if edited slightly)
2001-03-27 09:09:09 +00:00
Daniel Stenberg
053bf49bd2 Added ftpget.c just to show that it is exactly as easy to get FTP files 2001-03-27 09:00:18 +00:00
Daniel Stenberg
8b08dfed38 no more ' as first letter of a row, and made the quotes match in the top
.BI line
2001-03-27 08:45:50 +00:00
Daniel Stenberg
ba3a3553dc Added some text to WRITEHEADER about the fact that libcurl will always write
complete header lines one-by-one to that file handle
2001-03-27 08:41:37 +00:00
Daniel Stenberg
6a26104724 7.7.1-beta1 2001-03-26 13:49:50 +00:00
Daniel Stenberg
8b35b89f4d persistant fix for http/1.0 2001-03-26 09:07:44 +00:00
Daniel Stenberg
31f9d4016d 'Connection: keep-alive' is now understood when sent by a HTTP/1.0 server
as an indication of a persistant connection
2001-03-26 06:19:11 +00:00
Daniel Stenberg
bb601731ea numerous corrections since the 7.7 release 2001-03-24 18:50:55 +00:00
Daniel Stenberg
9a85172896 Colin Watson's man patch as posted to debian bug tracker numer #90281 2001-03-24 18:28:43 +00:00
Daniel Stenberg
a0eb52bee1 two Qs added:
1.5 Who makes cURL?
 1.6 What do you get for making cURL?
2001-03-23 15:28:13 +00:00
Daniel Stenberg
6235a8d969 make should be $(MAKE) 2001-03-23 14:29:10 +00:00
Daniel Stenberg
0d6a87ed7a match the new never-read-body when doing HEAD 2001-03-23 14:26:23 +00:00
Daniel Stenberg
b6241b3c89 curl_setopt() should be curl_easy_setopt() 2001-03-23 09:07:04 +00:00
Daniel Stenberg
1e14f8d4c7 DONT TOUCH the data->url as it may point to read-only memory!!! 2001-03-23 08:24:47 +00:00
Daniel Stenberg
bc5954fe2d updates by SM nttp at iname.com 2001-03-23 08:16:24 +00:00
Daniel Stenberg
02f6894af5 now always stops reading a HEAD reply after all the headers have been returned
RFC 2616, section 9.4 says: "The HEAD method is identical to GET except that
the server MUST NOT return a message-body in the response."
2001-03-23 07:52:45 +00:00
Daniel Stenberg
76576cd1e2 ConnectionExists() wrongly returned TRUE for too many connections if proxy
was not used...
2001-03-23 07:46:14 +00:00
Daniel Stenberg
997672ba9a updated with the new don't-encode-already-encoded-data concept 2001-03-22 20:06:31 +00:00
Daniel Stenberg
ec1f42a154 Treat 302-redirects the same way we treat 303-redirects 2001-03-22 20:02:52 +00:00
Daniel Stenberg
aa1c3bb46d reset the follow location counter in Curl_perform() so that we can follow
new locations on the same connection that was previously followed on
2001-03-22 19:14:35 +00:00
Daniel Stenberg
95f0714ff8 brand new Curl_ prefixes on global symbols 2001-03-22 19:07:38 +00:00
Daniel Stenberg
c050619b36 made it use Curl_ prefixes on global symbols 2001-03-22 18:44:43 +00:00
Daniel Stenberg
58085dbbf6 Jim Drash suggested and I made it not encode what looks like an already
encoded letter (in curl_escape)
2001-03-22 18:06:08 +00:00
Daniel Stenberg
546572da04 7.7 commit 2001-03-22 17:21:07 +00:00
Daniel Stenberg
005536cc28 removed the duplicates! 2001-03-22 15:42:10 +00:00
Daniel Stenberg
3d5b6aa3b0 added escape and unescape 2001-03-22 11:53:12 +00:00
Daniel Stenberg
f8d883355d the new escape/unescape function setup 2001-03-22 11:40:58 +00:00
Daniel Stenberg
c23df41d83 (un)escape, configure hack, betas run fine 2001-03-22 11:24:21 +00:00
Daniel Stenberg
8e7b261984 added how to pronounce curl! ;-) 2001-03-22 11:23:48 +00:00
Daniel Stenberg
08e3d034ef don't mention explicit version 7.8
removed escape/unescape as they're now documented
2001-03-22 11:22:47 +00:00
Daniel Stenberg
2f869f89ff added escape and unescape man pages 2001-03-22 11:22:09 +00:00
Daniel Stenberg
0f310a5001 not exactly new, but documented for 7.7 2001-03-22 10:32:56 +00:00
Daniel Stenberg
ad1abee441 Andrs Garca's problems on the mailing list made me realize that we can't
allow this script to simply detect a gethostbyname_r() if it can't figure
out how to use it. From now on, this script will fail when that happens.
2001-03-22 08:51:24 +00:00
Daniel Stenberg
669709f80e GNUTLS is another new SSL library we can add support for. Anyone? 2001-03-20 10:13:47 +00:00
Daniel Stenberg
ea409d0374 7.7-beta5 commit 2001-03-19 08:42:00 +00:00
Daniel Stenberg
eaaa1a1fd4 test case 39 added, HTTP location and continue 2001-03-19 08:36:08 +00:00
Daniel Stenberg
78b4851da1 Added support for HTTP code 100 continue, as 8.2.3 in RFC2616 defines 2001-03-19 07:47:57 +00:00
Daniel Stenberg
38c47803dd detect if chunked transfers are aborted 2001-03-16 15:45:12 +00:00
Daniel Stenberg
455663ba5e corrected the close to sclose() so that the memdebug stuff works 2001-03-16 15:44:38 +00:00
Daniel Stenberg
efb5d9a403 new directories 2001-03-16 15:22:51 +00:00
Daniel Stenberg
b1a5208e6b removed the CURL_SEPARATORS define 2001-03-16 15:21:26 +00:00
Daniel Stenberg
e6dacd92ec re-generated with the memdebug.h include 2001-03-16 15:20:36 +00:00
Daniel Stenberg
952b3a2c0f added memdebug.h include 2001-03-16 15:19:36 +00:00
Daniel Stenberg
721f9bca84 moved to ../../php/examples/ 2001-03-16 13:45:42 +00:00
Daniel Stenberg
ad4d5fabf8 the PHP examples are moved 2001-03-16 13:44:57 +00:00
Daniel Stenberg
aa860990ad fix the new makefiles in php/ and perl/ 2001-03-16 13:35:45 +00:00
Daniel Stenberg
0fa9135d9f use perl in two ways 2001-03-16 13:35:11 +00:00
Daniel Stenberg
8f0114a4dd Short about the perl interface 2001-03-16 13:34:08 +00:00
Daniel Stenberg
5980c2977b filled in 2001-03-16 13:30:56 +00:00
Daniel Stenberg
19f8d71508 for the php examples 2001-03-16 13:29:57 +00:00
Daniel Stenberg
6f3bccd911 PHP examples 2001-03-16 13:28:11 +00:00
Daniel Stenberg
96f81a5c4a new PHP section 2001-03-16 13:27:42 +00:00
Daniel Stenberg
ca05d1b59c a perl script that can be used to mirror all curl archives 2001-03-16 13:10:42 +00:00
Daniel Stenberg
895dc5e530 Added README for releases 2001-03-16 13:09:21 +00:00
Daniel Stenberg
bcc6ca6fd1 Added to build proper releases 2001-03-16 13:09:05 +00:00
Daniel Stenberg
d538241a58 Georg Horn's Curl::easy interface for perl 2001-03-16 13:05:39 +00:00
Daniel Stenberg
71b4b2ffa9 moved to contrib/ 2001-03-16 13:05:18 +00:00
Daniel Stenberg
65b4a63f56 moved here from ../ 2001-03-16 13:04:57 +00:00
Daniel Stenberg
ecbee01f4b moved the documentation item to 7.8, it is rather important to have things
documented
2001-03-15 14:45:03 +00:00
Daniel Stenberg
34fed76a35 updated to have the windows builds instructions use the root Makefile that
is delivered with each source archive
2001-03-15 14:44:01 +00:00
Daniel Stenberg
0adf0cfde7 connection timeouts added 2001-03-15 14:38:54 +00:00
Daniel Stenberg
d6c456db85 added connect timeout support 2001-03-15 14:38:30 +00:00
Daniel Stenberg
36c88343d3 Added --connect-timeout support 2001-03-15 14:38:03 +00:00
Daniel Stenberg
2360e5ce12 Added CURLOPT_CONNECTTIMEOUT 2001-03-15 14:37:41 +00:00
Daniel Stenberg
d445eac162 connection timeout is now supported 2001-03-15 14:37:17 +00:00
Daniel Stenberg
e0a6d20e20 Jrn's win32-fix to make it work better 2001-03-15 12:34:40 +00:00
Daniel Stenberg
3bb979b897 corrected it, did I mention IPv6 with HTTP proxy? 2001-03-15 09:14:43 +00:00
Daniel Stenberg
010daec776 Put more concentrated unix install help already at the top, with a note that
you might need to be root to use 'make install'.
2001-03-15 08:38:15 +00:00
Daniel Stenberg
e2b0ad8429 added some text for -d that says it "emulates filling in HTML forms" as that
is what most people will use -d for
2001-03-14 19:48:29 +00:00
Daniel Stenberg
6eed95103a ipv6 adjustments 2001-03-14 18:26:54 +00:00
Daniel Stenberg
4eb2a165e8 removed a bunch of warnings for IPv6-compiles 2001-03-14 18:24:07 +00:00
Daniel Stenberg
b7fc1e45b5 now works with IPv6 and HTTP proxy 2001-03-14 18:18:02 +00:00
Daniel Stenberg
3395a2fa9e netrc fix 2001-03-14 16:59:49 +00:00
Daniel Stenberg
a564a54e21 hm, don't free the home dir and append the .netrc part properly 2001-03-14 16:12:47 +00:00
Daniel Stenberg
92186dc3d3 checks for a few functions and include files more for the new getpwuid()
stuff in lib/netrc.c
2001-03-14 16:05:31 +00:00
Daniel Stenberg
7bd6507eec uses getpwuid() to find user's home dir 2001-03-14 16:05:00 +00:00
Daniel Stenberg
d4cc810de3 added a missing \ 2001-03-14 14:35:35 +00:00
Daniel Stenberg
bea7bbee1b always append the incoming request to the server.input file, it allows
the mainscript to verify a whole series of requests
2001-03-14 14:26:56 +00:00
Daniel Stenberg
fe64570d5d updated to work with the modified http server 2001-03-14 14:26:16 +00:00
Daniel Stenberg
df6ad8d8d6 Added test case 38 2001-03-14 14:25:57 +00:00
Daniel Stenberg
f8e1fc32de Edin Kadribaic's bug report #408488 forced a rearrange of two struct fields
from urldata to connectdata, quite correctly.
2001-03-14 14:11:11 +00:00
Daniel Stenberg
8c6d56f1f9 Added the --egd-file and --random-file options 2001-03-14 11:47:55 +00:00
Daniel Stenberg
1841c8ee6a curl 7.7 beta 3 2001-03-14 11:25:44 +00:00
Daniel Stenberg
70793595fe removed the two unnecessary include files 2001-03-14 10:27:13 +00:00
Daniel Stenberg
28a8e1602d ssluse fixed, various win32 fixes 2001-03-14 10:21:52 +00:00
Daniel Stenberg
cce05b9138 Bjrn Stenberg corrected the silly '(void)data' usage when SSL is not
used
2001-03-14 10:15:42 +00:00
Daniel Stenberg
72a7fd4dc7 Jrn's updated file 2001-03-14 10:06:23 +00:00
Daniel Stenberg
9a6a476cf5 the URL escape/unescape functions are also public but undocumented 2001-03-14 08:59:34 +00:00
Daniel Stenberg
5d0efedd2d First Jrn's updates were applied, then
my take at removing the private functions from the list, then I renamed
the *str(n)equal functions...
2001-03-14 08:58:36 +00:00
Daniel Stenberg
a426818a78 no longer includes the curl/types.h and curl/easy.h include files
explicitly, as they're taken care of indirectly by curl/curl.h these
days.
2001-03-14 08:55:17 +00:00
Daniel Stenberg
bfe413d8bd increased the 'current' number for the interface 2001-03-14 08:54:18 +00:00
Daniel Stenberg
dbbd20646f Curl_str(n)equal renamed to curl_str(n)equal 2001-03-14 08:53:31 +00:00
Daniel Stenberg
b8fe4deb13 documented the undocumented public functions in libcurl 2001-03-14 08:51:04 +00:00
Daniel Stenberg
332a016e3c chunked bugfix, Jrn's fixes, the interface number increase 2001-03-14 08:49:11 +00:00
Daniel Stenberg
3738e4bdc0 The Curl_* prefixes are now changed for curl_* ones, as these two functions
are used externally and thus are public symbols.
2001-03-14 08:47:56 +00:00
Daniel Stenberg
3201d2dafa Jrn added "#define socklen_t int" 2001-03-14 08:28:54 +00:00
Daniel Stenberg
0a1e002ca4 Jrn fixed it to compile on win32 again 2001-03-14 08:28:19 +00:00
Daniel Stenberg
9195bb64d4 Jrn Hartroth added a set of files 2001-03-14 08:23:51 +00:00
Daniel Stenberg
11ee547a0e Jrn Hartroth fixed a bad #endif placement 2001-03-14 08:20:41 +00:00
Daniel Stenberg
147de35d41 re-added the default switch for weird states 2001-03-13 23:29:53 +00:00
Daniel Stenberg
e16e9b91ae removed the random seeding and persistant stuff, as both are already in
this version!
2001-03-13 22:31:56 +00:00
Daniel Stenberg
f9cde0646f Added a failf() error message when the chunked read returns failure 2001-03-13 22:20:14 +00:00
Daniel Stenberg
195233ed5c updated the chunked state-machine to deal with the trailing CRLF that comes
after the data part
2001-03-13 22:16:42 +00:00
Daniel Stenberg
048e654514 made 'X to Y' sequences not include X twice 2001-03-13 22:14:53 +00:00
Daniel Stenberg
dfbd45142d corrected the chunked format 2001-03-13 22:13:06 +00:00
Daniel Stenberg
ff681f7bfd 7.7 beta 2 fixes 2001-03-13 15:44:31 +00:00
Daniel Stenberg
60bbb64a81 EXTRA_DIST got too long, I shortened it now but we have to do something
else as it will grow a lot more...
2001-03-13 13:31:14 +00:00
Daniel Stenberg
c622f2bb4e failf() now respects the mute flag 2001-03-13 13:22:58 +00:00
Daniel Stenberg
cd59f13da6 Guenole Bescon's bug found on march 8 is added 2001-03-13 13:14:21 +00:00
Daniel Stenberg
11d718bf52 exchanged I and me to we and us in a lot of places
updated for persistant connections and 7.7
2001-03-13 11:47:30 +00:00
Daniel Stenberg
8e8846d876 Added test case 37, HTTP GET with name+password in the URL 2001-03-13 09:44:09 +00:00
Daniel Stenberg
7d562bb685 a whole new section on persitant connections and how they're treated
internally
2001-03-13 08:16:54 +00:00
Daniel Stenberg
20ddd35669 we speak HTTP 1.1 now
more braging about the portability
2001-03-13 08:16:25 +00:00
Daniel Stenberg
063f88cd14 close policies 2001-03-13 07:59:19 +00:00
Daniel Stenberg
87b0b7cab9 initial close policy support 2001-03-13 07:54:18 +00:00
Daniel Stenberg
70d0d9d4da Added 'created' to the connectdata struct to hold the creation date, to
be used for the close policy decision
2001-03-13 07:53:59 +00:00
Daniel Stenberg
4ae3bd71ea Curl_tvnow is now properly declared with (void) 2001-03-13 07:53:06 +00:00
Daniel Stenberg
a9390665b8 curl_getinfo is removed, not a public function 2001-03-13 07:46:19 +00:00
Daniel Stenberg
fb7a6e3423 added --random-file and --egd-file to the command line client 2001-03-12 16:02:29 +00:00
Daniel Stenberg
cc99e3f7de Added the two new seeding options 2001-03-12 15:52:18 +00:00
Daniel Stenberg
e6b40bb6ac two new random seed options for the ssl config struct 2001-03-12 15:47:41 +00:00
Daniel Stenberg
f2fd1b8856 two new random seed options: CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET 2001-03-12 15:47:17 +00:00
Daniel Stenberg
cb4efcf275 better chunked error detection 2001-03-12 15:29:04 +00:00
Daniel Stenberg
56a27d608a Added test case 36:
[HTTP GET with badly formatted chunked Transfer-Encoding]
2001-03-12 15:27:01 +00:00
Daniel Stenberg
46c9075eab updated the comment for the chunked reading 2001-03-12 15:21:11 +00:00
Daniel Stenberg
d95fa648e9 made it return illegal hex in case no hexadecimal digit was read when at
least one was expected
2001-03-12 15:20:35 +00:00
Daniel Stenberg
563ad213dc added an error code for illegal hex values in the chunked stream 2001-03-12 15:20:02 +00:00
Daniel Stenberg
0121d7d731 Added new libcurl options in include/curl/curl.h, they're documented in
curl_easy_setopt.3 and they're partly implemented in lib/url.c

Slowly, we're getting there...
2001-03-12 15:11:38 +00:00
Daniel Stenberg
8495fac1c5 Added options for the persistant support, they're also documented in
curl_easy_setopt.3 now
2001-03-12 15:06:29 +00:00
Daniel Stenberg
38c349f751 support for a few new libcurl 7.7 CURLOPT_* options added 2001-03-12 15:05:54 +00:00
Daniel Stenberg
542df800ab Added four new options that come with the new persitant support:
CURLOPT_MAXCONNECTS, CURLOPT_CLOSEPOLICY, CURLOPT_FRESH_CONNECT and
CURLOPT_FORBID_REUSE
2001-03-12 14:54:00 +00:00
Daniel Stenberg
3e88b1cac5 the client is adjusted to work with persistant curl handles, and *gee* it
seems to be working!!!
2001-03-12 13:59:38 +00:00
Daniel Stenberg
d774b10afb Added infof() calls for persistant connection info, we are very likely to
need these at least for debugging 7.7 and probably later as well...
2001-03-12 13:58:03 +00:00
Daniel Stenberg
b449b94393 moved the libcurl init call 2001-03-12 13:57:02 +00:00
Daniel Stenberg
a6cb9b08b2 persistant updates 2001-03-12 13:55:06 +00:00
Daniel Stenberg
440a3101d0 added a note about persitant connections through HTTP proxies 2001-03-12 13:54:46 +00:00
Daniel Stenberg
9778a5356b Added some persistant notes 2001-03-12 13:54:10 +00:00
Daniel Stenberg
de7dcdbc54 modified to make the curl client with persistant connection support do
correct
2001-03-12 13:47:07 +00:00
Daniel Stenberg
070968abbc include the failed test case numbers in the end summary 2001-03-12 13:46:23 +00:00
Daniel Stenberg
e97fc2aab5 Added description of the new test case ranges support 2001-03-12 12:58:57 +00:00
Daniel Stenberg
a23ac24192 made it support test case ranges on the command line, specified as
"X to Y", where X is smaller than Y.
2001-03-12 12:58:30 +00:00
Daniel Stenberg
9ee14644a7 adjusted to work with the HTTP 1.1-speaking libcurl 2001-03-12 12:45:12 +00:00
Daniel Stenberg
c576e114b9 output the protocol data to stderr when verbose is on 2001-03-12 12:44:44 +00:00
Daniel Stenberg
639a7982ba server problems,
libcurl *works* persistant over HTTP proxy!!!!
2001-03-12 10:18:01 +00:00
Daniel Stenberg
5bbe189420 modified Curl_disconnect() so that it unlinks itself from the data struct,
it saves me from more mistakes when the connectindex is -1 ... also, there's
no point in having its parent do it as all parents would do it anyway.
2001-03-12 10:13:42 +00:00
Daniel Stenberg
93ff159e32 split up the big printf() into several ones to never use strings longer
than 509 letters (as newer gcc warns on with -Wall)
2001-03-12 09:47:23 +00:00
Daniel Stenberg
8eb8a0a8e4 bugfix: don't use the connectindex if it is -1 2001-03-12 09:44:57 +00:00
Daniel Stenberg
a4af638867 added persistant connection details 2001-03-12 09:44:08 +00:00
Daniel Stenberg
75a9a87ec2 replaced I and my with we and us 2001-03-12 09:43:43 +00:00
Daniel Stenberg
b5ba011110 updated 2001-03-12 09:42:22 +00:00
Daniel Stenberg
e9b763ff05 use the new name and hostname even though an old connection is reused, since
we can re-use a proxy connection that actually has different host names on
the same connection
2001-03-09 16:50:08 +00:00
Daniel Stenberg
ac0bad2433 remake Host: for each connection and it'll work with proxies too 2001-03-09 16:48:18 +00:00
Daniel Stenberg
67d5c0a970 for HTTP/1.0 we default to non keep-alive connections, but when we get a
1.0-reply from a proxy we use and the Proxy-Connection: keep-alive header
is used, we switch it on and live happily ever after
2001-03-09 16:02:59 +00:00
Daniel Stenberg
580896d615 Added httpversion to the progress struct, we do read it, we can just as well
store it.
2001-03-09 15:58:36 +00:00
Daniel Stenberg
11693c0faa the socklen_t check is more involved now, but works on linux at least 2001-03-09 15:38:59 +00:00
Daniel Stenberg
26cd8eda4a Added socklen_t 2001-03-09 15:24:33 +00:00
Daniel Stenberg
8cd3f44040 added a check for socklen_t
removed the tiny/Makefile that was added accidentaly before
2001-03-09 15:21:00 +00:00
Daniel Stenberg
2b30bfc349 all comments for the former public "low level" interface have been removed
since they were out-of-date and not correct anymore.

moved around some struct fields
2001-03-09 15:19:42 +00:00
Daniel Stenberg
8ec4dba599 removed handles and states from the main structs
renamed prefixes from curl_ to Curl_
made persistant connections work with http proxies (at least partly)
2001-03-09 15:18:25 +00:00
Daniel Stenberg
1efec6572e curl_transfer became Curl_perform() to better match the public name and
use the correct prefix
2001-03-09 15:17:09 +00:00
Daniel Stenberg
781dd7a9bf prefix changes curl_ to Curl_
made it work (partly) with persistant connections for HTTP/1.0 replies
moved the 'newurl' struct field for Location: to the connectdata struct
2001-03-09 15:16:28 +00:00
Daniel Stenberg
beb8761b22 #include <string.h> removed a warning 2001-03-09 15:14:51 +00:00
Daniel Stenberg
071c7de9fe removed curl_read() and curl_write() - they weren't used and the public
"low leve" interface is dumped
2001-03-09 15:14:22 +00:00
Daniel Stenberg
3e7ebcd051 uses socklen_t now 2001-03-09 15:13:34 +00:00
Daniel Stenberg
c67952fc5c curl_ prefix modified to Curl_ 2001-03-09 15:13:11 +00:00
Daniel Stenberg
7d7c24f915 accept() and getsockname() now use socklen_t types, as that was just added
to configure
2001-03-09 15:12:22 +00:00
Daniel Stenberg
0dc8c4d451 use unsigned int hex to receive the hex digit in, caused a warning with
-Wall and a new gcc
2001-03-09 15:11:39 +00:00
Daniel Stenberg
9cf4434ae2 Modified to use Curl_* functions instead of curl_* ones 2001-03-09 15:10:58 +00:00
Daniel Stenberg
8ccd8b6dbc only generate maximum 509 characters in each string 2001-03-09 13:11:28 +00:00
179 changed files with 6994 additions and 2231 deletions

429
CHANGES
View File

@@ -6,11 +6,420 @@
History of Changes History of Changes
Version 7.7.3-pre1
Daniel (4 May 2001)
- All callback functions now take 'void *' instead of 'FILE *'. This is made
this way to make it more obvious to people that anything can be passed to
them (by using the apropriate option). After discussions with Sterling
Hughes.
Daniel (3 May 2001)
- Cris Bailiff fixed a chunked transfer encoding problem with persistent
connection that made libcurl fail if the persistent connection used mixed
chunked and non-chunked transfers.
- Cris Bailiff fixed a bad treatment of 304-replies, as they would not be
treated as content-length 0 replies but would cause a "hang" until the
server timed-out and closed the connection.
- Brad Burdick found a minor problem in the docs/examples/Makefile.am
Daniel (27 April 2001)
- Updated the INTERALS document again. It was lagging a bit. I think I made it
more easy to follow now as well.
- Brad Burdick found a problem with persistent connections when curl received
a "Content-Length: 0" header.
- Giuseppe D'Ambrosio was first out to report that TELNET doesn't work in curl
compiled/built on win32. It seems to work for unixes though!
- Dave Hamilton reported weird problems with CURL/PHP that I really can't
explain at the moment. I'm hoping on some help from the PHP crew.
Daniel (26 April 2001)
- I rewrote the FTP command response function. I had to do it to make ftps
work, as the OpenSSL read()-function didn't work the same way the normal
unix read() does, but it was also a huge performance boost. Previously the
function read one byte at a time, now it reads very large chunks, and it
makes a notable speed difference.
Daniel (25 April 2001)
- Connection re-use when not using a proxy didn't work properly for
non-default port numbers.
Daniel (24 April 2001)
- I've noticed that FTPS doesn't work. We attempt to use ssl even for the
data transfer, which causes the transfer to 'hang'... We need to fix this.
- Improved the test suite to use 'stunnel' to do HTTPS and FTPS testing on
the alredy written perl servers easily.
Daniel (23 April 2001)
- The OpenSSL version string recently modified didn't zero terminate one
of the generated strings properly, which could lead to a crash or simply
weird version string output!
Version 7.7.2
Daniel (22 April 2001)
- Rosimildo da Silva updated the Makefiles for Borland/Windows.
- Eric Rautman pointed out a problem with persistent connections that would
lead to broken Host: headers in the second HTTP request.
Daniel (20 April 2001)
- Added man pages for the curl_strequal() and curl_mprintf() families. Wrote
a 'libcurl overview' man page.
- Spell-fixed some documents.
- S. Moonesamy corrected mistakes in the man page.
- Cris Bailiff fixed the curl_slists options in the perl interface, present
separately in the Curl::easy 1.1.4 package.
Daniel (19 April 2001)
- Linus Nielsen Feltzing removed the decimals from the size variables in the
--write-out output. We hardly ever get fraction of bytes! :-)
Version 7.7.2-pre1
Daniel (19 April 2001)
- Albert Chin provided a configure patch for the AC_SYS_LARGEFILE macro.
Daniel (18 April 2001)
- Input from Michael Mealling made me add --feature to curl-config. It
displays a list of features that have been built-in in the current
libcurl. The currently available features that can be listed are: SSL, KRB4
and IPv6.
- I committed Cris and Georg's perl interface work. They've got callbacks
working and options that receives those slist pointers.
- Puneet Pawaia detected a problem with resumed downloads that use persistent
connections and I made a rather large writeup to correct this. It is
important that all session-data is stored in the connectdata struct and not
in the main struct as this previously did.
Daniel (17 April 2001)
- Frederic Lepied fixed a ftp resumed download problem and introduced a new
error code that lets applications be able to detect when a resumed download
actually didn't download anything since the whole file is already present.
Should this return OK instead?
- I added 'curl-config.in' to the root dir and configure script. Now, a
curl-config script is made when curl is built. The script can be used to
figure out compile time options used when libcurl was built, which in turn
should be options YOU should use to build applications that use libcurl.
This *-config style is not a new idea, but something that has been used
successfully in other (library based) projects.
- Phil Karn pointed out that libcurl wrongly did not always use GMT time zone
for the If-Modified-Since style headers.
- Georg Schwarz pointed out an extra needed #include file needed in src/main.c
for curl to build on Ultrix.
Daniel (11 April 2001)
- Cris Bailiff pointed out two problems that I corrected. First, libcurl's use
of the environment variable HTTP_PROXY in uppercase may become a security
hazard when people use libcurl in a server/cgi situation where the server
sets the HTTP_*-variables according to incoming headers in the HTTP
request. Thus, a "Proxy:"-header would set that environment variable!
Then, invoking curl_easy_perform() without having an URL set caused a crash.
- S. Moonesamy brought a patch that make curl use non-blocking connects on
windows when connection timeout is set, as it allows windows users to set
that timeout!
- Hirotaka Matsuyuki wrote a Ruby interface to libcurl!
- Cris Bailiff, Forrest Cahoon and Georg Horn work on the Perl interface.
- I've written a first shot at a Java interface to libcurl. Many thanks to
Daniel Marell for tirelessly answering to all my basic Java questions. It
works, but it is still very basic.
Daniel (10 April 2001)
- The progress display could get silly when doing multiple file transfers, as
it wasn't properly reset between transfers!
- Discussions with Cris Bailiff who writes a Perl interface to libcurl, made
me add CURLOPT_HEADERFUNCTION. It can be used to set a separate callback
function for writing headers. Previously you could only set a different FILE
* when headers are written from within libcurl.
Daniel (7 April 2001)
- Andr<64>s Garc<72>a fixed a problem in curl_escape() and pointed out a flaw in
the curl_easy_setopt man page.
Daniel (6 April 2001)
- Adjusted the version code to properly display OpenSSL 0.9.6a. They sure
change their version define format often...
- curl_formfree() now accepts a NULL pointer without crashing!
Version 7.7.1
Daniel (3 April 2001)
- Puneet Pawaia pointed out two serious problems. Libcurl would attempt to
read bad memory during situations when an (ftp) connection attempt failed.
Also, the lib/Makefile.vc6 was corrected.
- More investigations in the Location: following code made me realize that
it was not clean enough to work transparantly with persistent and non-
persistent connections. I think I've fixed it now.
Daniel (29 March 2001)
- Georg Horn mailed me some corrections for the Curl::easy perl interface.
- Experimental ftps:// support added. It is basically FTP over SSL for the
control connection. It still makes all data transfers going over unencrypted
connections. Rainer Weikusat's ftpd-ssl server hack supports this and I used
that to verify the functionality.
Daniel (27 March 2001)
- Guenole Bescon discovered that if you set a CURLOPT_TIMEOUT and then tried
to get a file from a site and it fails, the SIGALRM would still be sent
after the timeout-time, quite inexpectedly!
- I added an ftp transfer example to docs/examples/ and I also wrote a tiny
example makefile that can be used as a start when building one of the
examples.
Version 7.7.1-beta1
Daniel (26 March 2001)
- Mohamed Lrhazi reported problems with 7.6.1 and persistent HTTP/1.0
connections (when the server replied a Connection: Keep-Alive) and this
problem was not properly dealt with in 7.7 either. A patch was posted to the
curl-and-php mailing list.
Daniel (24 March 2001)
- Colin Watson reported about a problem and brought a patch that corrected it,
which was about the man page and lines starting with a single quote (') in a
way that gnroff doesn't like.
Daniel (23 March 2001)
- Peter Bray reported correctly that the root makefile used make instead of
$(MAKE) for the test target.
- Corrected the Curl::easy perl interface to use curl_easy_setopt() and not
curl_setopt() which was removed in 7.7!
- S. Moonesamy provided updates on three documents (MANUAL, INSTALL and FAQ).
- When following a Location:, libcurl would sometimes write to the URL string
in a way it shouldn't. As the pointer is passed-in to libcurl from an
application, we can't be allowed to write to it. The particular bug report
from 'nk' that brought this up was because he had a read-only URL that then
caused a libcurl crash!
- No longer reads HEAD responses longer than to the last header. Previously,
curl would read the full reply if the connection was a "close" one.
- libcurl did re-use connections way too much. Doing "curl
http://www.{microsoft,ibm}.com" would make it re-use the connection which
made the second request return very odd results.
Daniel (22 March 2001)
- Edin Kadribasic made me aware that curl should not re-send POST requests
when following 302-redirects. I made 302 work like 303 which means curl uses
GET in the following request(s).
- libcurl now reset the "followed-location" counter on each invoke of
curl_easy_perform() as it otherwise would sum up all redirects on the same
connection and thus could reach the maxredirs counter wrongly.
- Jim Drash suggested curl_escape() should not re-encode what already looks
like an encoded sequence and I think that's a fair suggestion.
Version 7.7
Daniel (22 March 2001)
- The configure script now fails with an error message if gethostbyname_r() is
detected but it couldn't figure out how to invoke it (what amount of
arguments it is supposed to get). Reports from Andr<64>s Garc<72>a made me aware
of this need.
- Talking with Jim Drash made me finally put the curl_escape and curl_unescape
functions in the curl.h include file and write man pages for them. The
escape function was modified to use the same interface as the unescape one
had.
- No bug reports at all on the latest betas. Release time coming up.
Version 7.7-beta5
Daniel (19 March 2001)
- Georg Ottinger reported problems with using -C together with -L in the sense
that the -C info got lost when it was redirected. I could not repeat this
problem on the 7.7 branch why I leave this for the moment. Test case 39 was
added to do exactly this, and it seems to do right.
- Christian Robottom Reis reported how his 7.7 beta didn't successfully do
form posts as elegantly as 7.6.1 did. Indeed, this was a flaw in the header
engine, as HTTP 1.1 has introduced a new 100 "transient" return code for PUT
and POST operations that I need to add support for. Section 8.2.3 in RFC2616
has all the details. Seems to work now!
Daniel (16 March 2001)
- After having experienced another machine break-down, we're back.
- Georg Horn's perl interface Curl::easy is now included in the curl release
archive. The perl/ directory is now present. Please help me with docs,
examples and updates you think fit.
- Made a new php/ directory in the release archive and moved the PHP examples
into a subdirectory in there. Not much PHP info yet, but I plan to. Please
help me here as well!
- Made libcurl return error if a transfer is aborted in the middle of a
"chunk". It actually enables libcurl to discover premature transfer aborts
even if the Content-Length: size is unknown.
Daniel (15 March 2001)
- Added --connect-timeout to curl, which sets the new CURLOPT_CONNECTTIMEOUT
option in libcurl. It limits the time curl is allowed to spend in the
connection phase. This differs from -m/--max-time that limits the entire
file transfer operation. Requested by Larry Fahnoe and others.
I also updated the curl.1 and curl_easy_setopt.3 man pages and removed the
item from the TODO.
Version 7.7-beta4
Daniel (14 March 2001)
- Made curl grok IPv6 with HTTP proxies and got everything to compile nicely
again when ENABLE_IPV6 is set.
I need to remake things in the test suite. I can't test the FTP parts with
curl built for IPv6 as it uses a different set of FTP commands then!
- I fell onto a bug report on php.net (posted by Lars Torben Wilson) that was
a report meant for our project. Anyway, it said the .netrc parsing didn't
work as supposed, and as I agreed with Lars, I made the netrc parser use
getpwuid() to figure out the home directory of the effective user and try
that netrc. It still uses the environment variable HOME for those that don't
have that function or if the user doesn't return valid pwd info.
- Edin Kadribaic posted a bug report where he got a crash when a fetch with
user+password in the URL followed a Location: to a second URL (absolute,
without name+password). This bug has been around for a long while and
crashes due to a read at address zero. Fixed now. Wrote test case 38, that
tests this.
- Modified the test suite's httpserver slightly to append all client request
data to its log file so that the test script now better can verify a range
of requests and not only the last one, as it did previously.
- Updated the curl man page with --random-file and --egd-file details.
Version 7.7-beta3
Daniel (14 March 2001)
- Bj<42>rn Stenberg provided similar fixes as J<>rn did and some additional patches
for non-SSL compiles.
- I increased the interface number for libcurl as I've removed the low level
functions from the interface. I also took this opportunity to rename the
Curl_strequal function to curl_strequal and Curl_strnequal to
curl_strnequal, as they're public libcurl functions (even if they're still
undocumented).
This will make older programs not capable of using the new libcurl with
just a drop-in replacement.
- J<>rn Hartroth updated stuff for win32 compiles:
o config-win32.h was fixed for socklen_t
o lib/ssluse.c had a bad #endif placement
o lib/file.c was made to compile on win32 again
o lib/Makefile.m32 was updated with the new files
o lib/libcurl.def matches the current interface state
Daniel (13 March 2001)
- It only took an hour or so before J<>rn Hartroth found a problem in the
chunked transfer-encoding. Given his fine example-site, I could easily spot
the problem and when I re-read the spec (the part I have pasted in the top
of the http_chunks.h file), I realized I had made my state-machine slightly
wrong and didn't expect/handle the trailing CRLF that comes after the data
in each chunk (and those extra two bytes sure feel wasted).
Had to modify test case 34 to match this as well.
Version 7.7-beta2
Daniel (13 March 2001)
- Added the policy stuff to the curl_easy_setopt man page for the two supported
policies.
- Implemented some support for the CURLOPT_CLOSEPOLICY option. The policies
CURLCLOSEPOLICY_LEAST_RECENTLY_USED and CURLCLOSEPOLICY_OLDEST are now
supported, and the "least recently used" is used as default if no policy
is chosen.
Daniel (12 March 2001)
- Added CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET to libcurl for seeding the
SSL random engine. The random seeding support was also brought to the curl
client with the new options --random-file <file> and --egd-file <file>. I
need some people to really test this to know they work as supposed. Remember
that libcurl now informs (if verbose is on) if the random seed is considered
weak (HTTPS connections).
- Made the chunked transfer-encoding engine detected bad formatted data length
and return error if so (we can't possibly extract sensible data if this is
the case). Added a test case that detects this. Number 36. Now there are 60
test cases.
- Added 5 new libcurl options to curl/curl.h that can be used to control the
persistent connection support in libcurl. They're also documented (fairly
thoroughly) in the curl_easy_setopt.3 man page. Three of them are now
implemented, although not really tested at this point... Anyway, the new
implemented options are named CURLOPT_MAXCONNECTS, CURLOPT_FRESH_CONNECT,
CURLOPT_FORBID_REUSE. The ones still left to write code for are:
CURLOPT_CLOSEPOLICY and its related option CURLOPT_CLOSEFUNCTION.
- Made curl (the actual command line tool) use the new libcurl 7.7 persistent
connection support by re-using the same curl handle for every specified file
transfer and after some more test case tweaking we have 100% test case OK.
I made some test cases return HTTP/1.0 now to make sure that works as well.
- Had to add 'Connection: close' to the headers of a bunch of test cases so
that curl behaves "old-style" since the test http server doesn't do multiple
connections... Now I get 100% test case OK.
- The curl.haxx.se site, the main curl mailing list and my personal email are
all dead today due to power blackout in the area where the main servers are
located. Horrible.
- I've made persistance work over a squid HTTP proxy. I find it disturbing
that it uses headers that aren't present in any HTTP standard though
(Proxy-Connection:) and that makes me feel that I'm now on the edge of what
the standard actually defines. I need to get this code excercised on a lot
of different HTTP proxies before I feel safe.
Now I'm facing the problem with my test suite servers (both FTP and HTTP)
not supporting persistent connections and libcurl is doing them now. I have
to fix the test servers to get all the test cases do OK.
Daniel (8 March 2001)
- Guenole Bescon reported that libcurl did output errors to stderr even if
MUTE and NOPROGRESS was set. It turned out to be a bug and happens if
there's an error and no ERRORBUFFER is set. This is now corrected.
Version 7.7-beta1
Daniel (8 March 2001) Daniel (8 March 2001)
- "Transfer-Encoding: chunked" is no longer any trouble for libcurl. I've - "Transfer-Encoding: chunked" is no longer any trouble for libcurl. I've
added two source files and I've run some test downloads that look fine. added two source files and I've run some test downloads that look fine.
- HTTP HEAD works too, even on 1.1 servers.
Daniel (5 March 2001) Daniel (5 March 2001)
- The current 57 test cases now pass OK. It would suggest that libcurl works - The current 57 test cases now pass OK. It would suggest that libcurl works
using the old-style with one connection per handle. The test suite doesn't using the old-style with one connection per handle. The test suite doesn't
@@ -36,7 +445,7 @@ Daniel (2 March 2001)
- Now they work intermixed as well. Major coolness! - Now they work intermixed as well. Major coolness!
- More fiddling around, my 'tiny' client I have for testing purposes now has - More fiddling around, my 'tiny' client I have for testing purposes now has
proved to download both FTP and HTTP with persistant connections. They do proved to download both FTP and HTTP with persistent connections. They do
not work intermixed yet though. not work intermixed yet though.
Daniel (1 March 2001) Daniel (1 March 2001)
@@ -45,7 +454,7 @@ Daniel (1 March 2001)
now. now.
Daniel (22 February 2001) Daniel (22 February 2001)
- The persistant connections start to look good for HTTP. On a subsequent - The persistent connections start to look good for HTTP. On a subsequent
request, it seems that libcurl now can pick an already existing connection request, it seems that libcurl now can pick an already existing connection
if a suitable one exists, or it opens a new one. if a suitable one exists, or it opens a new one.
@@ -70,7 +479,7 @@ Daniel (20 February 2001)
mailing lists for discussions around how this is gonna be implemented. Docs mailing lists for discussions around how this is gonna be implemented. Docs
and more will follow. and more will follow.
Studied the HTTP RFC to find out better how persistant connections should Studied the HTTP RFC to find out better how persistent connections should
work. Seems cool enough. work. Seems cool enough.
Daniel (19 February 2001) Daniel (19 February 2001)
@@ -89,9 +498,9 @@ Daniel (15 February 2001)
string switches off the POST again. string switches off the POST again.
- Excellent suggestions from Rich Gray, Rick Jones, Johan Nilsson and Bjorn - Excellent suggestions from Rich Gray, Rick Jones, Johan Nilsson and Bjorn
Reese helped me define a way how to incorporate persistant connections into Reese helped me define a way how to incorporate persistent connections into
libcurl in a very smooth way. If done right, no change may have to be made libcurl in a very smooth way. If done right, no change may have to be made
to older programs and they will just start using persistant connections when to older programs and they will just start using persistent connections when
applicable! applicable!
Daniel (13 February 2001) Daniel (13 February 2001)
@@ -125,16 +534,16 @@ Daniel (8 February 2001)
Version 7.6.1-pre3 Version 7.6.1-pre3
Daniel (7 February 2001) Daniel (7 February 2001)
- SM found a flaw in the response reading function for FTP that could make - S. Moonesamy found a flaw in the response reading function for FTP that
libcurl not get out of the loop properly when it should, if libcurl got -1 could make libcurl not get out of the loop properly when it should, if
returned when reading the socket. libcurl got -1 returned when reading the socket.
- I found a similar mistake in http.c when using a proxy and reading the - I found a similar mistake in http.c when using a proxy and reading the
results from the proxy connection. results from the proxy connection.
Daniel (6 February 2001) Daniel (6 February 2001)
- A friendly person named "SM" (nntp at iname.com) pointed out that the VC - S. Moonesamy pointed out that the VC makefile in src/ needed the libpath set
makefile in src/ needed the libpath set for the debug build to work. for the debug build to work.
- Daniel Gehriger stepped in to assist with the VC++ stuff Robert Weaver - Daniel Gehriger stepped in to assist with the VC++ stuff Robert Weaver
brought up yesterday. brought up yesterday.

View File

@@ -1,22 +1,32 @@
This file is only present in the CVS - never in release archives. _ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
This contains information about other files and things that the CVS repository CVS-INFO
keeps in its inner sanctum.
CHANGES.0 contains ancient changes. This file is only present in the CVS - never in release archives. It contains
information about other files and things that the CVS repository keeps in its
inner sanctum.
memanalyze.pl is for analyzing the output generated by curl if -DMALLOCDEBUG
is used when compiling
Makefile.dist is included as the root Makefile in distribution archives
perl/ is a subdirectory with various perl scripts CHANGES.0 contains ancient changes.
memanalyze.pl is for analyzing the output generated by curl if -DMALLOCDEBUG
is used when compiling
buildconf builds the makefiles and configure stuff
Makefile.dist is included as the root Makefile in distribution archives
perl/contrib/ is a subdirectory with various perl scripts
java is a subdirectory with the Java interface to libcurl
To build after having extracted everything from CVS, do this: To build after having extracted everything from CVS, do this:
automake ./buildconf
aclocal
autoheader
autoconf
./configure ./configure
make make

View File

@@ -8,7 +8,9 @@ EXTRA_DIST = \
CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt \ CHANGES LEGAL maketgz MITX.txt MPL-1.1.txt \
config-win32.h reconf packages/README Makefile.dist config-win32.h reconf packages/README Makefile.dist
SUBDIRS = docs lib src include tests packages bin_SCRIPTS = curl-config
SUBDIRS = docs lib src include tests packages perl php
# create a root makefile in the distribution: # create a root makefile in the distribution:
dist-hook: dist-hook:
@@ -17,7 +19,7 @@ dist-hook:
check: test check: test
test: test:
@(cd tests; make quiet-test) @(cd tests; $(MAKE) quiet-test)
# #
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros # Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros

View File

@@ -30,16 +30,16 @@ ssl:
make make
borland: borland:
cd lib; make -f Makefile.b32 cd lib & make -f Makefile.b32
cd src; make -f Makefile.b32 cd src & make -f Makefile.b32
mingw32: mingw32:
cd lib; make -f Makefile.m32 cd lib & make -f Makefile.m32
cd src; make -f Makefile.m32 cd src & make -f Makefile.m32
mingw32-ssl: mingw32-ssl:
cd lib; make -f Makefile.m32 SSL=1 cd lib & make -f Makefile.m32 SSL=1
cd src; make -f Makefile.m32 SSL=1 cd src & make -f Makefile.m32 SSL=1
vc: vc:
cd lib cd lib

2
README
View File

@@ -12,7 +12,7 @@ README
document. document.
libcurl is a library that Curl is using to do its job. It is readily libcurl is a library that Curl is using to do its job. It is readily
available to be used by your software. Read the LIBCURL document to available to be used by your software. Read the libcurl.5 man page to
find out how! find out how!
You find answers to the most frequent questions we get in the FAQ document. You find answers to the most frequent questions we get in the FAQ document.

View File

@@ -43,6 +43,9 @@
/* Define this to 'int' if ssize_t is not an available typedefed type */ /* Define this to 'int' if ssize_t is not an available typedefed type */
#undef ssize_t #undef ssize_t
/* Define this to 'int' if socklen_t is not an available typedefed type */
#undef socklen_t
/* Define this as a suitable file to read random data from */ /* Define this as a suitable file to read random data from */
#undef RANDOM_FILE #undef RANDOM_FILE

View File

@@ -1,4 +1,4 @@
#serial 12 #serial 19
dnl By default, many hosts won't let programs access large files; dnl By default, many hosts won't let programs access large files;
dnl one must use special compiler options to get large-file access to work. dnl one must use special compiler options to get large-file access to work.
@@ -11,7 +11,14 @@ dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_TEST_INCLUDES dnl AC_SYS_LARGEFILE_TEST_INCLUDES
AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES, AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
[[#include <sys/types.h> [[#include <sys/types.h>
int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1]; /* Check that off_t can represent 2**63 - 1 correctly.
We can't simply "#define LARGE_OFF_T 9223372036854775807",
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
# define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
]]) ]])
dnl Internal subroutine of AC_SYS_LARGEFILE. dnl Internal subroutine of AC_SYS_LARGEFILE.
@@ -19,14 +26,11 @@ dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, F
AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE, AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
[AC_CACHE_CHECK([for $1 value needed for large files], $3, [AC_CACHE_CHECK([for $1 value needed for large files], $3,
[$3=no [$3=no
AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES AC_TRY_COMPILE([$5],
$5
,
[$6], [$6],
, ,
[AC_TRY_COMPILE([#define $1 $2] [AC_TRY_COMPILE([#define $1 $2]
AC_SYS_LARGEFILE_TEST_INCLUDES [$5]
$5
, ,
[$6], [$6],
[$3=$2])])]) [$3=$2])])])
@@ -35,7 +39,8 @@ $5
fi]) fi])
AC_DEFUN(AC_SYS_LARGEFILE, AC_DEFUN(AC_SYS_LARGEFILE,
[AC_ARG_ENABLE(largefile, [AC_REQUIRE([AC_PROG_CC])
AC_ARG_ENABLE(largefile,
[ --disable-largefile omit support for large files]) [ --disable-largefile omit support for large files])
if test "$enable_largefile" != no; then if test "$enable_largefile" != no; then
@@ -58,18 +63,30 @@ AC_DEFUN(AC_SYS_LARGEFILE,
AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64, AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
ac_cv_sys_file_offset_bits, ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.]) [Number of bits in a file offset, on hosts where this is settable.],
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1, AC_SYS_LARGEFILE_TEST_INCLUDES)
ac_cv_sys_largefile_source,
[Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
[#include <stdio.h>], [return !ftello;])
AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1, AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
ac_cv_sys_large_files, ac_cv_sys_large_files,
[Define for large files, on AIX-style hosts.]) [Define for large files, on AIX-style hosts.],
dnl lftp does not need ftello, and _XOPEN_SOURCE=500 makes resolv.h fail. AC_SYS_LARGEFILE_TEST_INCLUDES)
dnl AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
dnl ac_cv_sys_xopen_source,
dnl [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
dnl [#include <stdio.h>], [return !ftello;])
fi fi
]) ])
AC_DEFUN(AC_FUNC_FSEEKO,
[AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
ac_cv_sys_largefile_source,
[Define to make fseeko visible on some hosts (e.g. glibc 2.2).],
[#include <stdio.h>], [return !fseeko;])
# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
# in glibc 2.1.3, but that breaks too many other things.
# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
AC_CACHE_CHECK([for fseeko], ac_cv_func_fseeko,
[ac_cv_func_fseeko=no
AC_TRY_LINK([#include <stdio.h>],
[return fseeko && fseeko (stdin, 0, 0);],
[ac_cv_func_fseeko=yes])])
if test $ac_cv_func_fseeko != no; then
AC_DEFINE(HAVE_FSEEKO, 1,
[Define if fseeko (and presumably ftello) exists and is declared.])
fi])

6
buildconf Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
automake
aclocal
autoheader
autoconf

View File

@@ -26,6 +26,9 @@
/* Define this to 'int' if ssize_t is not an available typedefed type */ /* Define this to 'int' if ssize_t is not an available typedefed type */
#define ssize_t int #define ssize_t int
/* Define this to 'int' if socklen_t is not an available typedefed type */
#define socklen_t int
/* Define if you have the ANSI C header files. */ /* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1 #define STDC_HEADERS 1

View File

@@ -82,6 +82,9 @@ void main(void) {
if test "$ac_cv_working_getaddrinfo" = "yes"; then if test "$ac_cv_working_getaddrinfo" = "yes"; then
AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works]) AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works])
AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support]) AC_DEFINE(ENABLE_IPV6, 1, [Define if you want to enable IPv6 support])
IPV6_ENABLED=1
AC_SUBST(IPV6_ENABLED)
fi fi
]) ])
@@ -295,6 +298,14 @@ exit (rc != 0 ? 1 : 0); }],[
[ac_cv_gethostbyname_args=0])], [ac_cv_gethostbyname_args=0])],
[ac_cv_gethostbyname_args=0])]) [ac_cv_gethostbyname_args=0])])
if test "$ac_cv_func_gethostbyname_r" = "yes"; then
if test "$ac_cv_gethostbyname_args" = "0"; then
dnl there's a gethostbyname_r() function, but we don't know how
dnl many arguments it wants!
AC_MSG_ERROR([couldn't figure out how to use gethostbyname_r()])
fi
fi
]) ])
dnl ********************************************************************** dnl **********************************************************************
@@ -498,6 +509,10 @@ then
dnl add define KRB4 dnl add define KRB4
AC_DEFINE(KRB4) AC_DEFINE(KRB4)
dnl substitute it too!
KRB4_ENABLED=1
AC_SUBST(KRB4_ENABLED)
dnl the krb4 stuff needs a strlcpy() dnl the krb4 stuff needs a strlcpy()
AC_CHECK_FUNCS(strlcpy) AC_CHECK_FUNCS(strlcpy)
@@ -564,14 +579,45 @@ else
dnl Check for SSLeay headers dnl Check for SSLeay headers
AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h openssl/pem.h openssl/ssl.h openssl/err.h) AC_CHECK_HEADERS(openssl/x509.h openssl/rsa.h openssl/crypto.h \
openssl/pem.h openssl/ssl.h openssl/err.h)
if test $ac_cv_header_openssl_x509_h = no; then if test $ac_cv_header_openssl_x509_h = no; then
AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h) AC_CHECK_HEADERS(x509.h rsa.h crypto.h pem.h ssl.h err.h)
fi fi
dnl
dnl If all heades are present, we have enabled SSL!
if test "$ac_cv_header_openssl_x509_h" = "yes" &&
test "$ac_cv_header_openssl_rsa_h" = "yes" &&
test "$ac_cv_header_openssl_crypto_h" = "yes" &&
test "$ac_cv_header_openssl_pem_h" = "yes" &&
test "$ac_cv_header_openssl_ssl_h" = "yes" &&
test "$ac_cv_header_openssl_err_h" = "yes"; then
OPENSSL_ENABLED="1";
fi
dnl
dnl Check the alternative headers too
if test "$ac_cv_header_x509_h" = "yes" &&
test "$ac_cv_header_rsa_h" = "yes" &&
test "$ac_cv_header_crypto_h" = "yes" &&
test "$ac_cv_header_pem_h" = "yes" &&
test "$ac_cv_header_ssl_h" = "yes" &&
test "$ac_cv_header_err_h" = "yes"; then
OPENSSL_ENABLED="1";
fi
AC_SUBST(OPENSSL_ENABLED)
fi fi
if test X"$OPT_SSL" != Xoff &&
test "$OPENSSL_ENABLED" != "1"; then
AC_MSG_ERROR([OpenSSL libs and/or directories were not found where specified!])
fi
dnl these can only exist if openssl exists dnl these can only exist if openssl exists
AC_CHECK_FUNCS( RAND_status \ AC_CHECK_FUNCS( RAND_status \
@@ -673,6 +719,7 @@ AC_CHECK_HEADERS( \
winsock.h \ winsock.h \
time.h \ time.h \
io.h \ io.h \
pwd.h
) )
dnl Check for libz header dnl Check for libz header
@@ -693,6 +740,28 @@ AC_CHECK_SIZEOF(long long, 4)
# check for ssize_t # check for ssize_t
AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(ssize_t, int)
dnl
dnl We can't just AC_CHECK_TYPE() for socklen_t since it doesn't appear
dnl in the standard headers. We egrep for it in the socket headers and
dnl if it is used there we assume we have the type defined, otherwise
dnl we search for it with AC_CHECK_TYPE() the "normal" way
dnl
if test "$ac_cv_header_sys_socket_h" = "yes"; then
AC_MSG_CHECKING(for socklen_t in sys/socket.h)
AC_EGREP_HEADER(socklen_t,
sys/socket.h,
socklen_t=yes
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no))
fi
if test "$socklen_t" != "yes"; then
# check for socklen_t the standard way if it wasn't found before
AC_CHECK_TYPE(socklen_t, int)
fi
dnl Get system canonical name dnl Get system canonical name
AC_CANONICAL_HOST AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED(OS, "${host}") AC_DEFINE_UNQUOTED(OS, "${host}")
@@ -724,7 +793,9 @@ AC_CHECK_FUNCS( socket \
sigaction \ sigaction \
signal \ signal \
getpass_r \ getpass_r \
strlcat strlcat \
getpwuid \
geteuid
) )
dnl removed 'getpass' check on October 26, 2000 dnl removed 'getpass' check on October 26, 2000
@@ -765,5 +836,10 @@ AC_OUTPUT( Makefile \
packages/Linux/RPM/Makefile \ packages/Linux/RPM/Makefile \
packages/Linux/RPM/curl.spec \ packages/Linux/RPM/curl.spec \
packages/Linux/RPM/curl-ssl.spec \ packages/Linux/RPM/curl-ssl.spec \
tiny/Makefile ) perl/Makefile \
perl/Curl_easy/Makefile \
php/Makefile \
php/examples/Makefile \
curl-config
)

85
curl-config.in Normal file
View File

@@ -0,0 +1,85 @@
#! /bin/sh
#
# The idea to this kind of setup info script was stolen from numerous
# other packages, such as neon, libxml and gnome.
#
# $Id$
#
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
usage()
{
cat <<EOF
Usage: curl-config [OPTION]
Available values for OPTION include:
--cflags pre-processor and compiler flags
--feature newline separated list of enabled features
--help display this help and exit
--libs library linking information
--prefix curl install prefix
--version output version information
EOF
exit $1
}
if test $# -eq 0; then
usage 1
fi
while test $# -gt 0; do
case "$1" in
# this deals with options in the style
# --option=value and extracts the value part
# [not currently used]
-*=*) value=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) value= ;;
esac
case "$1" in
--prefix)
echo $prefix
;;
--feature)
if test "@OPENSSL_ENABLED@" = "1"; then
echo "SSL"
fi
if test "@KRB4_ENABLED@" = "1"; then
echo "KRB4"
fi
if test "@IPV6_ENABLED@" = "1"; then
echo "IPv6"
fi
;;
--version)
echo libcurl @VERSION@
exit 0
;;
--help)
usage 0
;;
--cflags)
echo @CPPFLAGS@
;;
--libs)
echo @LDFLAGS@ @LIBS@
;;
*)
usage
exit 1
;;
esac
shift
done
exit 0

View File

@@ -6,9 +6,9 @@
BUGS BUGS
Curl has grown substantially from that day, several years ago, when I Curl and libcurl have grown substantially since the beginning. At the time
started fiddling with it. When I write this, there are 16500 lines of source of writing (mid March 2001), there are 23000 lines of source code, and by
code, and by the time you read this it has probably grown even more. the time you read this it has probably grown even more.
Of course there are lots of bugs left. And lots of misfeatures. Of course there are lots of bugs left. And lots of misfeatures.
@@ -21,10 +21,11 @@ BUGS
http://sourceforge.net/bugs/?group_id=976 http://sourceforge.net/bugs/?group_id=976
When reporting a bug, you should include information that will help us When reporting a bug, you should include information that will help us
understand what's wrong, what's expected and how to repeat it. You therefore understand what's wrong, what you expected to happen and how to repeat the
need to supply your operating system's name and version number (uname -a bad behaviour. You therefore need to supply your operating system's name and
under a unix is fine), what version of curl you're using (curl -v is fine), version number (uname -a under a unix is fine), what version of curl you're
what URL you were working with and anything else you think matters. using (curl -V is fine), what URL you were working with and anything else
you think matters.
If curl crashed, causing a core dump (in unix), there is hardly any use to If curl crashed, causing a core dump (in unix), there is hardly any use to
send that huge file to anyone of us. Unless we have an exact same system send that huge file to anyone of us. Unless we have an exact same system
@@ -32,7 +33,7 @@ BUGS
a stack trace and send that (much smaller) output to us instead! a stack trace and send that (much smaller) output to us instead!
The address and how to subscribe to the mailing list is detailed in the The address and how to subscribe to the mailing list is detailed in the
README.curl file. MANUAL file.
HOW TO GET A STACK TRACE with a common unix debugger HOW TO GET A STACK TRACE with a common unix debugger
==================================================== ====================================================

View File

@@ -13,10 +13,10 @@ To Think About When Contributing Source Code
The License Issue The License Issue
When contributing with code, you agree to put your changes and new code under When contributing with code, you agree to put your changes and new code under
the same license curl and libcurl is already using. the same license curl and libcurl is already using unless stated otherwise.
If you add a larger piece of code, you can opt to make that file or set of If you add a larger piece of code, you can opt to make that file or set of
files to use a different license as long as they don't enfore any changes to files to use a different license as long as they don't enforce any changes to
the rest of the package and they make sense. Such "separate parts" can not be the rest of the package and they make sense. Such "separate parts" can not be
GPL (as we don't want the GPL virus to attack users of libcurl) but they must GPL (as we don't want the GPL virus to attack users of libcurl) but they must
use "GPL compatible" licenses. use "GPL compatible" licenses.
@@ -26,19 +26,19 @@ Naming
Try using a non-confusing naming scheme for your new functions and variable Try using a non-confusing naming scheme for your new functions and variable
names. It doesn't necessarily have to mean that you should use the same as in names. It doesn't necessarily have to mean that you should use the same as in
other places of the code, just that the names should be logical, other places of the code, just that the names should be logical,
understandable and be named according to what they're used for. understandable and be named according to what they're used for. File-local
functions should be made static.
Indenting Indenting
Please try using the same indenting levels and bracing method as all the Please try using the same indenting levels and bracing method as all the
other code already does. It makes the source code a lot easier to follow if other code already does. It makes the source code a lot easier to follow if
all of it is written using the same style. I don't ask you to like it, I just all of it is written using the same style. We don't ask you to like it, we
ask you to follow the tradition! ;-) just ask you to follow the tradition! ;-)
Commenting Commenting
Comment your source code extensively. I don't see myself as a very good Comment your source code extensively. Commented code is quality code and
source commenter, but I try to become one. Commented code is quality code and
enables future modifications much more. Uncommented code much more risk being enables future modifications much more. Uncommented code much more risk being
completely replaced when someone wants to extend things, since other persons' completely replaced when someone wants to extend things, since other persons'
source code can get quite hard to read. source code can get quite hard to read.
@@ -71,9 +71,9 @@ Separate Patches Doing Different Things
Patch Against Recent Sources Patch Against Recent Sources
Please try to get the latest available sources to make your patches Please try to get the latest available sources to make your patches
against. It makes my life so much easier. The very best is if you get the against. It makes the life of the developers so much easier. The very best is
most up-to-date sources from the CVS repository, but the latest release if you get the most up-to-date sources from the CVS repository, but the
archive is quite OK as well! latest release archive is quite OK as well!
Document Document
@@ -91,9 +91,9 @@ Write Access to CVS Repository
Test Cases Test Cases
Since the introduction of the test suite, we will get the possibility to Since the introduction of the test suite, we can quickly verify that the main
quickly verify that the main features are working as supposed to. To maintain features are working as they're supposed to. To maintain this situation and
this situation and improve it, all new features and functions that are added improve it, all new features and functions that are added need to be tested
need tro be tested. Every feature that is added should get at least one valid in the test suite. Every feature that is added should get at least one valid
test case that verifies that it works as documented. If every submitter also test case that verifies that it works as documented. If every submitter also
post a few test cases, it won't end up as a heavy burden on a single person! post a few test cases, it won't end up as a heavy burden on a single person!

203
docs/FAQ
View File

@@ -1,4 +1,4 @@
Updated: March 6, 2001 (http://curl.haxx.se/docs/faq.shtml) Updated: April 22, 2001 (http://curl.haxx.se/docs/faq.shtml)
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
@@ -12,6 +12,8 @@ FAQ
1.2 What is libcurl? 1.2 What is libcurl?
1.3 What is cURL not? 1.3 What is cURL not?
1.4 When will you make curl do XXXX ? 1.4 When will you make curl do XXXX ?
1.5 Who makes cURL?
1.6 What do you get for making cURL?
2. Install Related Problems 2. Install Related Problems
2.1 configure doesn't find OpenSSL even when it is installed 2.1 configure doesn't find OpenSSL even when it is installed
@@ -30,7 +32,7 @@ FAQ
3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y? 3.6 Does curl support javascript, ASP, XML, XHTML or HTML version Y?
3.7 Can I use curl to delete/rename a file through FTP? 3.7 Can I use curl to delete/rename a file through FTP?
3.8 How do I tell curl to follow HTTP redirects? 3.8 How do I tell curl to follow HTTP redirects?
3.9 How do I use curl in PHP? 3.9 How do I use curl in PHP, Perl, Tcl, Ruby or Java?
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
4. Running Problems 4. Running Problems
@@ -45,7 +47,7 @@ FAQ
4.5.4 "404 Not Found" 4.5.4 "404 Not Found"
4.5.5 "405 Method Not Allowed" 4.5.5 "405 Method Not Allowed"
4.6 Can you tell me what error code 142 means? 4.6 Can you tell me what error code 142 means?
4.7 How do I keep usernames and passwords secret in Curl command lines? 4.7 How do I keep user names and passwords secret in Curl command lines?
4.8 I found a bug! 4.8 I found a bug!
4.9 Curl can't authenticate to the server that requires NTLM? 4.9 Curl can't authenticate to the server that requires NTLM?
@@ -55,7 +57,7 @@ FAQ
5.3 How do I fetch multiple files with libcurl? 5.3 How do I fetch multiple files with libcurl?
5.4 Does libcurl do Winsock initing on win32 systems? 5.4 Does libcurl do Winsock initing on win32 systems?
5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ? 5.5 Does CURLOPT_FILE and CURLOPT_INFILE work on win32 ?
5.6 What about Keep-Alive or persistant connections? 5.6 What about Keep-Alive or persistent connections?
6. License Issues 6. License Issues
6.1 I have a GPL program, can I use the libcurl library? 6.1 I have a GPL program, can I use the libcurl library?
@@ -76,17 +78,19 @@ FAQ
with URL spelled in uppercase to make it obvious it deals with URLs. The with URL spelled in uppercase to make it obvious it deals with URLs. The
fact it can also be pronounced 'see URL' also helped. fact it can also be pronounced 'see URL' also helped.
Curl supports a range of common internet protocols, currently including Curl supports a range of common Internet protocols, currently including
HTTP, HTTPS, FTP, GOPHER, LDAP, DICT, TELNET and FILE. HTTP, HTTPS, FTP, GOPHER, LDAP, DICT, TELNET and FILE.
We spell it cURL or just curl. We spell it cURL or just curl. We pronounce it with an initial k sound:
[kurl].
1.2 What is libcurl? 1.2 What is libcurl?
libcurl is a reliable, higly portable multiprotocol file transfer library. libcurl is a reliable and portable library which provides you with an easy
interface to a range of common Internet protocols.
Any application is free to use libcurl, even commercial or closed-source You can use libcurl for free in your application even if it is commercial
ones. or closed-source.
1.3 What is cURL not? 1.3 What is cURL not?
@@ -99,8 +103,8 @@ FAQ
something: fine, go ahead and write a script that wraps around curl to make something: fine, go ahead and write a script that wraps around curl to make
it reality (like curlmirror.pl does). it reality (like curlmirror.pl does).
Curl is not an ftp site mirroring program. Sure, get and send ftp with curl Curl is not an FTP site mirroring program. Sure, get and send FTP with curl
but if you want systematic and sequential behaviour you should write a but if you want systematic and sequential behavior you should write a
script (or write a new program that interfaces libcurl) and do it. script (or write a new program that interfaces libcurl) and do it.
Curl is not a PHP tool, even though it works perfectly well when used from Curl is not a PHP tool, even though it works perfectly well when used from
@@ -112,33 +116,59 @@ FAQ
1.4 When will you make curl do XXXX ? 1.4 When will you make curl do XXXX ?
I love suggestions of what to change in order to make curl and libcurl We love suggestions of what to change in order to make curl and libcurl
better. I do however believe in a few rules when it comes to the future of better. We do however believe in a few rules when it comes to the future of
curl: curl:
* It is to remain a command line tool. If you want GUIs or fancy scripting * Curl is to remain a command line tool. If you want GUIs or fancy scripting
capabilities, you're free to write another tool that uses libcurl and that capabilities, you're free to write another tool that uses libcurl and that
offers this. There's no point in having one single tool that does every offers this. There's no point in having a single tool that does every
imaginable thing. That's also one of the great advantages of having the imaginable thing. That's also one of the great advantages of having the
core of curl as a library: libcurl. core of curl as a library.
* I do not add things to curl that other small and available tools already * We do not add things to curl that other small and available tools already
do very fine at the side. Curl's output is fine to pipe into another do very fine at the side. Curl's output is fine to pipe into another
program or redirect to another file for the next program to interpret. program or redirect to another file for the next program to interpret.
* I focus on protocol related issues and improvements. If you wanna do more * We focus on protocol related issues and improvements. If you wanna do more
magic with the supported protocols than curl currently does, chances are magic with the supported protocols than curl currently does, chances are
big I will agree. If you wanna add more protocols, I may very well big I will agree. If you wanna add more protocols, I may very well
agree. agree.
* If you want me to make all the work while you wait for me to implement it * If you want someone else to make all the work while you wait for us to
for you, that is not a very friendly attitude. I spend a considerable time implement it for you, that is not a very friendly attitude. We spend a
already on maintaining and developing curl. In order to get more out of considerable time already on maintaining and developing curl. In order to
me, I trust you will offer some of your time and efforts in return. get more out of us, you should consider trading in some of your time and
efforts in return.
* If you write the code, chances are bigger that it will get into curl * If you write the code, chances are bigger that it will get into curl
faster. faster.
1.5 Who makes cURL?
cURL and libcurl are not made by any single individual. Sure, Daniel
Stenberg writes the major parts, but various people's submissions are
important and crucial. Anyone can post their changes and improvements and
have them inserted in the main sources (of course on the condition that
developers agree on that the fixes are good).
The list of contributors in the bottom of the man page is only a small part
of all the people that every day provide us with bug reports, suggestions,
ideas and source code.
curl is developed by a community, with Daniel at the wheel.
1.6 What do you get for making cURL?
Project cURL is entirely free and open, without any commercial interests or
money involved. No person gets paid in any way for developing curl. We all
do this voluntarily on our spare time.
We get some help from companies. Contactor Data hosts the curl web site and
the main mailing list, Haxx owns the curl web site's domain and
sourceforge.net hosts several project tools we take advantage from like the
bug tracker, mailing lists and more.
2. Install Related Problems 2. Install Related Problems
2.1. configure doesn't find OpenSSL even when it is installed 2.1. configure doesn't find OpenSSL even when it is installed
@@ -174,7 +204,7 @@ FAQ
a few functions are left out from the libssl. a few functions are left out from the libssl.
If the function names missing include RSA or RSAREF you can be certain If the function names missing include RSA or RSAREF you can be certain
that this is because libssl requires the RSA and RSASEF libs to build. that this is because libssl requires the RSA and RSAREF libs to build.
See the INSTALL file section that explains how to add those libs to See the INSTALL file section that explains how to add those libs to
configure. Make sure that you remove the config.cache file before you configure. Make sure that you remove the config.cache file before you
@@ -182,23 +212,24 @@ FAQ
2.2. Does curl work/build with other SSL libraries? 2.2. Does curl work/build with other SSL libraries?
Curl has been written to use OpenSSL, although I doubt there would be much Curl has been written to use OpenSSL, although there should not be much
problems using a different library. If anyone does "port" curl to use a problems using a different library. If anyone does "port" curl to use a
different SSL library, I am of course very interested in getting the patch! different SSL library, we are of course very interested in getting the
patch!
2.3. Where can I find a copy of LIBEAY32.DLL? 2.3. Where can I find a copy of LIBEAY32.DLL?
That is an OpenSSL binary built for Windows. That is an OpenSSL binary built for Windows.
Curl uses OpenSSL to do the SSL stuff. The LIBEAY32.DLL is what curl needs Curl uses OpenSSL to do the SSL stuff. The LIBEAY32.DLL is what curl needs
on a windows machine to do https://. Check out the curl web page to find on a windows machine to do https://. Check out the curl web site to find
accurate and up-to-date pointers to recent OpenSSL DDLs and other binary accurate and up-to-date pointers to recent OpenSSL DLLs and other binary
packages. packages.
2.4. Does cURL support Socks (RFC 1928) ? 2.4. Does cURL support Socks (RFC 1928) ?
No. Nobody has wanted it that badly yet. I would appriciate patches that No. Nobody has wanted it that badly yet. We appreciate patches that bring
brings this functionality. this functionality.
3. Usage problems 3. Usage problems
@@ -220,7 +251,7 @@ FAQ
3.2. How do I tell curl to resume a transfer? 3.2. How do I tell curl to resume a transfer?
Curl supports resume both ways on FTP, download ways on HTTP. Curl supports resumed transfers both ways on both FTP and HTTP.
Try the -C option. Try the -C option.
@@ -232,10 +263,11 @@ FAQ
use the -F type. In all the most common cases, you should use -d which then use the -F type. In all the most common cases, you should use -d which then
causes a posting with the type 'application/x-www-form-urlencoded'. causes a posting with the type 'application/x-www-form-urlencoded'.
I have described this in some detail in the README.curl file, and if you This is described in some detail in the MANUAL and TheArtOfHttpScripting
don't understand it the first time, read it again before you post questions documents, and if you don't understand it the first time, read it again
about this to the mailing list. I would also suggest that you read through before you post questions about this to the mailing list. Also, try reading
the mailing list archives for old postings and questions regarding this. through the mailing list archives for old postings and questions regarding
this.
3.4. How do I tell curl to run custom FTP commands? 3.4. How do I tell curl to run custom FTP commands?
@@ -243,7 +275,7 @@ FAQ
file transfer. Study the -Q/--quote option. file transfer. Study the -Q/--quote option.
Since curl is used for file transfers, you don't use curl to just perform Since curl is used for file transfers, you don't use curl to just perform
ftp commands without transfering anything. Therefore you must always specify FTP commands without transferring anything. Therefore you must always specify
a URL to transfer to/from even when doing custom FTP commands. a URL to transfer to/from even when doing custom FTP commands.
3.5. How can I disable the Pragma: nocache header? 3.5. How can I disable the Pragma: nocache header?
@@ -255,7 +287,7 @@ FAQ
3.6. Does curl support javascript, ASP, XML, XHTML or HTML version Y? 3.6. Does curl support javascript, ASP, XML, XHTML or HTML version Y?
To curl, all contents are alike. It doesn't matter how the page was To curl, all contents are alike. It doesn't matter how the page was
generated. It may be ASP, PHP, perl, shell-script, SSI or plain generated. It may be ASP, PHP, Perl, shell-script, SSI or plain
HTML-files. There's no difference to curl and it doesn't even know what kind HTML-files. There's no difference to curl and it doesn't even know what kind
of language that generated the page. of language that generated the page.
@@ -265,7 +297,7 @@ FAQ
3.7. Can I use curl to delete/rename a file through FTP? 3.7. Can I use curl to delete/rename a file through FTP?
Yes. You specify custom ftp commands with -Q/--quote. Yes. You specify custom FTP commands with -Q/--quote.
One example would be to delete a file after you have downloaded it: One example would be to delete a file after you have downloaded it:
@@ -279,8 +311,21 @@ FAQ
curl -L http://redirector.com curl -L http://redirector.com
3.9 How do I use curl in PHP? 3.9 How do I use curl in PHP, Perl, Tcl, Ruby or Java?
There exist many language-interfaces for curl that integrates it better with
various languages. If you are fluid in a script language, you may very well
opt to use such an interface instead of using the command line tool.
At the time of writing, there are bindings for the five language mentioned
above, but chances are there are even more by the time you read this. Or you
may be able you write your own wrapper for a not-yet support language!
Find out more about which languages that support curl directly, and how to
install and use them, in the libcurl section of the curl web site:
http://curl.haxx.se/libcurl/
PHP4 has the ability to use libcurl as an internal module if built with that PHP4 has the ability to use libcurl as an internal module if built with that
option enabled. You then get a set of extra functions that can be used option enabled. You then get a set of extra functions that can be used
within your PHP programs. You find all details about those functions in the within your PHP programs. You find all details about those functions in the
@@ -295,7 +340,7 @@ FAQ
3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP? 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
Curl adheres to the HTTP spec, which basically means you can play with *any* Curl adheres to the HTTP spec, which basically means you can play with *any*
protocol that is built ontop of HTTP. Protocols such as SOAP, WEBDAV and protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and
XML-RPC are all such ones. You can use -X to set custom requests and -H to XML-RPC are all such ones. You can use -X to set custom requests and -H to
set custom headers (or replace internally generated ones). set custom headers (or replace internally generated ones).
@@ -306,9 +351,9 @@ FAQ
4.1. Problems connecting to SSL servers. 4.1. Problems connecting to SSL servers.
It took a very long time before I could sort out why curl had problems It took a very long time before we could sort out why curl had problems to
to connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The
The error sometimes showed up similar to: error sometimes showed up similar to:
16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233: 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233:
@@ -316,14 +361,14 @@ FAQ
requests properly. To correct this problem, tell curl to select SSLv2 from requests properly. To correct this problem, tell curl to select SSLv2 from
the command line (-2/--sslv2). the command line (-2/--sslv2).
I have also seen examples where the remote server didn't like the SSLv2 There has also been examples where the remote server didn't like the SSLv2
request and instead you had to force curl to use SSLv3 with -3/--sslv3. request and instead you had to force curl to use SSLv3 with -3/--sslv3.
4.2. Why do I get problems when I use & or % in the URL? 4.2. Why do I get problems when I use & or % in the URL?
In general unix shells, the & letter is treated special and when used it In general unix shells, the & letter is treated special and when used, it
runs the specified command in the background. To safely send the & as a part runs the specified command in the background. To safely send the & as a part
of a URL, you should qoute the entire URL by using single (') or double (") of a URL, you should quote the entire URL by using single (') or double (")
quotes around it. quotes around it.
An example that would invoke a remote CGI that uses &-letters could be: An example that would invoke a remote CGI that uses &-letters could be:
@@ -346,8 +391,8 @@ FAQ
curl '{curl,www}.haxx.se' curl '{curl,www}.haxx.se'
To be able to use those letters as actual parts of the URL (without using To be able to use those letters as actual parts of the URL (without using
them for the curl URL "globbing" system), use the -g/--globoff option them for the curl URL "globbing" system), use the -g/--globoff option (curl
(included in curl 7.6 and later): 7.6 and later):
curl -g 'www.site.com/weirdname[].html' curl -g 'www.site.com/weirdname[].html'
@@ -363,8 +408,8 @@ FAQ
4.5 Why do I get return code XXX from a HTTP server? 4.5 Why do I get return code XXX from a HTTP server?
RFC2616 clearly explains the return codes. I'll make a short transcript RFC2616 clearly explains the return codes. This is a short transcript. Go
here. Go read the RFC for exact details: read the RFC for exact details:
4.5.1 "400 Bad Request" 4.5.1 "400 Bad Request"
@@ -398,13 +443,13 @@ FAQ
abort from such a condition and that's why it got this undocumented abort from such a condition and that's why it got this undocumented
error. This should not occur in releases after 7.4.1. error. This should not occur in releases after 7.4.1.
4.7. How do I keep usernames and passwords secret in Curl command lines? 4.7. How do I keep user names and passwords secret in Curl command lines?
I see this problem as two parts: This problem has two sides:
The first part is to avoid having clear-text passwords in the command line The first part is to avoid having clear-text passwords in the command line
so that they don't appear in 'ps' outputs and similar. That is easily so that they don't appear in 'ps' outputs and similar. That is easily
avoided by using the "-K" option tho tell curl to read parameters from a avoided by using the "-K" option to tell curl to read parameters from a
file or stdin to which you can pass the secret info. file or stdin to which you can pass the secret info.
To keep the passwords in your account secret from the rest of the world is To keep the passwords in your account secret from the rest of the world is
@@ -414,11 +459,11 @@ FAQ
Also note that regular HTTP and FTP passwords are sent in clear across the Also note that regular HTTP and FTP passwords are sent in clear across the
network. All it takes for anyone to fetch them is to listen on the network. network. All it takes for anyone to fetch them is to listen on the network.
Evesdropping is very easy. Eavesdropping is very easy.
4.8 I found a bug! 4.8 I found a bug!
It is not a bug if the behaviour is documented. Read the docs first. It is not a bug if the behavior is documented. Read the docs first.
If it is a problem with a binary you've downloaded or a package for your If it is a problem with a binary you've downloaded or a package for your
particular platform, try contacting the person who built the package/archive particular platform, try contacting the person who built the package/archive
@@ -447,15 +492,14 @@ FAQ
programs. libcurl will use thread-safe functions instead of non-safe ones if programs. libcurl will use thread-safe functions instead of non-safe ones if
your system has such. your system has such.
I am very interested in once and for all getting some kind of report or We would appreciate some kind of report or README file from those who have
README file from those who have used libcurl in a threaded environment, used libcurl in a threaded environment.
since I haven't and I get this question more and more frequently!
5.2 How can I receive all data into a large memory chunk? 5.2 How can I receive all data into a large memory chunk?
You are in full control of the callback function that gets called every time You are in full control of the callback function that gets called every time
there is data received from the remote server. You can make that callback do there is data received from the remote server. You can make that callback do
whatever you want. You do not have to write the receivied data to a file. whatever you want. You do not have to write the received data to a file.
One solution to this problem could be to have a pointer to a struct that you One solution to this problem could be to have a pointer to a struct that you
pass to the callback function. You set the pointer using the pass to the callback function. You set the pointer using the
@@ -487,13 +531,17 @@ FAQ
5.3 How do I fetch multiple files with libcurl? 5.3 How do I fetch multiple files with libcurl?
Starting with version 7.7, curl and libcurl will have excellent support for Starting with version 7.7, curl and libcurl will have excellent support for
transferring multiple files. transferring multiple files. You should just repeatedly set new URLs with
curl_easy_setopt() and then transfer it with curl_easy_perform(). The handle
you get from curl_easy_init() is not only reusable starting with libcurl
7.7, but also you're encouraged to reuse it if you can, as that will enable
libcurl to use persistent connections.
The easy interface of libcurl does not support multiple requests using the For libcurl prior to 7.7, there was no multiple file support. The only
same connection. The only available way to do multiple requests is to available way to do multiple requests was to init/perform/cleanup for each
init/perform/cleanup for each request. transfer.
5.4 Does libcurl do Winsock initing on win32 systems? 5.4 Does libcurl do Winsock initialization on win32 systems?
No. No.
@@ -513,22 +561,18 @@ FAQ
(Provided by Joel DeYoung and Bob Schader) (Provided by Joel DeYoung and Bob Schader)
5.6 What about Keep-Alive or persistant connections? 5.6 What about Keep-Alive or persistent connections?
Starting with version 7.7, curl and libcurl will have excellent support for Starting with version 7.7, curl and libcurl will have excellent support for
persistant connections when transferring several files from the same server. persistent connections when transferring several files from the same server.
Curl will attempt to reuse connections for all URLs specified on the same
command line/config file, and libcurl will reuse connections for all
transfers that are made using the same libcurl handle.
This is closely related to issue 5.3. Since libcurl has no real support Previous versions had no persistent connection support.
for doing multiple file transfers, there's no support for Keep-Alive or
persistant connections either.
This is of course subject to change as soon as libcurl gets support for
multiple files. Feel free to join in and make this change happen sooner!
6. License Issues 6. License Issues
NOTE: This section concerns curl 7.5.2 or later!
Curl and libcurl are released under a MIT/X derivate license *or* the MPL, Curl and libcurl are released under a MIT/X derivate license *or* the MPL,
the Mozilla Public License. To get a really good answer to your license the Mozilla Public License. To get a really good answer to your license
conflict questions, you should study the MPL and MIT/X licenses and the conflict questions, you should study the MPL and MIT/X licenses and the
@@ -573,9 +617,10 @@ FAQ
No. No.
We carefully picked this license years ago and a large amount of people have We have carefully picked this license after years of development and
contributed with source code knowing that this is the license we use. This discussions and a large amount of people have contributed with source code
license puts the restrictions we want on curl/libcurl and it does not spread knowing that this is the license we use. This license puts the restrictions
to other programs or libraries that use it. The recent dual license we want on curl/libcurl and it does not spread to other programs or
modification should make it possible for everyone to use libcurl or curl in libraries that use it. The recent dual license modification should make it
their projects, no matter what license they already have in use. possible for everyone to use libcurl or curl in their projects, no matter
what license they already have in use.

View File

@@ -17,12 +17,14 @@ Misc
- progress bar/time specs while downloading - progress bar/time specs while downloading
- "standard" proxy environment variables support - "standard" proxy environment variables support
- config file support - config file support
- compiles on win32 - compiles on win32 (reported built on 29 operating systems)
- redirectable stderr - redirectable stderr
- use selected network interface for outgoing traffic - use selected network interface for outgoing traffic
- IPv6 support - IPv6 support
- persistant connections
HTTP HTTP
- HTTP/1.1 compliant
- GET - GET
- PUT - PUT
- HEAD - HEAD
@@ -72,6 +74,7 @@ FTP
TELNET TELNET
- connection negotiation - connection negotiation
- custom telnet options
- stdin/stdout I/O - stdin/stdout I/O
LDAP (*2) LDAP (*2)

View File

@@ -7,24 +7,35 @@
How To Compile How To Compile
Curl has been compiled and built on numerous different operating systems. The Curl has been compiled and built on numerous different operating systems. The
way to proceed is mainly divided in two different ways: the unix way or the way to proceed is mainly divided in two different ways: the unix way or the
windows way. windows way.
If you're using Windows (95, 98, NT) or OS/2, you should continue reading from If you're using Windows (95/98/NT/ME/2000 or whatever) or OS/2, you should
the Win32 or OS/2 headers further down. All other systems should be capable of continue reading from the Win32 or OS/2 headers further down. All other
being installed as described below. systems should be capable of being installed as described below.
UNIX UNIX
==== ====
The configure script *always* tries to find a working SSL library unless A normal unix installation is made in three or four steps (after you've
explicitly told not to. If you have OpenSSL installed in the default unpacked the source archive):
search path for your compiler/linker, you don't need to do anything
special:
./configure ./configure
make
make test (optional)
make install
If you have OpenSSL installed in /usr/local/ssl, you can run configure You probably need to be root when doing the last command.
If you want to install curl in a different file hierarchy than /usr/local,
you need to specify that already when running configure:
./configure --prefix=/path/to/curl/tree
The configure script always tries to find a working SSL library unless
explicitly told not to. If you have OpenSSL installed in the default search
path for your compiler/linker, you don't need to do anything special. If
you have OpenSSL installed in e.g /usr/local/ssl, you can run configure
like: like:
./configure --with-ssl ./configure --with-ssl
@@ -54,33 +65,11 @@ UNIX
env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \ env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
./configure ./configure
If your SSL library was compiled with rsaref (usually for use in If your SSL library was compiled with rsaref (usually for use in the United
the United States), you may also need to set: States), you may also need to set:
LIBS=-lRSAglue -lrsaref LIBS=-lRSAglue -lrsaref
(from Doug Kaufman <dkaufman@rahul.net>) (as suggested by Doug Kaufman)
Without SSL support, just run:
./configure
Then run:
make
Use the executable `curl` in src/ directory.
To install curl on your system, run
make install
This will copy curl to /usr/local/bin/ (or $prefix/bin if you used the
--prefix option to configure) and it copies the man pages, the lib and the
include files to suitable places.
To make sure everything runs as supposed, run the test suite:
make test
KNOWN PROBLEMS KNOWN PROBLEMS
@@ -109,7 +98,7 @@ UNIX
they're executable and set to appear in the path *BEFORE* the actual (but they're executable and set to appear in the path *BEFORE* the actual (but
obsolete) autoconf and autoheader scripts. obsolete) autoconf and autoheader scripts.
OPTIONS MORE OPTIONS
Remember, to force configure to use the standard cc compiler if both Remember, to force configure to use the standard cc compiler if both
cc and gcc are present, run configure like cc and gcc are present, run configure like
@@ -156,29 +145,27 @@ Win32
MingW32 (GCC-2.95) style MingW32 (GCC-2.95) style
------------------------ ------------------------
Run the 'mingw32.bat' file to get the proper environment variables Run the 'mingw32.bat' file to get the proper environment variables
set, then run 'make -f Makefile.m32' in the lib/ dir and then set, then run 'make mingw32' in the root dir.
'make -f Makefile.m32' in the src/ dir.
If you have any problems linking libraries or finding header files, If you have any problems linking libraries or finding header files, be
be sure to look at the provided "Makefile.m32" files for the proper sure to verify that the provided "Makefile.m32" files use the proper
paths, and adjust as necessary. paths, and adjust as necessary.
Cygwin style Cygwin style
------------ ------------
Almost identical to the unix installation. Run the configure script Almost identical to the unix installation. Run the configure script in
in the curl root with 'sh configure'. Make sure you have the sh the curl root with 'sh configure'. Make sure you have the sh
executable in /bin/ or you'll see the configure fail towards the executable in /bin/ or you'll see the configure fail towards the end.
end.
Run 'make' Run 'make'
Microsoft command line style Microsoft command line style
---------------------------- ----------------------------
Run the 'vcvars32.bat' file to get the proper environment variables Run the 'vcvars32.bat' file to get the proper environment variables
set, then run 'nmake -f Makefile.vc6' in the lib/ dir and then set, then run 'nmake vc' in the root dir.
'nmake -f Makefile.vc6' in the src/ dir.
The vcvars32.bat file is part of the Microsoft development environment. The vcvars32.bat file is part of the Microsoft development
environment.
IDE-style IDE-style
------------------------- -------------------------
@@ -196,9 +183,9 @@ Win32
For VC++ 6, there's an included Makefile.vc6 that should be possible For VC++ 6, there's an included Makefile.vc6 that should be possible
to use out-of-the-box. to use out-of-the-box.
Microsoft note: add /Zm200 to the compiler options, as the hugehelp.c Microsoft note: add /Zm200 to the compiler options to increase the
won't compile otherwise due to "too long puts string" or something compiler's memory allocation limit, as the hugehelp.c won't compile
like that! due to "too long puts string".
With SSL: With SSL:
@@ -206,26 +193,24 @@ Win32
MingW32 (GCC-2.95) style MingW32 (GCC-2.95) style
------------------------ ------------------------
Run the 'mingw32.bat' file to get the proper environment variables Run the 'mingw32.bat' file to get the proper environment variables
set, then run 'make -f Makefile.m32 SSL=1' in the lib/ dir and then set, then run 'make mingw32-ssl' in the root dir.
'make -f Makefile.m32 SSL=1' in the src/ dir.
If you have any problems linking libraries or finding header files, If you have any problems linking libraries or finding header files, be
be sure to look at the provided "Makefile.m32" files for the proper sure to look at the provided "Makefile.m32" files for the proper
paths, and adjust as necessary. paths, and adjust as necessary.
Cygwin style Cygwin style
------------ ------------
Haven't done, nor got any reports on how to do. It should although be Haven't done, nor got any reports on how to do. It should although be
identical to the unix setup for the same purpose. See above. identical to the unix setup for the same purpose. See above.
Microsoft command line style Microsoft command line style
---------------------------- ----------------------------
Run the 'vcvars32.bat' file to get the proper environment variables Run the 'vcvars32.bat' file to get the proper environment variables
set, then run 'nmake -f Makefile.vc6 release-ssl' in the lib/ dir and set, then run 'nmake vc-ssl' in the root dir.
then 'nmake -f Makefile.vc6' in the src/ dir.
The vcvars32.bat file is part of the Microsoft development environment. The vcvars32.bat file is part of the Microsoft development
environment.
Microsoft / Borland style Microsoft / Borland style
------------------------- -------------------------
@@ -252,7 +237,7 @@ IBM OS/2
If you want to build with OpenSSL or OpenLDAP support, you'll need to If you want to build with OpenSSL or OpenLDAP support, you'll need to
download those libraries, too. Dirk Ohme has done some work to port SSL download those libraries, too. Dirk Ohme has done some work to port SSL
libraries under OS/2, but it looks like he doesn't care about emx. You'll libraries under OS/2, but it looks like he doesn't care about emx. You'll
find his patches on: http://come.to/Dirk.Ohme find his patches on: http://come.to/Dirk_Ohme
If during the linking you get an error about _errno being an undefined If during the linking you get an error about _errno being an undefined
symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__ symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__
@@ -266,10 +251,10 @@ IBM OS/2
PORTS PORTS
===== =====
Just to show off, this is a probably incomplete list of known hardware and This is a probably incomplete list of known hardware and
operating systems that curl has been compiled for: operating systems that curl has been compiled for:
- Ultrix - Ultrix 4.3a
- SINIX-Z v5 - SINIX-Z v5
- Alpha DEC OSF 4 - Alpha DEC OSF 4
- Alpha Digital UNIX v3.2 - Alpha Digital UNIX v3.2

View File

@@ -1,4 +1,4 @@
Updated for curl 7.6 on January 26, 2001 Updated for curl 7.7.2 on April 26, 2001
_ _ ____ _ _ _ ____ _
___| | | | _ \| | ___| | | | _ \| |
/ __| | | | |_) | | / __| | | | |_) | |
@@ -7,11 +7,11 @@
INTERNALS INTERNALS
The project is kind of split in two. The library and the client. The client The project is split in two. The library and the client. The client part uses
part uses the library, but the library is meant to be designed to allow other the library, but the library is designed to allow other applications to use
applications to use it. it.
Thus, the largest amount of code and complexity is in the library part. The largest amount of code and complexity is in the library part.
CVS CVS
=== ===
@@ -35,13 +35,13 @@ Windows vs Unix
the same at all places except for the header file that defines them. The the same at all places except for the header file that defines them. The
macros in use are sclose(), sread() and swrite(). macros in use are sclose(), sread() and swrite().
2. Windows requires a couple of init calls for the socket stuff 2. Windows requires a couple of init calls for the socket stuff.
Those must be made by the application that uses libcurl, in curl that means Those must be made by the application that uses libcurl, in curl that means
src/main.c has some code #ifdef'ed to do just that. src/main.c has some code #ifdef'ed to do just that.
3. The file descriptors for network communication and file operations are 3. The file descriptors for network communication and file operations are
not easily interchangable as in unix not easily interchangable as in unix.
We avoid this by not trying any funny tricks on file descriptors. We avoid this by not trying any funny tricks on file descriptors.
@@ -51,10 +51,10 @@ Windows vs Unix
We set stdout to binary under windows We set stdout to binary under windows
Inside the source code, I do make an effort to avoid '#ifdef WIN32'. All Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All
conditionals that deal with features *should* instead be in the format conditionals that deal with features *should* instead be in the format
'#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts, '#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts,
I maintain two config-win32.h files (one in / and one in src/) that are we maintain two config-win32.h files (one in / and one in src/) that are
supposed to look exactly as a config.h file would have looked like on a supposed to look exactly as a config.h file would have looked like on a
Windows machine! Windows machine!
@@ -64,12 +64,6 @@ Windows vs Unix
Library Library
======= =======
As described elsewhere, libcurl is meant to get two different "layers" of
interfaces. At the present point only the high-level, the "easy", interface
has been fully implemented and documented. We assume the easy-interface in
this description, the low-level interface will be documented when fully
implemented.
There are plenty of entry points to the library, namely each publicly defined There are plenty of entry points to the library, namely each publicly defined
function that libcurl offers to applications. All of those functions are function that libcurl offers to applications. All of those functions are
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
@@ -79,7 +73,7 @@ Library
makes sure we stay absolutely platform independent. makes sure we stay absolutely platform independent.
curl_easy_init() allocates an internal struct and makes some initializations. curl_easy_init() allocates an internal struct and makes some initializations.
The returned handle does not revail internals. The returned handle does not reveal internals.
curl_easy_setopt() takes a three arguments, where the option stuff must be curl_easy_setopt() takes a three arguments, where the option stuff must be
passed in pairs, the parameter-ID and the parameter-value. The list of passed in pairs, the parameter-ID and the parameter-value. The list of
@@ -87,32 +81,84 @@ Library
curl_easy_perform() does a whole lot of things: curl_easy_perform() does a whole lot of things:
It starts off in the lib/easy.c file by calling curl_transfer(), but the main It starts off in the lib/easy.c file by calling Curl_perform() and the main
work is lib/url.c. The function first analyzes the URL, it separates the work then continues lib/url.c. The flow continues with a call to
different components and connects to the remote host. This may involve using Curl_connect() to connect to the remote site.
a proxy and/or using SSL. The Curl_gethost() function in lib/hostip.c is used
for looking up host names.
When connected, the proper protocol-specific function is called. The o Curl_connect()
functions are named after the protocols they handle. Curl_ftp(), Curl_http(),
Curl_dict(), etc. They all reside in their respective files (ftp.c, http.c
and dict.c).
The protocol-specific functions of course deal with protocol-specific ... analyzes the URL, it separates the different components and connects to
negotiations and setup. They have access to the Curl_sendf() (from the remote host. This may involve using a proxy and/or using SSL. The
lib/sendf.c) function to send printf-style formatted data to the remote host Curl_gethost() function in lib/hostip.c is used for looking up host names.
and when they're ready to make the actual file transfer they call the
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
returns. curl_transfer() then calls _Tranfer() in lib/transfer.c that
performs the entire file transfer.
During transfer, the progress functions in lib/progress.c are called at a When Curl_connect is done, we are connected to the remote site. Then it is
frequent interval (or at the user's choice, a specified callback might get time to tell the server to get a document/file. Curl_do() arranges this.
called). The speedcheck functions in lib/speedcheck.c are also used to verify
that the transfer is as fast as required. o Curl_do()
Curl_do() makes sure the proper protocol-specific function is called. The
functions are named after the protocols they handle. Curl_ftp(),
Curl_http(), Curl_dict(), etc. They all reside in their respective files
(ftp.c, http.c and dict.c).
The protocol-specific functions of course deal with protocol-specific
negotiations and setup. They have access to the Curl_sendf() (from
lib/sendf.c) function to send printf-style formatted data to the remote
host and when they're ready to make the actual file transfer they call the
Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
returns.
o Transfer()
Curl_perform() then calls Transfer() in lib/transfer.c that performs
the entire file transfer.
During transfer, the progress functions in lib/progress.c are called at a
frequent interval (or at the user's choice, a specified callback might get
called). The speedcheck functions in lib/speedcheck.c are also used to
verify that the transfer is as fast as required.
o Curl_done()
Called after a transfer is done. This function takes care of everything
that has to be done after a transfer. This function attempts to leave
matters in a state so that Curl_do() should be possible to call again on
the same connection (in a persistent connection case). It may also soon be
closed with Curl_disconnect().
o Curl_disconnect()
During normal connection and transfers, no one ever tries to close any
connection so this is not normally called when curl_easy_perform() is
used. This function is only used when we are certain that no more transfers
is going to be made on the connection (it can be also closed by
force). This function can also be called at times to make sure that libcurl
doesn't keep too many connections alive at the same time.
This function cleans up all resources that are associated with a single
connection.
Curl_perform() is the function that does the main "connect - do - transfer -
done" loop. It loops if there's a Location: to follow.
When completed, the curl_easy_cleanup() should be called to free up used When completed, the curl_easy_cleanup() should be called to free up used
resources. resources. It runs Curl_disconnect() on all open connectons.
A quick roundup on internal function sequences (many of these call
protocol-specific function-pointers):
curl_connect - connects to a remote site and does initial connect fluff
This also checks for an existing connection to the requested site and uses
that one if it is possible.
curl_do - starts a transfer
curl_transfer() - transfers data
curl_done - ends a transfer
curl_disconnect - disconnects from a remote site. This is called when the
disconnect is really requested, which doesn't necessarily have to be
exactly after curl_done in case we want to keep the connection open for
a while.
HTTP(S) HTTP(S)
@@ -129,6 +175,14 @@ Library
the source by the use of curl_read() for reading and curl_write() for writing the source by the use of curl_read() for reading and curl_write() for writing
data to the remote server. data to the remote server.
http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
encoding.
An interesting detail with the HTTP(S) request, is the add_buffer() series of
functions we use. They append data to one single buffer, and when the
building is done the entire request is sent off in one single write. This is
done this way to overcome problems with flawed firewalls and lame servers.
FTP FTP
The Curl_if2ip() function can be used for getting the IP number of a The Curl_if2ip() function can be used for getting the IP number of a
@@ -160,7 +214,7 @@ Library
URL encoding and decoding, called escaping and unescaping in the source code, URL encoding and decoding, called escaping and unescaping in the source code,
is found in lib/escape.c. is found in lib/escape.c.
While transfering data in _Transfer() a few functions might get While transfering data in Transfer() a few functions might get
used. curl_getdate() in lib/getdate.c is for HTTP date comparisons (and used. curl_getdate() in lib/getdate.c is for HTTP date comparisons (and
more). more).
@@ -182,6 +236,34 @@ Library
exists in lib/getpass.c. libcurl offers a custom callback that can be used exists in lib/getpass.c. libcurl offers a custom callback that can be used
instead of this, but it doesn't change much to us. instead of this, but it doesn't change much to us.
Persistent Connections
======================
With curl 7.7, we added persistent connection support to libcurl which has
introduced a somewhat different treatmeant of things inside of libcurl.
o The 'UrlData' struct returned in the curl_easy_init() call must never
hold connection-oriented data. It is meant to hold the root data as well
as all the options etc that the library-user may choose.
o The 'UrlData' struct holds the cache array of pointers to 'connectdata'
structs. There's one connectdata struct for each connection that libcurl
knows about.
o This also enables the 'curl handle' to be reused on subsequent transfers,
something that was illegal in pre-7.7 versions.
o When we are about to perform a transfer with curl_easy_perform(), we first
check for an already existing connection in the cache that we can use,
otherwise we create a new one and add to the cache. If the cache is full
already when we add a new connection, we close one of the present ones. We
select which one to close dependent on the close policy that may have been
previously set.
o When the tranfer operation is complete, we try to leave the connection open.
Particular options may tell us not to, and protocols may signal closure on
connections and then we don't keep it open of course.
o When curl_easy_cleanup() is called, we close all still opened connections.
You do realize that the curl handle must be re-used in order for the
persistent connections to work.
Library Symbols Library Symbols
=============== ===============
@@ -210,6 +292,7 @@ Client
====== ======
main() resides in src/main.c together with most of the client code. main() resides in src/main.c together with most of the client code.
src/hugehelp.c is automatically generated by the mkhelp.pl perl script to src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
display the complete "manual" and the src/urlglob.c file holds the functions display the complete "manual" and the src/urlglob.c file holds the functions
used for the URL-"globbing" support. Globbing in the sense that the {} and [] used for the URL-"globbing" support. Globbing in the sense that the {} and []
@@ -225,25 +308,26 @@ Client
curl_easy_getinfo() function to extract useful information from the curl curl_easy_getinfo() function to extract useful information from the curl
session. session.
Recent versions may loop and do all that several times if many URLs were Recent versions may loop and do all this several times if many URLs were
specified on the command line or config file. specified on the command line or config file.
Memory Debugging Memory Debugging
================ ================
The file named lib/memdebug.c contains debug-versions of a few The file lib/memdebug.c contains debug-versions of a few functions. Functions
functions. Functions such as malloc, free, fopen, fclose, etc that somehow such as malloc, free, fopen, fclose, etc that somehow deal with resources
deal with resources that might give us problems if we "leak" them. The that might give us problems if we "leak" them. The functions in the memdebug
functions in the memdebug system do nothing fancy, they do their normal system do nothing fancy, they do their normal function and then log
function and then log information about what they just did. The logged data information about what they just did. The logged data can then be analyzed
is then analyzed after a complete session, after a complete session,
memanalyze.pl is a perl script present only in CVS (not part of the release memanalyze.pl is the perl script present only present in CVS (not part of the
archives) that analyzes a log file generated by the memdebug system. It release archives) that analyzes a log file generated by the memdebug
detects if resources are allocated but never freed and other kinds of errors system. It detects if resources are allocated but never freed and other kinds
related to resource management. of errors related to resource management.
Use -DMALLOCDEBUG when compiling to enable memory debugging. Use -DMALLOCDEBUG when compiling to enable memory debugging, this is also
switched on by running configure with --enable-debug.
Test Suite Test Suite
========== ==========
@@ -256,8 +340,8 @@ Test Suite
httpserver.pl and ftpserver.pl before all the test cases are performed. The httpserver.pl and ftpserver.pl before all the test cases are performed. The
test suite currently only runs on unix-like platforms. test suite currently only runs on unix-like platforms.
You'll find a complete description of the test case data files in the README You'll find a complete description of the test case data files in the
file in the test directory. tests/README file.
The test suite automatically detects if curl was built with the memory The test suite automatically detects if curl was built with the memory
debugging enabled, and if it was it will detect memory leaks too. debugging enabled, and if it was it will detect memory leaks too.
@@ -269,6 +353,7 @@ Building Releases
released, run the 'maketgz' script (using 'make distcheck' will give you a released, run the 'maketgz' script (using 'make distcheck' will give you a
pretty good view on the status of the current sources). maketgz prompts for pretty good view on the status of the current sources). maketgz prompts for
version number of the client and the library before it creates a release version number of the client and the library before it creates a release
archive. archive. maketgz uses 'make dist' for the actual archive building, why you
need to fill in the Makefile.am files properly for which files that should
be included in the release archives.
You must have autoconf installed to build release archives.

View File

@@ -6,8 +6,8 @@
How To Use Libcurl In Your C/C++ Program How To Use Libcurl In Your C/C++ Program
[ libcurl can be used directly from within your PHP or Perl programs as well, [ libcurl can be used directly from within your Java, PHP, Perl, Ruby or Tcl
look elsewhere for documentation on this ] programs as well, look elsewhere for documentation on this ]
The interface is meant to be very simple for applictions/programmers, hence The interface is meant to be very simple for applictions/programmers, hence
the name "easy". We have therefore minimized the number of entries. the name "easy". We have therefore minimized the number of entries.
@@ -49,6 +49,29 @@ The Easy Interface
For details on these, read the separate man pages. For details on these, read the separate man pages.
Linking with libcurl
Staring with 7.7.2 (on unix-like machines), there's a tool named curl-config
that gets installed with the rest of the curl stuff when 'make install' is
performed.
curl-config is added to make it easier for applications to link with
libcurl and developers to learn about libcurl and how to use it.
Run 'curl-config --libs' to get the (additional) linker options you need to
link with the particular version of libcurl you've installed.
For details, see the curl-config.1 man page.
libcurl symbol names
All public functions in the libcurl interface are prefixed with 'curl_' (with
a lowercase c). You can find other functions in the library source code, but
other prefixes indicate the functions are private and may change without
further notice in the next release.
Only use documented functions and functionality!
Portability Portability
libcurl works *exactly* the same, on any of the platforms it compiles and libcurl works *exactly* the same, on any of the platforms it compiles and
@@ -58,9 +81,16 @@ Portability
you to init the winsock stuff before you use the libcurl functions. Details you to init the winsock stuff before you use the libcurl functions. Details
on this are noted on the curl_easy_init() man page. on this are noted on the curl_easy_init() man page.
(*) = it appears users of the cygwin environment gets this done (*) = it appears as if users of the cygwin environment get this done
automatically. automatically.
Threads
Never *ever* call curl-functions simultaneously using the same handle from
several threads. libcurl is thread-safe and can be used in any number of
threads, but you must use separate curl handles if you want to use libcurl in
more than one thread simultaneously.
Persistant Connections Persistant Connections
With libcurl 7.7, persistant connections were added. Persistant connections With libcurl 7.7, persistant connections were added. Persistant connections

View File

@@ -15,22 +15,26 @@ SIMPLE USAGE
curl ftp://ftp.funet.fi/README curl ftp://ftp.funet.fi/README
Get a gopher document from funet's gopher server:
curl gopher://gopher.funet.fi
Get a web page from a server using port 8000: Get a web page from a server using port 8000:
curl http://www.weirdserver.com:8000/ curl http://www.weirdserver.com:8000/
Get a list of the root directory of an FTP site: Get a list of the root directory of an FTP site:
curl ftp://ftp.fts.frontec.se/ curl ftp://cool.haxx.se/
Get a gopher document from funet's gopher server:
curl gopher://gopher.funet.fi
Get the definition of curl from a dictionary: Get the definition of curl from a dictionary:
curl dict://dict.org/m:curl curl dict://dict.org/m:curl
Fetch two documents at once:
curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/
DOWNLOAD TO A FILE DOWNLOAD TO A FILE
Get a web page and store in a local file: Get a web page and store in a local file:
@@ -43,6 +47,10 @@ DOWNLOAD TO A FILE
curl -O http://www.netscape.com/index.html curl -O http://www.netscape.com/index.html
Fetch two files and store them with their remote names:
curl -O www.haxx.se/index.html -O curl.haxx.se/download.html
USING PASSWORDS USING PASSWORDS
FTP FTP
@@ -178,7 +186,7 @@ DETAILED INFORMATION
-D/--dump-header option when getting files from both FTP and HTTP, and it -D/--dump-header option when getting files from both FTP and HTTP, and it
will then store the headers in the specified file. will then store the headers in the specified file.
Store the HTTP headers in a separate file: Store the HTTP headers in a separate file (headers.txt in the example):
curl --dump-header headers.txt curl.haxx.se curl --dump-header headers.txt curl.haxx.se
@@ -237,32 +245,32 @@ POST (HTTP)
-F accepts parameters like -F "name=contents". If you want the contents to -F accepts parameters like -F "name=contents". If you want the contents to
be read from a file, use <@filename> as contents. When specifying a file, be read from a file, use <@filename> as contents. When specifying a file,
you can also specify which content type the file is, by appending you can also specify the file content type by appending ';type=<mime type>'
';type=<mime type>' to the file name. You can also post contents of several to the file name. You can also post the contents of several files in one field.
files in one field. So that the field name 'coolfiles' can be sent three For example, the field name 'coolfiles' is used to send three files, with
files with different content types in a manner similar to: different content types using the following syntax:
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \ curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \
http://www.post.com/postit.cgi http://www.post.com/postit.cgi
If content-type is not specified, curl will try to guess from the extension If the content-type is not specified, curl will try to guess from the file
(it only knows a few), or use the previously specified type (from an earlier extension (it only knows a few), or use the previously specified type
file if several files are specified in a list) or finally using the default (from an earlier file if several files are specified in a list) or else it
type 'text/plain'. will using the default type 'text/plain'.
Emulate a fill-in form with -F. Let's say you fill in three fields in a Emulate a fill-in form with -F. Let's say you fill in three fields in a
form. One field is a file name which to post, one field is your name and one form. One field is a file name which to post, one field is your name and one
field is a file description. We want to post the file we have written named field is a file description. We want to post the file we have written named
"cooltext.txt". To let curl do the posting of this data instead of your "cooltext.txt". To let curl do the posting of this data instead of your
favourite browser, you have to check out the HTML of the form page to get to favourite browser, you have to read the HTML source of the form page and find
know the names of the input fields. In our example, the input field names are the names of the input fields. In our example, the input field names are
'file', 'yourname' and 'filedescription'. 'file', 'yourname' and 'filedescription'.
curl -F "file=@cooltext.txt" -F "yourname=Daniel" \ curl -F "file=@cooltext.txt" -F "yourname=Daniel" \
-F "filedescription=Cool text file with cool text inside" \ -F "filedescription=Cool text file with cool text inside" \
http://www.post.com/postit.cgi http://www.post.com/postit.cgi
So, to send two files in one post you can do it in two ways: To send two files in one post you can do it in two ways:
1. Send multiple files in a single "field" with a single field name: 1. Send multiple files in a single "field" with a single field name:
@@ -272,11 +280,11 @@ POST (HTTP)
curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif" curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif"
REFERER REFERRER
A HTTP request has the option to include information about which address A HTTP request has the option to include information about which address
that referred to actual page, and curl allows the user to specify that that referred to actual page. Curl allows you to specify the
referrer to get specified on the command line. It is especially useful to referrer to be used on the command line. It is especially useful to
fool or trick stupid servers or CGI scripts that rely on that information fool or trick stupid servers or CGI scripts that rely on that information
being available or contain certain data. being available or contain certain data.
@@ -345,13 +353,17 @@ COOKIES
Note that by specifying -b you enable the "cookie awareness" and with -L Note that by specifying -b you enable the "cookie awareness" and with -L
you can make curl follow a location: (which often is used in combination you can make curl follow a location: (which often is used in combination
with cookies). So that if a site sends cookies and a location, you can with cookies). So that if a site sends cookies and a location, you can
use a non-existing file to trig the cookie awareness like: use a non-existing file to trigger the cookie awareness like:
curl -L -b empty-file www.example.com curl -L -b empty.txt www.example.com
The file to read cookies from must be formatted using plain HTTP headers OR The file to read cookies from must be formatted using plain HTTP headers OR
as netscape's cookie file. Curl will determine what kind it is based on the as netscape's cookie file. Curl will determine what kind it is based on the
file contents. file contents. In the above command, curl will parse the header and store
the cookies received from www.example.com. curl will send to the server the
stored cookies which match the request as it follows the location. The
file "empty.txt" may be a non-existant file.
PROGRESS METER PROGRESS METER
@@ -384,12 +396,12 @@ PROGRESS METER
SPEED LIMIT SPEED LIMIT
Curl offers the user to set conditions regarding transfer speed that must Curl allows the user to set the transfer speed conditions that must be met
be met to let the transfer keep going. By using the switch -y and -Y you to let the transfer keep going. By using the switch -y and -Y you
can make curl abort transfers if the transfer speed doesn't exceed your can make curl abort transfers if the transfer speed is below the specified
given lowest limit for a specified time. lowest limit for a specified time.
To let curl abandon downloading this page if its slower than 3000 bytes per To have curl abort the download if the speed is slower than 3000 bytes per
second for 1 minute, run: second for 1 minute, run:
curl -y 3000 -Y 60 www.far-away-site.com curl -y 3000 -Y 60 www.far-away-site.com
@@ -455,9 +467,13 @@ EXTRA HEADERS
curl -H "X-you-and-me: yes" www.love.com curl -H "X-you-and-me: yes" www.love.com
This can also be useful in case you want curl to send a different text in This can also be useful in case you want curl to send a different text in a
a header than it normally does. The -H header you specify then replaces the header than it normally does. The -H header you specify then replaces the
header curl would normally send. header curl would normally send. If you replace an internal header with an
empty one, you prevent that header from being sent. To prevent the Host:
header from being used:
curl -H "Host:" www.server.com
FTP and PATH NAMES FTP and PATH NAMES
@@ -598,7 +614,7 @@ RESUMING FILE TRANSFERS
(*1) = This requires that the ftp server supports the non-standard command (*1) = This requires that the ftp server supports the non-standard command
SIZE. If it doesn't, curl will say so. SIZE. If it doesn't, curl will say so.
(*2) = This requires that the wb server supports at least HTTP/1.1. If it (*2) = This requires that the web server supports at least HTTP/1.1. If it
doesn't, curl will say so. doesn't, curl will say so.
TIME CONDITIONS TIME CONDITIONS
@@ -745,6 +761,25 @@ TELNET
to track when the login prompt is received and send the username and to track when the login prompt is received and send the username and
password accordingly. password accordingly.
PERSISTANT CONNECTIONS
Specifying multiple files on a single command line will make curl transfer
all of them, one after the other in the specified order.
libcurl will attempt to use persistant connections for the transfers so that
the second transfer to the same host can use the same connection that was
already initiated and was left open in the previous transfer. This greatly
decreases connection time for all but the first transfer and it makes a far
better use of the network.
Note that curl cannot use persistant connections for transfers that are used
in subsequence curl invokes. Try to stuff as many URLs as possible on the
same command line if they are using the same host, as that'll make the
transfers faster. If you use a http proxy for file transfers, practicly
all transfers will be persistant.
Persistant connections were introduced in curl 7.7.
MAILING LISTS MAILING LISTS
For your convenience, we have several open mailing lists to discuss curl, For your convenience, we have several open mailing lists to discuss curl,
@@ -753,10 +788,10 @@ MAILING LISTS
To subscribe to the main curl list, mail curl-request@contactor.se with To subscribe to the main curl list, mail curl-request@contactor.se with
"subscribe <fill in your email address>" in the body. "subscribe <fill in your email address>" in the body.
To subscribe to the libcurl users list, follow the instructions at To subscribe to the curl-library users/deverlopers list, follow the
http://curl.haxx.se/mail/ instructions at http://curl.haxx.se/mail/
To subscribe to the curl announce list, to only get information about new To subscribe to the curl-announce list, to only get information about new
releases, follow the instructions at http://curl.haxx.se/mail/ releases, follow the instructions at http://curl.haxx.se/mail/
To subscribe to the curl-and-PHP list in which curl using with PHP is To subscribe to the curl-and-PHP list in which curl using with PHP is

View File

@@ -6,6 +6,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = \ man_MANS = \
curl.1 \ curl.1 \
curl-config.1 \
curl_easy_cleanup.3 \ curl_easy_cleanup.3 \
curl_easy_getinfo.3 \ curl_easy_getinfo.3 \
curl_easy_init.3 \ curl_easy_init.3 \
@@ -17,7 +18,13 @@ man_MANS = \
curl_getenv.3 \ curl_getenv.3 \
curl_slist_append.3 \ curl_slist_append.3 \
curl_slist_free_all.3 \ curl_slist_free_all.3 \
curl_version.3 curl_version.3 \
curl_escape.3 \
curl_unescape.3 \
curl_strequal.3 \
curl_strnequal.3 \
curl_mprintf.3 \
libcurl.5
EXTRA_DIST = $(man_MANS) \ EXTRA_DIST = $(man_MANS) \
MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \ MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS \

View File

@@ -22,3 +22,8 @@ README.win32
in order to extract a separate text file: in order to extract a separate text file:
curl -M >manual.txt curl -M >manual.txt
Download all the libcurl man pages in HTML format using the link on the
bottom of this page:
http://curl.haxx.se/libcurl/c/

View File

@@ -9,21 +9,26 @@ TODO
Things to do in project cURL. Please tell me what you think, contribute and Things to do in project cURL. Please tell me what you think, contribute and
send me patches that improve things! send me patches that improve things!
To do for the 7.7 release: To do for the next release:
* Fix the random seeding. Add --egd-socket and --random-file options to the * Make sure SSL works even when IPv6 is enabled. We just can't connect to
curl client and libcurl curl_easy_setopt() interface. IPv6 sites and use SSL, but we should detect that particular condition
and warn about it.
* Support persistant connections (fully detailed elsewhere)
* Add a special connection-timeout that only goes for the connection phase.
To do for the 7.8 release:
* Make SSL session ids get used if multiple HTTPS documents from the same * Make SSL session ids get used if multiple HTTPS documents from the same
host is requested. host is requested.
To do in a future release: To do in a future release (random order):
* Rewrite parts of the test suite. Make a (XML?) format to store all
test-data in a single for a single test case. The current system makes far
too many separate files. We also need to have the test suite support
different behaviors, like when libcurl is compiled for IPv6 support and
thus performs a different set of FTP commands.
* Add configure options that disables certain protocols in libcurl to
decrease footprint. '--disable-[protocol]' where protocol is http, ftp,
telnet, ldap, dict or file.
* Extend the test suite to include telnet and https. The telnet could just do * Extend the test suite to include telnet and https. The telnet could just do
ftp or http operations (for which we have test servers) and the https would ftp or http operations (for which we have test servers) and the https would
@@ -33,9 +38,10 @@ To do in a future release:
stamp as the remote file. libcurl already is capable of fetching the remote stamp as the remote file. libcurl already is capable of fetching the remote
file's date. file's date.
* Make the SSL layer option capable of using the Mozilla Security Services as * Make curl's SSL layer option capable of using other free SSL libraries.
an alternative to OpenSSL: Such as the Mozilla Security Services
http://www.mozilla.org/projects/security/pki/nss/ (http://www.mozilla.org/projects/security/pki/nss/) and GNUTLS
(http://gnutls.hellug.gr/)
* Add asynchronous name resolving, as this enables full timeout support for * Add asynchronous name resolving, as this enables full timeout support for
fork() systems. fork() systems.
@@ -84,5 +90,3 @@ To do in a future release:
EPRT for IPv6 (done), and EPSV instead of PASV. HTTP proxies are left to EPRT for IPv6 (done), and EPSV instead of PASV. HTTP proxies are left to
add support for. add support for.
* SSL for more protocols, like SSL-FTP...
(http://search.ietf.org/internet-drafts/draft-murray-auth-ftp-ssl-05.txt)

54
docs/curl-config.1 Normal file
View File

@@ -0,0 +1,54 @@
.\" You can view this file with:
.\" nroff -man curl-config.1
.\" Written by Daniel Stenberg
.\"
.TH curl-config 1 "18 March 2001" "Curl 7.7.2" "curl-config manual"
.SH NAME
curl-config \- Get information about a libcurl installation
.SH SYNOPSIS
.B curl-config [options]
.SH DESCRIPTION
.B curl-config
displays information about a previous curl and libcurl installation.
.SH OPTIONS
.IP "--cflags"
What set of CFLAGS that was used when libcurl was built. This is mostly a
debug option that serves no particular use to most people.
.IP "--feature"
Lists what particular main features the installed libcurl was built with. At
the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
any particular order. The keywords will be separated by newlines. There may be
none, one or several keywords in the list.
.IP "--help"
Displays the available options.
.IP "--libs"
Shows the complete set of libs and other linker options you will need in order
to link your application with libcurl.
.IP "--prefix"
This is the prefix used when libcurl was installed. Libcurl is then installed
in $prefix/lib and its header files are installed in $prefix/include and so
on. The prefix is set with "configure --prefix".
.IP "--version"
Outputs version information about the installed libcurl.
.SH "EXAMPLES"
What is the path to the curl header files?
echo `curl-config --prefix`/include
What is the path to libcurl?
echo `curl-config --prefix`/lib
What other linker options do I need when I link with libcurl?
curl-config --libs
How do I know if libcurl was built with SSL support?
curl-config --feature | grep SSL
What's the installed libcurl version?
curl-config --version
.SH "SEE ALSO"
.BR curl (1)

View File

@@ -2,7 +2,7 @@
.\" nroff -man curl.1 .\" nroff -man curl.1
.\" Written by Daniel Stenberg .\" Written by Daniel Stenberg
.\" .\"
.TH curl 1 "19 January 2001" "Curl 7.6" "Curl Manual" .TH curl 1 "20 April 2001" "Curl 7.7.2" "Curl Manual"
.SH NAME .SH NAME
curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or curl \- get a URL with FTP, TELNET, LDAP, GOPHER, DICT, FILE, HTTP or
HTTPS syntax. HTTPS syntax.
@@ -41,6 +41,12 @@ supported at the moment:
Starting with curl 7.6, you can specify any amount of URLs on the command Starting with curl 7.6, you can specify any amount of URLs on the command
line. They will be fetched in a sequential manner in the specified order. line. They will be fetched in a sequential manner in the specified order.
Starting with curl 7.7, curl will attempt to re-use connections for multiple
file transfers, so that getting many files from the same server will not do
multiple connects/handshakes. This improves speed. Of course this is only done
on files specified on a single command line and cannot be used between
separate curl invokes.
.SH OPTIONS .SH OPTIONS
.IP "-a/--append" .IP "-a/--append"
(FTP) (FTP)
@@ -85,6 +91,15 @@ also be enforced by using an URL that ends with ";type=A". This option causes
data sent to stdout to be in text mode for win32 systems. data sent to stdout to be in text mode for win32 systems.
If this option is used twice, the second one will disable ASCII usage. If this option is used twice, the second one will disable ASCII usage.
.IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is
of no more use. This option didn't work in win32 systems until 7.7.2. See
also the
.I "--max-time"
option.
If this option is used several times, the last one will be used.
.IP "-c/--continue" .IP "-c/--continue"
.B Deprecated. Use '-C -' instead. .B Deprecated. Use '-C -' instead.
Continue/Resume a previous file transfer. This instructs curl to Continue/Resume a previous file transfer. This instructs curl to
@@ -103,17 +118,18 @@ If used with uploads, the ftp server command SIZE will not be used by
curl. Upload resume is for FTP only. curl. Upload resume is for FTP only.
HTTP resume is only possible with HTTP/1.1 or later servers. HTTP resume is only possible with HTTP/1.1 or later servers.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-d/--data <data>" .IP "-d/--data <data>"
(HTTP) Sends the specified data in a POST request to the HTTP server. Note (HTTP) Sends the specified data in a POST request to the HTTP server, in a way
that the data is sent exactly as specified with no extra processing (with all that can emulate as if a user has filled in a HTML form and pressed the submit
newlines cut off). The data is expected to be "url-encoded". This will cause button. Note that the data is sent exactly as specified with no extra
curl to pass the data to the server using the content-type processing (with all newlines cut off). The data is expected to be
application/x-www-form-urlencoded. Compare to -F. If more than one -d/--data "url-encoded". This will cause curl to pass the data to the server using the
option is used on the same command line, the data pieces specified will be content-type application/x-www-form-urlencoded. Compare to -F. If more than
merged together with a separating &-letter. Thus, using '-d name=daniel -d one -d/--data option is used on the same command line, the data pieces
skill=lousy' would generate a post chunk that looks like specified will be merged together with a separating &-letter. Thus, using '-d
'name=daniel&skill=lousy'. name=daniel -d skill=lousy' would generate a post chunk that looks like
\&'name=daniel&skill=lousy'.
If you start the data with the letter @, the rest should be a file name to If you start the data with the letter @, the rest should be a file name to
read the data from, or - if you want curl to read the data from stdin. The read the data from, or - if you want curl to read the data from stdin. The
@@ -124,12 +140,12 @@ To post data purely binary, you should instead use the --data-binary option.
-d/--data is the same as --data-ascii. -d/--data is the same as --data-ascii.
If this option is used serveral times, the ones following the first will If this option is used several times, the ones following the first will
append data. append data.
.IP "--data-ascii <data>" .IP "--data-ascii <data>"
(HTTP) This is an alias for the -d/--data option. (HTTP) This is an alias for the -d/--data option.
If this option is used serveral times, the ones following the first will If this option is used several times, the ones following the first will
append data. append data.
.IP "--data-binary <data>" .IP "--data-binary <data>"
(HTTP) This posts data in a similar manner as --data-ascii does, although when (HTTP) This posts data in a similar manner as --data-ascii does, although when
@@ -137,9 +153,9 @@ using this option the entire context of the posted data is kept as-is. If you
want to post a binary file without the strip-newlines feature of the want to post a binary file without the strip-newlines feature of the
--data-ascii option, this is for you. --data-ascii option, this is for you.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
If this option is used serveral times, the ones following the first will If this option is used several times, the ones following the first will
append data. append data.
.IP "-D/--dump-header <file>" .IP "-D/--dump-header <file>"
(HTTP/FTP) (HTTP/FTP)
@@ -150,7 +166,7 @@ This option is handy to use when you want to store the cookies that a HTTP
site sends to you. The cookies could then be read in a second curl invoke by site sends to you. The cookies could then be read in a second curl invoke by
using the -b/--cookie option! using the -b/--cookie option!
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-e/--referer <URL>" .IP "-e/--referer <URL>"
(HTTP) Sends the "Referer Page" information to the HTTP server. This can also (HTTP) Sends the "Referer Page" information to the HTTP server. This can also
be set with the -H/--header flag of course. When used with be set with the -H/--header flag of course. When used with
@@ -159,7 +175,12 @@ you can append ";auto" to the referer URL to make curl automatically set the
previous URL when it follows a Location: header. The ";auto" string can be previous URL when it follows a Location: header. The ";auto" string can be
used alone, even if you don't set an initial referer. used alone, even if you don't set an initial referer.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--egd-file <file>"
(HTTPS) Specify the path name to the Entropy Gathering Daemon socket. The
socket is used to seed the random engine for SSL connections. See also the
.I "--random-file"
option.
.IP "-E/--cert <certificate[:password]>" .IP "-E/--cert <certificate[:password]>"
(HTTPS) (HTTPS)
Tells curl to use the specified certificate file when getting a file Tells curl to use the specified certificate file when getting a file
@@ -168,12 +189,12 @@ If the optional password isn't specified, it will be queried for on
the terminal. Note that this certificate is the private key and the private the terminal. Note that this certificate is the private key and the private
certificate concatenated! certificate concatenated!
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--cacert <CA certificate>" .IP "--cacert <CA certificate>"
(HTTPS) Tells curl to use the specified certificate file to verify the (HTTPS) Tells curl to use the specified certificate file to verify the
peer. The certificate must be in PEM format. peer. The certificate must be in PEM format.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-f/--fail" .IP "-f/--fail"
(HTTP) (HTTP)
Fail silently (no output at all) on server errors. This is mostly done Fail silently (no output at all) on server errors. This is mostly done
@@ -195,7 +216,7 @@ get attached in the post as a file upload, while the < makes a text field and
just get the contents for that text field from a file. just get the contents for that text field from a file.
Example, to send your password file to the server, where Example, to send your password file to the server, where
'password' is the name of the form-field to which /etc/passwd will be the \&'password' is the name of the form-field to which /etc/passwd will be the
input: input:
.B curl .B curl
@@ -236,7 +257,7 @@ name, IP address or host name. An example could look like:
.B "curl --interface eth0:1 http://www.netscape.com/" .B "curl --interface eth0:1 http://www.netscape.com/"
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-I/--head" .IP "-I/--head"
(HTTP/FTP) (HTTP/FTP)
Fetch the HTTP-header only! HTTP-servers feature the command HEAD Fetch the HTTP-header only! HTTP-servers feature the command HEAD
@@ -249,7 +270,7 @@ If this option is used twice, the second will again disable header only.
should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use should be one of 'clear', 'safe', 'confidential' or 'private'. Should you use
a level that is not one of these, 'private' will instead be used. a level that is not one of these, 'private' will instead be used.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-K/--config <config file>" .IP "-K/--config <config file>"
Specify which config file to read curl arguments from. The config file is a Specify which config file to read curl arguments from. The config file is a
text file in which command line arguments can be written which then will be text file in which command line arguments can be written which then will be
@@ -283,8 +304,11 @@ If this option is used twice, the second will again disable location following.
Maximum time in seconds that you allow the whole operation to take. This is Maximum time in seconds that you allow the whole operation to take. This is
useful for preventing your batch jobs from hanging for hours due to slow useful for preventing your batch jobs from hanging for hours due to slow
networks or links going down. This doesn't work fully in win32 systems. networks or links going down. This doesn't work fully in win32 systems.
See also the
.I "--connect-timeout"
option.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-M/--manual" .IP "-M/--manual"
Manual. Display the huge help text. Manual. Display the huge help text.
.IP "-n/--netrc" .IP "-n/--netrc"
@@ -302,7 +326,7 @@ directory.
A quick and very simple example of how to setup a A quick and very simple example of how to setup a
.I .netrc .I .netrc
to allow curl to ftp to the machine host.domain.com with user name to allow curl to ftp to the machine host.domain.com with user name
'myself' and password 'secret' should look similar to: \&'myself' and password 'secret' should look similar to:
.B "machine host.domain.com login myself password secret" .B "machine host.domain.com login myself password secret"
@@ -362,7 +386,7 @@ i.e "my.host.domain" to specify machine
(any single-letter string) to make it pick the machine's default (any single-letter string) to make it pick the machine's default
.RE .RE
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-q" .IP "-q"
If used as the first parameter on the command line, the If used as the first parameter on the command line, the
.I $HOME/.curlrc .I $HOME/.curlrc
@@ -377,6 +401,12 @@ to be run before and after the transfer. If the server returns failure for one
of the commands, the entire operation will be aborted. of the commands, the entire operation will be aborted.
This option can be used multiple times. This option can be used multiple times.
.IP "--random-file <file>"
(HTTPS) Specify the path name to file containing what will be considered as
random data. The data is used to seed the random engine for SSL connections.
See also the
.I "--edg-file"
option.
.IP "-r/--range <range>" .IP "-r/--range <range>"
(HTTP/FTP) (HTTP/FTP)
Retrieve a byte range (i.e a partial document) from a HTTP/1.1 or FTP Retrieve a byte range (i.e a partial document) from a HTTP/1.1 or FTP
@@ -415,7 +445,7 @@ document.
FTP range downloads only support the simple syntax 'start-stop' (optionally FTP range downloads only support the simple syntax 'start-stop' (optionally
with one of the numbers omitted). It depends on the non-RFC command SIZE. with one of the numbers omitted). It depends on the non-RFC command SIZE.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-s/--silent" .IP "-s/--silent"
Silent mode. Don't show progress meter or error messages. Makes Silent mode. Don't show progress meter or error messages. Makes
Curl mute. Curl mute.
@@ -442,18 +472,18 @@ think that your last directory name is the remote file name to
use. That will most likely cause the upload operation to fail. If use. That will most likely cause the upload operation to fail. If
this is used on a http(s) server, the PUT command will be used. this is used on a http(s) server, the PUT command will be used.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-u/--user <user:password>" .IP "-u/--user <user:password>"
Specify user and password to use when fetching. See README.curl for detailed Specify user and password to use when fetching. See README.curl for detailed
examples of how to use this. If no password is specified, curl will examples of how to use this. If no password is specified, curl will
ask for it interactively. ask for it interactively.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-U/--proxy-user <user:password>" .IP "-U/--proxy-user <user:password>"
Specify user and password to use for Proxy authentication. If no Specify user and password to use for Proxy authentication. If no
password is specified, curl will ask for it interactively. password is specified, curl will ask for it interactively.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--url <URL>" .IP "--url <URL>"
Specify a URL to fetch. This option is mostly handy when you wanna specify Specify a URL to fetch. This option is mostly handy when you wanna specify
URL(s) in a config file. URL(s) in a config file.
@@ -536,12 +566,12 @@ The average download speed that curl measured for the complete download.
The average upload speed that curl measured for the complete upload. The average upload speed that curl measured for the complete upload.
.RE .RE
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-x/--proxy <proxyhost[:port]>" .IP "-x/--proxy <proxyhost[:port]>"
Use specified proxy. If the port number is not specified, it is assumed at Use specified proxy. If the port number is not specified, it is assumed at
port 1080. port 1080.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-X/--request <command>" .IP "-X/--request <command>"
(HTTP) (HTTP)
Specifies a custom request to use when communicating with the HTTP server. Specifies a custom request to use when communicating with the HTTP server.
@@ -552,19 +582,19 @@ HTTP 1.1 specification for details and explanations.
Specifies a custom FTP command to use instead of LIST when doing file lists Specifies a custom FTP command to use instead of LIST when doing file lists
with ftp. with ftp.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-y/--speed-time <time>" .IP "-y/--speed-time <time>"
If a download is slower than speed-limit bytes per second during a speed-time If a download is slower than speed-limit bytes per second during a speed-time
period, the download gets aborted. If speed-time is used, the default period, the download gets aborted. If speed-time is used, the default
speed-limit will be 1 unless set with -y. speed-limit will be 1 unless set with -y.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-Y/--speed-limit <speed>" .IP "-Y/--speed-limit <speed>"
If a download is slower than this given speed, in bytes per second, for If a download is slower than this given speed, in bytes per second, for
speed-time seconds it gets aborted. speed-time is set with -Y and is 30 if speed-time seconds it gets aborted. speed-time is set with -Y and is 30 if
not set. not set.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-z/--time-cond <date expression>" .IP "-z/--time-cond <date expression>"
(HTTP) (HTTP)
Request to get a file that has been modified later than the given time and Request to get a file that has been modified later than the given time and
@@ -580,7 +610,7 @@ Start the date expression with a dash (-) to make it request for a document
that is older than the given date/time, default is a document that is newer that is older than the given date/time, default is a document that is newer
than the specified date/time. than the specified date/time.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-3/--sslv3" .IP "-3/--sslv3"
(HTTPS) (HTTPS)
Forces curl to use SSL version 3 when negotiating with a remote SSL server. Forces curl to use SSL version 3 when negotiating with a remote SSL server.
@@ -601,7 +631,7 @@ Redirect all writes to stderr to the specified file instead. If the file name
is a plain '-', it is instead written to stdout. This option has no point when is a plain '-', it is instead written to stdout. This option has no point when
you're using a shell with decent redirecting capabilities. you're using a shell with decent redirecting capabilities.
If this option is used serveral times, the last one will be used. If this option is used several times, the last one will be used.
.SH FILES .SH FILES
.I ~/.curlrc .I ~/.curlrc
.RS .RS
@@ -792,6 +822,11 @@ If you do find bugs, mail them to curl-bug@haxx.se.
- Robert Weaver <robert.weaver@sabre.com> - Robert Weaver <robert.weaver@sabre.com>
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com> - Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
- Jun-ichiro itojun Hagino <itojun@iijlab.net> - Jun-ichiro itojun Hagino <itojun@iijlab.net>
- Frederic Lepied <flepied@mandrakesoft.com>
- Georg Horn <horn@koblenz-net.de>
- Cris Bailiff <c.bailiff@awayweb.com>
- Sterling Hughes <sterling@designmultimedia.com>
- S. Moonesamy
.SH WWW .SH WWW
http://curl.haxx.se http://curl.haxx.se

View File

@@ -2,13 +2,13 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" Written by daniel@haxx.se .\" Written by daniel@haxx.se
.\" .\"
.TH curl_easy_setopt 3 "6 March 2001" "libcurl 7.5" "libcurl Manual" .TH curl_easy_setopt 3 "10 April 2001" "libcurl 7.7.2" "libcurl Manual"
.SH NAME .SH NAME
curl_easy_setopt - Set curl easy-session options curl_easy_setopt - Set curl easy-session options
.SH SYNOPSIS .SH SYNOPSIS
.B #include <curl/curl.h> .B #include <curl/curl.h>
.sp .sp
.BI "CURLcode curl_easy_setopt(CURL *" handle ", CURLoption "option ", ...); .BI "CURLcode curl_easy_setopt(CURL *" handle ", CURLoption "option ", ...);"
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
curl_easy_setopt() is called to tell libcurl how to behave in a number of curl_easy_setopt() is called to tell libcurl how to behave in a number of
@@ -26,6 +26,13 @@ NOTE: strings passed to libcurl as 'char *' arguments, will not be copied by
the library. Instead you should keep them available until libcurl no longer the library. Instead you should keep them available until libcurl no longer
needs them. Failing to do so will cause very odd behaviour or even crashes. needs them. Failing to do so will cause very odd behaviour or even crashes.
More note: the options set with this function call are valid for the
forthcoming data transfers that are performed when you invoke
.I curl_easy_perform .
The options are not in any way reset between transfers, so if you want
subsequent transfers with different options, you must change them between the
transfers.
The The
.I "handle" .I "handle"
is the return code from the is the return code from the
@@ -35,54 +42,43 @@ call.
These options are in a bit of random order, but you'll figure it out! These options are in a bit of random order, but you'll figure it out!
.TP 0.8i .TP 0.8i
.B CURLOPT_FILE .B CURLOPT_FILE
Data pointer to pass instead of FILE * to the file write function. Note that Data pointer to pass to file write function. Note that if you specify the
if you specify the
.I CURLOPT_WRITEFUNCTION .I CURLOPT_WRITEFUNCTION
, this is the pointer you'll get as input. , this is the pointer you'll get as input. If you don't use a callback, you
must pass a 'FILE *' as libcurl passes it to fwrite() when writing data.
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a NOTE: If you're using libcurl as a win32 DLL, you MUST use the
.I CURLOPT_WRITEFUNCTION \fICURLOPT_WRITEFUNCTION\fP if you set this option.
if you set the
.I CURLOPT_FILE
option.
.TP .TP
.B CURLOPT_WRITEFUNCTION .B CURLOPT_WRITEFUNCTION
Function pointer that should use match the following prototype: Function pointer that should match the following prototype:
.BI "size_t function( void *ptr, size_t size, size_t nmemb, FILE *stream);" .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
This function gets called by libcurl as soon as there is received data that This function gets called by libcurl as soon as there is received data that
needs to be written down. The size of the data pointed to by needs to be written down. The size of the data pointed to by \fIptr\fP is
.I ptr \fIsize\fP multiplied with \fInmemb\fP. Return the number of bytes actually
is written or return -1 to signal error to the library (it will cause it to abort
.I size the transfer with CURLE_WRITE_ERROR).
multiplied with
.I nmemb. Set the \fIstream\fP argument with the \fBCURLOPT_FILE\fP option.
Return the number of bytes actually written or return -1 to signal error to the library (it will cause it to abort the transfer).
.TP .TP
.B CURLOPT_INFILE .B CURLOPT_INFILE
Data pointer to pass instead of FILE * to the file read function. Note that if Data pointer to pass to the file read function. Note that if you specify the
you specify the \fICURLOPT_READFUNCTION\fP, this is the pointer you'll get as input. If you
.I CURLOPT_READFUNCTION don't specify a read callback, this must be a valid FILE *.
, this is the pointer you'll get as input.
NOTE: If you're using libcurl as a win32 .DLL, you MUST use a NOTE: If you're using libcurl as a win32 DLL, you MUST use a
.I CURLOPT_READFUNCTION \fICURLOPT_READFUNCTION\fP if you set this option.
if you set the
.I CURLOPT_INFILE
option.
.TP .TP
.B CURLOPT_READFUNCTION .B CURLOPT_READFUNCTION
Function pointer that should use match the following prototype: Function pointer that should match the following prototype:
.BI "size_t function( void *ptr, size_t size, size_t nmemb, FILE *stream);" .BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
This function gets called by libcurl as soon as it needs to read data in order This function gets called by libcurl as soon as it needs to read data in order
to send it to the peer. The data area pointed at by the pointer to send it to the peer. The data area pointed at by the pointer \fIptr\fP may
.I ptr be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of
may be filled with at most bytes. Your function must return the actual number of bytes that you stored in
.I size that memory area. Returning -1 will signal an error to the library and cause
multiplied with it to abort the current transfer immediately (with a CURLE_READ_ERROR return
.I nmemb code).
number of bytes. Your function must return the actual number of bytes that you
stored in that memory area. Returning -1 will signal an error to the library
and cause it to abort the current transfer immediately.
.TP .TP
.B CURLOPT_INFILESIZE .B CURLOPT_INFILESIZE
When uploading a file to a remote site, this option should be used to tell When uploading a file to a remote site, this option should be used to tell
@@ -267,7 +263,11 @@ curl_slist' structs properly filled in. Use
.I curl_slist_append(3) .I curl_slist_append(3)
to create the list and to create the list and
.I curl_slist_free_all(3) .I curl_slist_free_all(3)
to clean up an entire list. to clean up an entire list. If you add a header that is otherwise generated
and used by libcurl internally, your added one will be used instead. If you
add a header with no contents as in 'Accept:', the internally used header will
just get disabled. Thus, using this option you can add new headers, replace
internal headers and remove internal headers.
.TP .TP
.B CURLOPT_HTTPPOST .B CURLOPT_HTTPPOST
Tells libcurl you want a multipart/formdata HTTP POST to be made and you Tells libcurl you want a multipart/formdata HTTP POST to be made and you
@@ -306,7 +306,33 @@ struct curl_slist structs properly filled in as described for
.I "CURLOPT_QUOTE" .I "CURLOPT_QUOTE"
.TP .TP
.B CURLOPT_WRITEHEADER .B CURLOPT_WRITEHEADER
Pass a FILE * to be used to write the header part of the received data to. Pass a pointer to be used to write the header part of the received data to. If
you don't use a callback to take care of the writing, this must be a FILE
*. The headers are guaranteed to be written one-by-one and only complete lines
are written. Parsing headers should be easy enough using this. See also the
\fICURLOPT_HEADERFUNCTION\fP option.
.TP
.B CURLOPT_HEADERFUNCTION
Function pointer that should match the following prototype:
.BI "size_t function( void *ptr, size_t size, size_t nmemb, void *stream);"
This function gets called by libcurl as soon as there is received header data
that needs to be written down. The function will be called once for each
header with a complete header line in each invoke. The size of the data
pointed to by
.I ptr
is
.I size
multiplied with
.I nmemb.
The pointer named
.I stream
will be the one you passed to libcurl with the
.I CURLOPT_WRITEHEADER
option.
Return the number of bytes actually written or return -1 to signal error to
the library (it will cause it to abort the transfer with a
.I CURLE_WRITE_ERROR
return code). (Added in libcurl 7.7.2)
.TP .TP
.B CURLOPT_COOKIEFILE .B CURLOPT_COOKIEFILE
Pass a pointer to a zero terminated string as parameter. It should contain the Pass a pointer to a zero terminated string as parameter. It should contain the
@@ -346,7 +372,7 @@ name. (Added in libcurl 7.3)
.B CURLOPT_KRB4LEVEL .B CURLOPT_KRB4LEVEL
Pass a char * as parameter. Set the krb4 security level, this also enables Pass a char * as parameter. Set the krb4 security level, this also enables
krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or krb4 awareness. This is a string, 'clear', 'safe', 'confidential' or
'private'. If the string is set but doesn't match one of these, 'private' \&'private'. If the string is set but doesn't match one of these, 'private'
will be used. Set the string to NULL to disable kerberos4. The kerberos will be used. Set the string to NULL to disable kerberos4. The kerberos
support only works for FTP. (Added in libcurl 7.3) support only works for FTP. (Added in libcurl 7.3)
.TP .TP
@@ -419,6 +445,59 @@ Pass a long. The set number will be the redirection limit. If that many
redirections have been followed, the next redirect will cause an error. This redirections have been followed, the next redirect will cause an error. This
option only makes sense if the CURLOPT_FOLLOWLOCATION is used at the same option only makes sense if the CURLOPT_FOLLOWLOCATION is used at the same
time. (Added in 7.5) time. (Added in 7.5)
.TP
.B CURLOPT_MAXCONNECTS
Pass a long. The set number will be the persistant connection cache size. The
set amount will be the maximum amount of simultaneous connections that libcurl
may cache between file transfers. Default is 5, and there isn't much point in
changing this value unless you are perfectly aware of how this work and
changes libcurl's behaviour. Note: if you have already performed transfers
with this curl handle, setting a smaller MAXCONNECTS than before may cause
open connections to unnecessarily get closed. (Added in 7.7)
.TP
.B CURLOPT_CLOSEPOLICY
Pass a long. This option sets what policy libcurl should use when the
connection cache is filled and one of the open connections has to be closed to
make room for a new connection. This must be one of the CURLCLOSEPOLICY_*
defines. Use CURLCLOSEPOLICY_LEAST_RECENTLY_USED to make libcurl close the
connection that was least recently used, that connection is also least likely
to be capable of re-use. Use CURLCLOSEPOLICY_OLDEST to make libcurl close the
oldest connection, the one that was created first among the ones in the
connection cache. The other close policies are not support yet. (Added in 7.7)
.TP
.B CURLOPT_FRESH_CONNECT
Pass a long. Set to non-zero to make the next transfer use a new connection by
force. If the connection cache is full before this connection, one of the
existinf connections will be closed as according to the set policy. This
option should be used with caution and only if you understand what it
does. Set to 0 to have libcurl attempt re-use of an existing connection.
(Added in 7.7)
.TP
.B CURLOPT_FORBID_REUSE
Pass a long. Set to non-zero to make the next transfer explicitly close the
connection when done. Normally, libcurl keep all connections alive when done
with one transfer in case there comes a succeeding one that can re-use them.
This option should be used with caution and only if you understand what it
does. Set to 0 to have libcurl keep the connection open for possibly later
re-use. (Added in 7.7)
.TP
.B CURLOPT_RANDOM_FILE
Pass a char * to a zero terminated file name. The file will be used to read
from to seed the random engine for SSL. The more random the specified file is,
the more secure will the SSL connection become.
.TP
.B CURLOPT_EGDSOCKET
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
socket. It will be used to seed the random engine for SSL.
.TP
.B CURLOPT_CONNECTTIMEOUT
Pass a long. It should contain the maximum time in seconds that you allow the
connection to the server to take. This only limits the connection phase, once
it has connected, this option is of no more use. Set to zero to disable
connection timeout (it will then only timeout on the system's internal
timeouts). This option doesn't work in win32 systems. See also the
.I CURLOPT_TIMEOUT
option.
.PP .PP
.SH RETURN VALUE .SH RETURN VALUE
0 means the option was set properly, non-zero means an error as 0 means the option was set properly, non-zero means an error as

28
docs/curl_escape.3 Normal file
View File

@@ -0,0 +1,28 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_escape 3 "22 March 2001" "libcurl 7.7" "libcurl Manual"
.SH NAME
curl_escape - URL encodes the given string
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "char *curl_escape( char *" url ", int "length " );"
.ad
.SH DESCRIPTION
This function will convert the given input string to an URL encoded string and
return that as a new allocated string. All input characters that are not a-z,
A-Z or 0-9 will be converted to their "URL escaped" version. If a sequence of
%NN (where NN is a two-digit hexadecimal number) is found in the string to
encode, that 3-letter combination will be copied to the output unmodifed,
assuming that it is an already encoded piece of data.
If the 'length' argument is set to 0, curl_escape() will use strlen() on the
input 'url' string to find out the size.
You must free() the returned string when you're done with it.
.SH RETURN VALUE
A pointer to a zero terminated string or NULL if it failed.
.SH "SEE ALSO"
.I curl_unescape(), RFC 2396

View File

@@ -2,7 +2,7 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" Written by daniel@haxx.se .\" Written by daniel@haxx.se
.\" .\"
.TH curl_formfree 3 "5 March 2001" "libcurl 7.5" "libcurl Manual" .TH curl_formfree 3 "6 April 2001" "libcurl 7.7.1" "libcurl Manual"
.SH NAME .SH NAME
curl_formfree - free a previously build multipart/formdata HTTP POST chain curl_formfree - free a previously build multipart/formdata HTTP POST chain
.SH SYNOPSIS .SH SYNOPSIS
@@ -19,5 +19,7 @@ None
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_formparse "(3) " .BR curl_formparse "(3) "
.SH BUGS .SH BUGS
Surely there are some, you tell me! libcurl 7.7.1 and earlier versions does not allow a NULL pointer to be used as
argument.

View File

@@ -2,26 +2,31 @@
.\" nroff -man [file] .\" nroff -man [file]
.\" Written by daniel@haxx.se .\" Written by daniel@haxx.se
.\" .\"
.TH curl_formparse 3 "5 March 2001" "libcurl 7.0" "libcurl Manual" .TH curl_formparse 3 "3 May 2001" "libcurl 7.7.2" "libcurl Manual"
.SH NAME .SH NAME
curl_formparse - add a section to a multipart/formdata HTTP POST curl_formparse - add a section to a multipart/formdata HTTP POST
.SH SYNOPSIS .SH SYNOPSIS
.B #include <curl/curl.h> .B #include <curl/curl.h>
.sp .sp
.BI "CURLcode curl_formparse(char *" string, "struct HttpPost **" firstitem, .BI "CURLcode curl_formparse(char * " string, " struct HttpPost ** " firstitem,
.BI "struct HttpPost ** "lastitem ");" .BI "struct HttpPost ** " lastitem ");"
.ad .ad
.SH DESCRIPTION .SH DESCRIPTION
curl_formparse() is used to append sections when building a multipart/formdata curl_formparse() is used to append sections when building a multipart/formdata
HTTP POST. Append one section at a time until you've added all the sections HTTP POST (sometimes refered to as rfc1867-style posts). Append one section at
you want included and then you pass the a time until you've added all the sections you want included and then you pass
.I firstitem the \fI firstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
pointer as parameter to CURLOPT_HTTPPOST. \fIlastitem\fP is set after each call and on repeated invokes it should be
.I lastitem left as set to allow repeated invokes to find the end of the list in a faster
is set after each call and on repeated invokes it should be left as set to way. \fIstring\fP must be a zero terminated string abiding to the syntax
allow repeated invokes to find the end of the list in a faster way. described in a section below
.I string
must be a zero terminated string following the following syntax. The pointers \fIfirstitem\fP and \fIlastitem\fP point to, should both be
pointers to NULL in the first call to this function. All list-data will be
allocated by the function itself. You must call \fIcurl_formfree\fP after the
form post has been done to free the resources again.
See example below.
.SH "FORM PARSE STRINGS" .SH "FORM PARSE STRINGS"
The The
.I string .I string
@@ -55,6 +60,18 @@ content-type for all of them in the same way as with a single file.
.PP .PP
.SH RETURN VALUE .SH RETURN VALUE
Returns non-zero if an error occurs. Returns non-zero if an error occurs.
.SH EXAMPLE
HttpPost* post = NULL;
HttpPost* last = NULL;
/* Add an image section */
curl_formparse("picture=@my-face.jpg", &post, &last);
/* Add a normal text section */
curl_formparse("name=FooBar", &post, &last);
/* Set the form info */
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
.SH "SEE ALSO" .SH "SEE ALSO"
.BR curl_easy_setopt "(3) " .BR curl_easy_setopt "(3) "
.SH BUGS .SH BUGS

88
docs/curl_mprintf.3 Normal file
View File

@@ -0,0 +1,88 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_printf 3 "20 April 2001" "libcurl 7.7.2" "libcurl Manual"
.SH NAME
curl_maprintf, curl_mfprintf, curl_mprintf, curl_msnprintf, curl_msprintf
curl_mvaprintf, curl_mvfprintf, curl_mvprintf, curl_mvsnprintf,
curl_mvsprintf - formatted output conversion
.SH SYNOPSIS
.B #include <curl/mprintf.h>
.sp
.BI "int curl_mprintf(const char *" format ", ...);"
.br
.BI "int curl_mfprintf(FILE *" fd ", const char *" format ", ...);"
.br
.BI "int curl_msprintf(char *" buffer ", const char *" format ", ...);"
.br
.BI "int curl_msnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", ...);"
.br
.BI "int curl_mvprintf(const char *" format ", va_list " args ");"
.br
.BI "int curl_mvfprintf(FILE *" fd ", const char *" format ", va_list " args ");"
.br
.BI "int curl_mvsprintf(char *" buffer ", const char *" format ", va_list " args ");"
.br
.BI "int curl_mvsnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", va_list " args ");"
.br
.BI "char *curl_maprintf(const char *" format ", ...);"
.br
.BI "char *curl_mvaprintf(const char *" format ", va_list " args ");"
.SH DESCRIPTION
These are all functions that produces output according to a format string and
given arguments. These are mostly clones of the well-known C-style functions
and there will be no detailed explanation of all available formatting rules
and usage here.
See this table for notable exceptions.
.RS
.TP
.B curl_mprintf()
Normal printf() clone.
.TP
.B curl_mfprintf()
Normal fprinf() clone.
.TP
.B curl_msprintf()
Normal sprintf() clone.
.TP
.B curl_msnprintf()
snprintf() clone. Many systems don't have this. It is just like \fBsprintf\fP
but with an extra argument after the buffer that specifies the length of the
target buffer.
.TP
.B curl_mvprintf()
Normal vprintf() clone.
.TP
.B curl_mvfprintf()
Normal vfprintf() clone.
.TP
.B curl_mvsprintf()
Normal vsprintf() clone.
.TP
.B curl_mvsnprintf()
vsnprintf() clone. Many systems don't have this. It is just like
\fBvsprintf\fP but with an extra argument after the buffer that specifies the
length of the target buffer.
.TP
.B curl_maprintf()
Like printf() but returns the output string as a malloc()ed string. The
returned string must be free()ed by the receiver.
.TP
.B curl_mvaprintf()
Like curl_maprintf() but takes a va_list pointer argument instead of a
variable amount of arguments.
.RE
To easily use all these cloned functions instead of the normal ones, #define
_MPRINTF_REPLACE before you include the <curl/mprintf.h> file. Then all the
normal names like printf, fprintf, sprintf etc will use the curl-functions
instead.
.SH RETURN VALUE
The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to
a newly allocated string, or NULL it it failed.
All other functions return the number of character they actually outputed.
.SH "SEE ALSO"
.BR printf "(3), " sprintf "(3), " fprintf "(3), " vprintf "(3) "

30
docs/curl_strequal.3 Normal file
View File

@@ -0,0 +1,30 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_strequal 3 "20 April 2001" "libcurl 7.7.2" "libcurl Manual"
.SH NAME
curl_strequal, curl_strnequal - case insensitive string comparisons
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "int curl_strequal(char *" str1 ", char *" str2 ");"
.sp
.BI "int curl_strenqual(char *" str1 ", char *" str2 ", size_t " len ");"
.SH DESCRIPTION
The
.B curl_strequal()
function compares the two strings \fIstr1\fP and \fIstr2\fP, ignoring the case
of the characters. It returns a non-zero (TRUE) integer if the strings are
identical.
.sp
The \fBcurl_strnequal()\fP function is similar, except it only compares the
first \fIlen\fP characters of \fIstr1\fP.
.sp
These functions are provided by libcurl to enable applications to compare
strings in a truly portable manner. There are no standard portable case
insensitive string comparison functions. These two works on all platforms.
.SH RETURN VALUE
A pointer to a zero terminated string.
.SH "SEE ALSO"
.BR strcmp "(3), " strcasecmp "(3)"

1
docs/curl_strnequal.3 Normal file
View File

@@ -0,0 +1 @@
.so curl_strequal.3

27
docs/curl_unescape.3 Normal file
View File

@@ -0,0 +1,27 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" Written by daniel@haxx.se
.\"
.TH curl_unescape 3 "22 March 2001" "libcurl 7.7" "libcurl Manual"
.SH NAME
curl_unescape - URL decodes the given string
.SH SYNOPSIS
.B #include <curl/curl.h>
.sp
.BI "char *curl_unescape( char *" url ", int "length " );"
.ad
.SH DESCRIPTION
This function will convert the given URL encoded input string to a "plain
string" and return that as a new allocated string. All input characters that
are URL encoded (%XX where XX is a two-digit hexadecimal number, or +) will be
converted to their plain text versions (up to a ? letter, no letters to the
right of a ? letter will be converted).
If the 'length' argument is set to 0, curl_unescape() will use strlen() on the
input 'url' string to find out the size.
You must free() the returned string when you're done with it.
.SH RETURN VALUE
A pointer to a zero terminated string or NULL if it failed.
.SH "SEE ALSO"
.I curl_escape(), RFC 2396

View File

@@ -4,10 +4,9 @@
AUTOMAKE_OPTIONS = foreign no-dependencies AUTOMAKE_OPTIONS = foreign no-dependencies
EXTRA_DIST = EXTRA_DIST = README curlgtk.c sepheaders.c simple.c postit.c \
README curlgtk.c sepheaders.c simple.c postit.c \ win32sockets.c persistant.c ftpget.c Makefile.example \
win32sockets.c persistant.c \ multithread.c
getpageinvar.php simpleget.php simplepost.php
all: all:
@echo "done" @echo "done"

View File

@@ -0,0 +1,41 @@
#############################################################################
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# $Id$
#
# What to call the final executable
TARGET = example
# Which object files that the executable consists of
OBJS= ftpget.o
# What compiler to use
CC = gcc
# Compiler flags, -g for debug, -c to make an object file
CFLAGS = -c -g
# This should point to a directory that holds libcurl, if it isn't
# in the system's standard lib dir
# We also set a -L to include the directory where we have the openssl
# libraries
LDFLAGS = -L/home/dast/lib -L/usr/local/ssl/lib
# We need -lcurl for the curl stuff
# We need -lsocket and -lnsl when on Solaris
# We need -lssl and -lcrypto when using libcurl with SSL support
# We need -ldl for dlopen() if that is in libdl
LIBS = -lcurl -lsocket -lnsl -lssl -lcrypto -dl
# Link the target with all objects and libraries
$(TARGET) : $(OBJS)
$(CC) $(LDFLAGS) $(LIBS) -o $(TARGET) $(OBJS)
# Compile the source files into object files
ftpget.o : ftpget.c
$(CC) $(CFLAGS) $<

View File

@@ -7,5 +7,12 @@ advantage of libcurl.
If you end up with other small but still useful example sources, please mail If you end up with other small but still useful example sources, please mail
them for submission in future packages and on the web site. them for submission in future packages and on the web site.
There are examples for different languages and environments. Browse around to The Makefile.example is an example makefile that could be used to build these
find those that fit you. examples. Just edit the file according to your system and requirements first.
Try the php/examples/ directory for PHP programming snippets!
*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
applications/experiments. Even if the examples in this directory use that
site as an example URL at some places, it doesn't mean that the URLs work or
that we expect you to actually torture our web site with your tests! Thanks.

44
docs/examples/ftpget.c Normal file
View File

@@ -0,0 +1,44 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
#include <stdio.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
/* to make this work under windows, use the win32-functions from the
win32socket.c file as well */
int main(int argc, char **argv)
{
CURL *curl;
CURLcode res;
FILE *ftpfile;
/* local file name to store the file as */
ftpfile = fopen("curl.tar.gz", "wb"); /* b is binary for win */
curl = curl_easy_init();
if(curl) {
/* Get curl 7.7 from sunet.se's FTP site: */
curl_easy_setopt(curl, CURLOPT_URL,
"ftp://ftp.sunet.se/pub/www/utilities/curl/curl-7.7.tar.gz");
curl_easy_setopt(curl, CURLOPT_FILE, ftpfile);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(ftpfile); /* close the local file */
return 0;
}

View File

@@ -0,0 +1,70 @@
/*****************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* $Id$
*/
/* A multi-threaded example that uses pthreads extensively to fetch
* X remote files at once */
#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h>
/* silly list of test-URLs */
char *urls[]= {
"http://curl.haxx.se/",
"ftp://cool.haxx.se/",
"http://www.contactor.se/",
"www.haxx.se"
};
void *pull_one_url(void *url)
{
CURL *curl;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
return NULL;
}
/*
int pthread_create(pthread_t *new_thread_ID,
const pthread_attr_t *attr,
void * (*start_func)(void *), void *arg);
*/
int main(int argc, char **argv)
{
pthread_t tid[4];
int i;
int error;
for(i=0; i< 4; i++) {
error = pthread_create(&tid[i],
NULL, /* default attributes please */
pull_one_url,
urls[i]);
if(0 != error)
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
else
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
}
/* now wait for all threads to terminate */
for(i=0; i< 4; i++) {
error = pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
}
return 0;
}

130
docs/libcurl.5 Normal file
View File

@@ -0,0 +1,130 @@
.\" You can view this file with:
.\" nroff -man [file]
.\" Written by Daniel Stenberg
.\"
.TH libcurl 5 "23 April 2001" "libcurl 7.7.2" "libcurl overview"
.SH NAME
libcurl \- client-side URL transfers
.SH DESCRIPTION
This is an overview on how to use libcurl in your c/c++ programs. There are
specific man pages for each function mentioned in here.
libcurl can also be used directly from within your Java, PHP, Perl, Ruby or
Tcl programs as well, look elsewhere for documentation on this!
When using libcurl's easy interface, you init your session and get a handle,
which you use as input to the following interface functions you use. Use
.B curl_easy_init()
to get the handle.
You continue by setting all the options you want in the upcoming transfer,
most important among them is the URL itself (you can't transfer anything
without a specified URL as you may have figured out yourself). You might want
to set some callbacks as well that will be called from the library when data
is available etc.
.B curl_easy_setopt()
is there for this.
When all is setup, you tell libcurl to perform the transfer using
.B curl_easy_perform().
It will then do the entire operation and won't return until it is done
(successfully or not).
After the transfer has been made, you can set new options and make another
transfer, or if you're done, cleanup the session by calling
.B curl_easy_cleanup().
If you want persistant connections, you don't cleanup immediately, but instead
run ahead and perform other transfers using the same handle. See the chapter
below for Persistant Connections.
There is also a series of other helpful functions to use. They are:
.RS
.TP 10
.B curl_version()
displays the libcurl version
.TP
.B curl_getdate()
converts a date string to time_t
.TP
.B curl_getenv()
portable environment variable reader
.TP
.B curl_easy_getinfo()
get information about a performed transfer
.TP
.B curl_formparse()
helps building a HTTP form POST
.TP
.B curl_formfree()
free a list built with curl_formparse()
.TP
.B curl_slist_append()
builds a linked list
.TP
.B curl_slist_free_all()
frees a whole curl_slist
.TP
.B curl_mprintf()
portable printf() functions
.TP
.B curl_streual()
portable case insensitive string comparisons
.RE
.SH "LINKING WITH LIBCURL"
Starting with 7.7.2 (on unix-like machines), there's a tool named curl-config
that gets installed with the rest of the curl stuff when 'make install' is
performed.
curl-config is added to make it easier for applications to link with libcurl
and developers to learn about libcurl and how to use it.
Run 'curl-config --libs' to get the (additional) linker options you need to
link with the particular version of libcurl you've installed.
For details, see the curl-config.1 man page.
.SH "LIBCURL SYMBOL NAMES"
All public functions in the libcurl interface are prefixed with 'curl_' (with
a lowercase c). You can find other functions in the library source code, but
other prefixes indicate the functions are private and may change without
further notice in the next release.
Only use documented functions and functionality!
.SH "PORTABILITY"
libcurl works
.B exactly
the same, on any of the platforms it compiles and builds on.
There's only one caution, and that is the win32 platform that may(*) require
you to init the winsock stuff before you use the libcurl functions. Details on
this are noted on the curl_easy_init() man page.
(*) = it appears as if users of the cygwin environment get this done
automatically.
.SH "THREADS"
Never ever call curl-functions simultaneously using the same handle from
several threads. libcurl is thread-safe and can be used in any number of
threads, but you must use separate curl handles if you want to use libcurl in
more than one thread simultaneously.
.SH "PERSISTANT CONNECTIONS"
With libcurl 7.7, persistant connections were added. Persistant connections
means that libcurl can re-use the same connection for several transfers, if
the conditions are right.
libcurl will *always* attempt to use persistant connections. Whenever you use
curl_easy_perform(), libcurl will attempt to use an existing connection to do
the transfer, and if none exists it'll open a new one that will be subject
for re-use on a possible following call to curl_easy_perform().
To allow libcurl to take full advantage of persistant connections, you should
do as many of your file transfers as possible using the same curl
handle. When you call curl_easy_cleanup(), all the possibly open connections
held by libcurl will be closed and forgotten.
Note that the options set with curl_easy_setopt() will be used in on every
repeat curl_easy_perform() call
.SH "COMPATIBILITY WITH OLDER LIBCURLS"
Repeated curl_easy_perform() calls on the same handle were not supported in
pre-7.7 versions, and caused confusion and undefined behaviour.

View File

@@ -76,12 +76,12 @@ typedef int (*curl_progress_callback)(void *clientp,
typedef size_t (*curl_write_callback)(char *buffer, typedef size_t (*curl_write_callback)(char *buffer,
size_t size, size_t size,
size_t nitems, size_t nitems,
FILE *outstream); void *outstream);
typedef size_t (*curl_read_callback)(char *buffer, typedef size_t (*curl_read_callback)(char *buffer,
size_t size, size_t size,
size_t nitems, size_t nitems,
FILE *instream); void *instream);
typedef int (*curl_passwd_callback)(void *clientp, typedef int (*curl_passwd_callback)(void *clientp,
char *prompt, char *prompt,
@@ -146,7 +146,8 @@ typedef enum {
CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */
CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */
CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */
CURLE_ALREADY_COMPLETE, /* 50 - file to dowload is already complete */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;
@@ -172,7 +173,7 @@ typedef enum {
typedef enum { typedef enum {
CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/ CINIT(NOTHING, LONG, 0), /********* the first one is unused ************/
/* This is the FILE * the regular output should be written to. */ /* This is the FILE * or void * the regular output should be written to. */
CINIT(FILE, OBJECTPOINT, 1), CINIT(FILE, OBJECTPOINT, 1),
/* The full URL to get/put */ /* The full URL to get/put */
@@ -275,7 +276,8 @@ typedef enum {
/* send linked-list of QUOTE commands */ /* send linked-list of QUOTE commands */
CINIT(QUOTE, OBJECTPOINT, 28), CINIT(QUOTE, OBJECTPOINT, 28),
/* send FILE * to store headers to */ /* send FILE * or void * to store headers to, if you use a callback it
is simply passed to the callback unmodified */
CINIT(WRITEHEADER, OBJECTPOINT, 29), CINIT(WRITEHEADER, OBJECTPOINT, 29),
#ifdef MULTIDOC #ifdef MULTIDOC
@@ -398,6 +400,42 @@ typedef enum {
/* This points to a linked list of telnet options */ /* This points to a linked list of telnet options */
CINIT(TELNETOPTIONS, OBJECTPOINT, 70), CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
/* Max amount of cached alive connections */
CINIT(MAXCONNECTS, LONG, 71),
/* What policy to use when closing connections when the cache is filled
up */
CINIT(CLOSEPOLICY, LONG, 72),
/* Callback to use when CURLCLOSEPOLICY_CALLBACK is set */
CINIT(CLOSEFUNCTION, FUNCTIONPOINT, 73),
/* Set to explicitly use a new connection for the upcoming transfer.
Do not use this unless you're absolutely sure of this, as it makes the
operation slower and is less friendly for the network. */
CINIT(FRESH_CONNECT, LONG, 74),
/* Set to explicitly forbid the upcoming transfer's connection to be re-used
when done. Do not use this unless you're absolutely sure of this, as it
makes the operation slower and is less friendly for the network. */
CINIT(FORBID_REUSE, LONG, 75),
/* Set to a file name that contains random data for libcurl to use to
seed the random engine when doing SSL connects. */
CINIT(RANDOM_FILE, OBJECTPOINT, 76),
/* Set to the Entropy Gathering Daemon socket pathname */
CINIT(EGDSOCKET, OBJECTPOINT, 77),
/* Time-out connect operations after this amount of seconds, if connects
are OK within this time, then fine... This only aborts the connect
phase. [Only works on unix-style/SIGALRM operating systems] */
CINIT(CONNECTTIMEOUT, LONG, 78),
/* Function that will be called to store headers (instead of fwrite). The
* parameters will use fwrite() syntax, make sure to follow them. */
CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
CURLOPT_LASTENTRY /* the last unusued */ CURLOPT_LASTENTRY /* the last unusued */
} CURLoption; } CURLoption;
@@ -423,10 +461,10 @@ typedef enum {
NOTE: they return TRUE if the strings match *case insensitively*. NOTE: they return TRUE if the strings match *case insensitively*.
*/ */
extern int (Curl_strequal)(const char *s1, const char *s2); extern int (curl_strequal)(const char *s1, const char *s2);
extern int (Curl_strnequal)(const char *s1, const char *s2, size_t n); extern int (curl_strnequal)(const char *s1, const char *s2, size_t n);
#define strequal(a,b) Curl_strequal(a,b) #define strequal(a,b) curl_strequal(a,b)
#define strnequal(a,b,c) Curl_strnequal(a,b,c) #define strnequal(a,b,c) curl_strnequal(a,b,c)
/* external form function */ /* external form function */
int curl_formparse(char *string, int curl_formparse(char *string,
@@ -443,9 +481,14 @@ char *curl_getenv(char *variable);
/* Returns a static ascii string of the libcurl version. */ /* Returns a static ascii string of the libcurl version. */
char *curl_version(void); char *curl_version(void);
/* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */
char *curl_escape(char *string, int length);
char *curl_unescape(char *string, int length);
/* This is the version number */ /* This is the version number */
#define LIBCURL_VERSION "7.7-beta1" #define LIBCURL_VERSION "7.7.3"
#define LIBCURL_VERSION_NUM 0x070700 #define LIBCURL_VERSION_NUM 0x070703
/* linked-list structure for the CURLOPT_QUOTE option (and other) */ /* linked-list structure for the CURLOPT_QUOTE option (and other) */
struct curl_slist { struct curl_slist {
@@ -502,21 +545,6 @@ typedef enum {
before it can be included! */ before it can be included! */
#include <curl/easy.h> /* nothing in curl is fun without the easy stuff */ #include <curl/easy.h> /* nothing in curl is fun without the easy stuff */
/*
* NAME curl_getinfo()
*
* DESCRIPTION
*
* Request internal information from the curl session with this function.
* The third argument MUST be a pointer to a long or a pointer to a char *.
* The data pointed to will be filled in accordingly and can be relied upon
* only if the function returns CURLE_OK.
* This function is intended to get used *AFTER* a performed transfer, all
* results are undefined before the transfer is completed.
*/
CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...);
typedef enum { typedef enum {
CURLCLOSEPOLICY_NONE, /* first, never use this */ CURLCLOSEPOLICY_NONE, /* first, never use this */

134
java/CurlGlue.java Normal file
View File

@@ -0,0 +1,134 @@
/**
* The curl class is a JNI wrapper for libcurl. Please bear with me, I'm no
* true java dude (yet). Improve what you think is bad and send me the
* updates!
* daniel@haxx.se
*
* This is meant as a raw, crude and low-level interface to libcurl. If you
* want fancy stuff, build upon this.
*/
public class CurlGlue
{
// start of imported generated list, make a new list with
// define2java.pl on demand
public static final int CURLOPT_NOTHING = 0;
public static final int CURLOPT_FILE = 10001;
public static final int CURLOPT_URL = 10002;
public static final int CURLOPT_PORT = 3;
public static final int CURLOPT_PROXY = 10004;
public static final int CURLOPT_USERPWD = 10005;
public static final int CURLOPT_PROXYUSERPWD = 10006;
public static final int CURLOPT_RANGE = 10007;
public static final int CURLOPT_INFILE = 10009;
public static final int CURLOPT_ERRORBUFFER = 10010;
public static final int CURLOPT_WRITEFUNCTION = 20011;
public static final int CURLOPT_READFUNCTION = 20012;
public static final int CURLOPT_TIMEOUT = 13;
public static final int CURLOPT_INFILESIZE = 14;
public static final int CURLOPT_POSTFIELDS = 10015;
public static final int CURLOPT_REFERER = 10016;
public static final int CURLOPT_FTPPORT = 10017;
public static final int CURLOPT_USERAGENT = 10018;
public static final int CURLOPT_LOW_SPEED_LIMIT = 19;
public static final int CURLOPT_LOW_SPEED_TIME = 20;
public static final int CURLOPT_RESUME_FROM = 21;
public static final int CURLOPT_COOKIE = 10022;
public static final int CURLOPT_HTTPHEADER = 10023;
public static final int CURLOPT_HTTPPOST = 10024;
public static final int CURLOPT_SSLCERT = 10025;
public static final int CURLOPT_SSLCERTPASSWD = 10026;
public static final int CURLOPT_CRLF = 27;
public static final int CURLOPT_QUOTE = 10028;
public static final int CURLOPT_WRITEHEADER = 10029;
public static final int CURLOPT_COOKIEFILE = 10031;
public static final int CURLOPT_SSLVERSION = 32;
public static final int CURLOPT_TIMECONDITION = 33;
public static final int CURLOPT_TIMEVALUE = 34;
public static final int CURLOPT_HTTPREQUEST = 10035;
public static final int CURLOPT_CUSTOMREQUEST = 10036;
public static final int CURLOPT_STDERR = 10037;
public static final int CURLOPT_POSTQUOTE = 10039;
public static final int CURLOPT_WRITEINFO = 10040;
public static final int CURLOPT_VERBOSE = 41;
public static final int CURLOPT_HEADER = 42;
public static final int CURLOPT_NOPROGRESS = 43;
public static final int CURLOPT_NOBODY = 44;
public static final int CURLOPT_FAILONERROR = 45;
public static final int CURLOPT_UPLOAD = 46;
public static final int CURLOPT_POST = 47;
public static final int CURLOPT_FTPLISTONLY = 48;
public static final int CURLOPT_FTPAPPEND = 50;
public static final int CURLOPT_NETRC = 51;
public static final int CURLOPT_FOLLOWLOCATION = 52;
public static final int CURLOPT_FTPASCII = 53;
public static final int CURLOPT_TRANSFERTEXT = 53;
public static final int CURLOPT_PUT = 54;
public static final int CURLOPT_MUTE = 55;
public static final int CURLOPT_PROGRESSFUNCTION = 20056;
public static final int CURLOPT_PROGRESSDATA = 10057;
public static final int CURLOPT_AUTOREFERER = 58;
public static final int CURLOPT_PROXYPORT = 59;
public static final int CURLOPT_POSTFIELDSIZE = 60;
public static final int CURLOPT_HTTPPROXYTUNNEL = 61;
public static final int CURLOPT_INTERFACE = 10062;
public static final int CURLOPT_KRB4LEVEL = 10063;
public static final int CURLOPT_SSL_VERIFYPEER = 64;
public static final int CURLOPT_CAINFO = 10065;
public static final int CURLOPT_PASSWDFUNCTION = 20066;
public static final int CURLOPT_PASSWDDATA = 10067;
public static final int CURLOPT_MAXREDIRS = 68;
public static final int CURLOPT_FILETIME = 10069;
public static final int CURLOPT_TELNETOPTIONS = 10070;
public static final int CURLOPT_MAXCONNECTS = 71;
public static final int CURLOPT_CLOSEPOLICY = 72;
public static final int CURLOPT_CLOSEFUNCTION = 20073;
public static final int CURLOPT_FRESH_CONNECT = 74;
public static final int CURLOPT_FORBID_REUSE = 75;
public static final int CURLOPT_RANDOM_FILE = 10076;
public static final int CURLOPT_EGDSOCKET = 10077;
public static final int CURLOPT_CONNECTTIMEOUT = 78;
public static final int CURLOPT_HEADERFUNCTION = 20079;
// end of generated list
public CurlGlue() {
javacurl_handle = jni_init();
}
public void finalize() {
jni_cleanup(javacurl_handle);
}
private int javacurl_handle;
/* constructor and destructor for the libcurl handle */
private native int jni_init();
private native void jni_cleanup(int javacurl_handle);
private native synchronized int jni_perform(int javacurl_handle);
// Instead of varargs, we have different functions for each
// kind of type setopt() can take
private native int jni_setopt(int libcurl, int option, String value);
private native int jni_setopt(int libcurl, int option, int value);
private native int jni_setopt(int libcurl, int option, CurlWrite value);
public native int getinfo();
public int perform() {
return jni_perform(javacurl_handle);
}
public int setopt(int option, int value) {
return jni_setopt(javacurl_handle, option, value);
}
public int setopt(int option, String value) {
return jni_setopt(javacurl_handle, option, value);
}
public int setopt(int option, CurlWrite value) {
return jni_setopt(javacurl_handle, option, value);
}
static {
System.loadLibrary("javacurl");
}
}

9
java/CurlWrite.java Normal file
View File

@@ -0,0 +1,9 @@
public interface CurlWrite
{
/**
* handleString gets called by libcurl on each chunk of data
* we receive from the remote server
*/
public int handleString(byte s[]);
}

35
java/Makefile Normal file
View File

@@ -0,0 +1,35 @@
TARGET = libjavacurl.so
OBJS = javacurl.o
CC = gcc
CFLAGS = -c
CPPFLAGS = -I/usr/j2se/include -I/usr/local/include -I/usr/j2se/include/solaris
# Linux might use -shared -Wl,-soname,libnative.so instead of -G
LDFLAGS = -G -lcurl -ldl -L/usr/local/ssl/lib -lssl -lcrypto
all: CurlGlue.h CurlGlue.class javacurl.o $(TARGET) test.class
test:
java test
javacurl.o: javacurl.c CurlGlue.h
$(CC) $(CPPFLAGS) $(CFLAGS) $<
CurlGlue.h: CurlGlue.java CurlGlue.class
javah CurlGlue
touch CurlGlue.h
test.class: CurlGlue.class javacurl.o
javac test.java
CurlGlue.class: CurlGlue.java
javac $<
$(TARGET): $(OBJS)
$(CC) -o $(TARGET) $(LDFLAGS) $(OBJS)
clean:
rm -f javacurl.o CurlGlue.h CurlGlue.class

13
java/README Normal file
View File

@@ -0,0 +1,13 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Java Interface
This is very much work in progress and it does not work.
The interface is not set yet, bring your suggestions!
Feel free to grab the source files in here and help out!

22
java/define2java.pl Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/perl
open(GCC, "gcc -E ../include/curl/curl.h|");
while(<GCC>) {
if($_ =~ /(CURLOPT_(.*)) += (.*)/) {
$var= $1;
$expr = $3;
$f=$3;
if($expr =~ / *(\d+) *\+ *(\d+)/) {
$expr = $1+$2;
}
# nah, keep the CURL prefix to make them look like other
# languages' defines
# $var =~ s/^CURL//g;
print " public static final int $var = $expr;\n";
}
}
close(GCC);

196
java/javacurl.c Normal file
View File

@@ -0,0 +1,196 @@
#include <curl/curl.h> /* libcurl header */
#include "CurlGlue.h" /* the JNI-generated glue header file */
/*
* This is a private struct allocated for every 'CurlGlue' object.
*/
struct javacurl {
void *libcurl;
void *whatever;
struct writecallback {
jmethodID mid;
JNIEnv *java;
jclass cls; /* global reference */
jobject object;
} write;
};
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1init(JNIEnv *java,
jobject myself)
{
void *libhandle;
struct javacurl *jcurl=NULL;
libhandle = curl_easy_init();
if(libhandle) {
jcurl=(struct javacurl *)malloc(sizeof(struct javacurl));
if(jcurl) {
memset(jcurl, 0, sizeof(struct javacurl));
jcurl->libcurl = libhandle;
}
else {
curl_easy_cleanup(libhandle);
return (jint)0;
}
}
return (jint) jcurl; /* nasty typecast */
}
JNIEXPORT void JNICALL Java_CurlGlue_jni_1cleanup(JNIEnv *java,
jobject myself,
jint jcurl)
{
struct javacurl *curl = (struct javacurl*)jcurl;
if(curl->write.cls) {
/* a global reference we must delete */
(*java)->DeleteGlobalRef(java, curl->write.cls);
(*java)->DeleteGlobalRef(java, curl->write.object);
}
curl_easy_cleanup(curl->libcurl); /* cleanup libcurl stuff */
free((void *)curl); /* free the struct too */
}
/*
* setopt() int + string
*/
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILjava_lang_String_2
(JNIEnv *java, jobject myself, jint jcurl, jint option, jstring value)
{
/* get the actual string C-style */
const char *str = (*java)->GetStringUTFChars(java, value, 0);
void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
puts("setopt int + string");
return (jint)curl_easy_setopt(handle, (CURLoption)option, str);
}
/*
* setopt() int + int
*/
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__III
(JNIEnv *java, jobject myself, jint jcurl, jint option, jint value)
{
void *handle = (void *)((struct javacurl*)jcurl)->libcurl;
CURLoption opt = (CURLoption)option;
puts("setopt int + int");
switch(opt) {
case CURLOPT_FILE:
/* silently ignored, we don't need user-specified callback data when
we have an object, and besides the CURLOPT_FILE is not exported
to the java interface */
return 0;
}
return (jint)curl_easy_setopt(handle, (CURLoption)option, value);
}
static int javacurl_write_callback(void *ptr,
size_t size,
size_t nmemb,
FILE *stream)
{
struct javacurl *curl = (struct javacurl *)stream;
size_t realsize = size * nmemb;
JNIEnv *java = curl->write.java;
jbyteArray jb=NULL;
int ret=0;
fprintf(stderr, "%d bytes data received in callback:\n"
"ptr=%p, java=%p cls=%p\n",
realsize, curl, java, curl->write.cls);
jb=(*java)->NewByteArray(java, realsize);
(*java)->SetByteArrayRegion(java, jb, 0,
realsize, (jbyte *)ptr);
fprintf(stderr, "created byte-array\n");
ret = (*java)->CallIntMethod(java,
curl->write.object,
curl->write.mid,
jb);
fprintf(stderr, "java-method returned %d\n", ret);
return realsize;
}
/*
* setopt() int + object
*/
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1setopt__IILCurlWrite_2
(JNIEnv *java, jobject myself, jint jcurl, jint option, jobject object)
{
jclass cls_local = (*java)->GetObjectClass(java, object);
jmethodID mid;
struct javacurl *curl = (struct javacurl *)jcurl;
jclass cls;
jobject obj_global;
switch(option) {
case CURLOPT_WRITEFUNCTION:
/* this makes a reference that'll be alive until we kill it! */
cls = (*java)->NewGlobalRef(java, cls_local);
printf("setopt int + object, option = %d cls= %p\n",
option, cls);
if(!cls) {
puts("couldn't make local reference global");
return 0;
}
/* this is the write callback */
mid = (*java)->GetMethodID(java, cls, "handleString", "([B)I");
if(!mid) {
puts("no callback method found");
return 0;
}
obj_global = (*java)->NewGlobalRef(java, object);
curl->write.mid = mid;
curl->write.cls = cls;
curl->write.object = obj_global;
/*curl->write.java = java; stored on perform */
fprintf(stderr, "setopt write callback and write file pointer %p, java = %p\n",
curl, java);
curl_easy_setopt(curl->libcurl, CURLOPT_WRITEFUNCTION,
javacurl_write_callback);
curl_easy_setopt(curl->libcurl, CURLOPT_FILE,
curl);
break;
}
return 0;
}
JNIEXPORT jint JNICALL Java_CurlGlue_getinfo
(JNIEnv *java, jobject value)
{
return 0;
}
JNIEXPORT jint JNICALL Java_CurlGlue_jni_1perform
(JNIEnv *java, jobject myself, jint jcurl)
{
struct javacurl *curl=(struct javacurl*)jcurl;
curl->write.java = java;
return (jint)curl_easy_perform(curl->libcurl);
}

27
java/test.java Normal file
View File

@@ -0,0 +1,27 @@
import CurlGlue;
import CurlWrite;
class test implements CurlWrite {
public int handleString(byte s[])
{
/* output everything */
System.out.println("IIIIIIIIIII -------------- OOOOOOOOOOOOOOOOOOO");
try {
System.out.write(s);
}
catch (java.io.IOException moo) {
// nothing
}
return 0;
}
public static void main(String[] args)
{
CurlGlue cg = new CurlGlue();
test cw = new test();
cg.setopt(CurlGlue.CURLOPT_URL, "http://www.contactor.se/");
cg.setopt(CurlGlue.CURLOPT_WRITEFUNCTION, cw);
cg.perform();
}
}

View File

@@ -16,7 +16,7 @@ lib_LTLIBRARIES = libcurl.la
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
libcurl_la_LDFLAGS = -version-info 1:0:0 libcurl_la_LDFLAGS = -version-info 2:0:0
# This flag accepts an argument of the form current[:revision[:age]]. So, # This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
# 1. # 1.

View File

@@ -14,7 +14,7 @@ RM = del
LIB = tlib LIB = tlib
TOPDIR = .. TOPDIR = ..
CURNTDIR = . CURNTDIR = .
CXXFLAGS = -5 -O2 -w-aus -w-ccc -w-csu -w-par -w-pia -w-rch -w-inl -w-ngu -w-pro CXXFLAGS = -5 -O2 -w-aus -w-ccc -w-csu -w-par -w-pia -w-rch -w-inl -w-ngu -w-pro -tWM
DEFINES = -DLIBCURL_BIGENDIAN=0 -DNDEBUG -DWIN32 -DCONSOLE -DMBCS DEFINES = -DLIBCURL_BIGENDIAN=0 -DNDEBUG -DWIN32 -DCONSOLE -DMBCS
INCDIRS = -I$(CURNTDIR);$(TOPDIR)/include/ INCDIRS = -I$(CURNTDIR);$(TOPDIR)/include/
@@ -34,6 +34,7 @@ SOURCES = \
formdata.c \ formdata.c \
ftp.c \ ftp.c \
http.c \ http.c \
http_chunks.c \
ldap.c \ ldap.c \
dict.c \ dict.c \
telnet.c \ telnet.c \
@@ -64,11 +65,11 @@ OBJECTS = $(SOURCES:.c=.obj)
all: $(LIBCURLLIB) all: $(LIBCURLLIB)
clean: clean:
$(RM) $(LIBCURLLIB) -$(RM) $(LIBCURLLIB)
$(RM) *.obj -$(RM) *.obj
$(LIBCURLLIB): $(LINKLIB) $(OBJECTS) Makefile.b32.resp $(LIBCURLLIB): $(LINKLIB) $(OBJECTS) Makefile.b32.resp
$(RM) $(LIBCURLLIB) -$(RM) $(LIBCURLLIB)
$(LIB) $(LIBCURLLIB) @Makefile.b32.resp $(LIB) $(LIBCURLLIB) @Makefile.b32.resp

View File

@@ -5,6 +5,7 @@
+formdata.obj & +formdata.obj &
+ftp.obj & +ftp.obj &
+http.obj & +http.obj &
+http_chunks.obj &
+ldap.obj & +ldap.obj &
+dict.obj & +dict.obj &
+telnet.obj & +telnet.obj &

View File

@@ -33,13 +33,13 @@ libcurl_a_SOURCES = arpa_telnet.h file.c getpass.h netrc.h timeval.c base64.c \
urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \ urldata.h transfer.c getdate.h ldap.c ssluse.c version.c transfer.h getenv.c \
ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \ ldap.h ssluse.h escape.c getenv.h mprintf.c telnet.c escape.h getpass.c netrc.c \
telnet.h getinfo.c strequal.c strequal.h easy.c security.h \ telnet.h getinfo.c strequal.c strequal.h easy.c security.h \
security.c krb4.c security.c krb4.h krb4.c memdebug.h memdebug.c inet_ntoa_r.h http_chunks.h http_chunks.c
libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \ libcurl_a_OBJECTS = file.o timeval.o base64.o hostip.o progress.o \
formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \ formdata.o cookie.o http.o sendf.o ftp.o url.o dict.o if2ip.o \
speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.o \ speedcheck.o getdate.o transfer.o ldap.o ssluse.o version.o \
getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \ getenv.o escape.o mprintf.o telnet.o getpass.o netrc.o getinfo.o \
strequal.o easy.o security.o krb4.o strequal.o easy.o security.o krb4.o memdebug.o http_chunks.o
LIBRARIES = $(libcurl_a_LIBRARIES) LIBRARIES = $(libcurl_a_LIBRARIES)
SOURCES = $(libcurl_a_SOURCES) SOURCES = $(libcurl_a_SOURCES)

View File

@@ -5,10 +5,11 @@
## ##
## Comments to: Troy Engel <tengel@sonic.net> ## Comments to: Troy Engel <tengel@sonic.net>
## Updated by: Craig Davison <cd@securityfocus.com> ## Updated by: Craig Davison <cd@securityfocus.com>
## Updated by: SM <sm@technologist.com>
PROGRAM_NAME = libcurl.lib PROGRAM_NAME = libcurl.lib
PROGRAM_NAME_DEBUG = libcurld.lib PROGRAM_NAME_DEBUG = libcurld.lib
OPENSSL_PATH = ../../openssl-0.9.6 #OPENSSL_PATH = ../../openssl-0.9.6a
######################################################## ########################################################
## Nothing more to do below this line! ## Nothing more to do below this line!
@@ -22,7 +23,7 @@ CCD = cl.exe /MDd /Gm /ZI /Od /D "_DEBUG" /GZ
LINKD = link.exe -lib /out:$(PROGRAM_NAME_DEBUG) LINKD = link.exe -lib /out:$(PROGRAM_NAME_DEBUG)
## SSL Release ## SSL Release
CCRS = cl.exe /MD /O2 /D "NDEBUG" /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/include" /I "$(OPENSSL_PATH)/include/openssl" CCRS = cl.exe /MD /O2 /D "NDEBUG" /D "USE_SSLEAY" /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
LINKRS = link.exe -lib /out:$(PROGRAM_NAME) /LIBPATH:$(OPENSSL_PATH)/out32dll LINKRS = link.exe -lib /out:$(PROGRAM_NAME) /LIBPATH:$(OPENSSL_PATH)/out32dll
CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS" CFLAGS = /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /D "_LIB" /YX /FD /c /D "MSDOS"
@@ -38,6 +39,7 @@ RELEASE_OBJS= \
formdatar.obj \ formdatar.obj \
ftpr.obj \ ftpr.obj \
httpr.obj \ httpr.obj \
http_chunksr.obj \
ldapr.obj \ ldapr.obj \
dictr.obj \ dictr.obj \
telnetr.obj \ telnetr.obj \
@@ -68,6 +70,7 @@ DEBUG_OBJS= \
formdatad.obj \ formdatad.obj \
ftpd.obj \ ftpd.obj \
httpd.obj \ httpd.obj \
http_chunksd.obj \
ldapd.obj \ ldapd.obj \
dictd.obj \ dictd.obj \
telnetd.obj \ telnetd.obj \
@@ -98,6 +101,7 @@ RELEASE_SSL_OBJS= \
formdatars.obj \ formdatars.obj \
ftprs.obj \ ftprs.obj \
httprs.obj \ httprs.obj \
http_chunksrs.obj \
ldaprs.obj \ ldaprs.obj \
dictrs.obj \ dictrs.obj \
telnetrs.obj \ telnetrs.obj \
@@ -128,6 +132,7 @@ LINK_OBJS= \
formdata.obj \ formdata.obj \
ftp.obj \ ftp.obj \
http.obj \ http.obj \
http_chunks.obj \
ldap.obj \ ldap.obj \
dict.obj \ dict.obj \
telnet.obj \ telnet.obj \
@@ -176,6 +181,8 @@ ftpr.obj: ftp.c
$(CCR) $(CFLAGS) ftp.c $(CCR) $(CFLAGS) ftp.c
httpr.obj: http.c httpr.obj: http.c
$(CCR) $(CFLAGS) http.c $(CCR) $(CFLAGS) http.c
http_chunksr.obj: http_chunks.c
$(CCR) $(CFLAGS) http_chunks.c
ldapr.obj: ldap.c ldapr.obj: ldap.c
$(CCR) $(CFLAGS) ldap.c $(CCR) $(CFLAGS) ldap.c
dictr.obj: dict.c dictr.obj: dict.c
@@ -234,6 +241,8 @@ ftpd.obj: ftp.c
$(CCD) $(CFLAGS) ftp.c $(CCD) $(CFLAGS) ftp.c
httpd.obj: http.c httpd.obj: http.c
$(CCD) $(CFLAGS) http.c $(CCD) $(CFLAGS) http.c
http_chunksd.obj: http_chunks.c
$(CCD) $(CFLAGS) http_chunks.c
ldapd.obj: ldap.c ldapd.obj: ldap.c
$(CCD) $(CFLAGS) ldap.c $(CCD) $(CFLAGS) ldap.c
dictd.obj: dict.c dictd.obj: dict.c
@@ -292,7 +301,9 @@ formdatars.obj: formdata.c
ftprs.obj: ftp.c ftprs.obj: ftp.c
$(CCRS) $(CFLAGS) ftp.c $(CCRS) $(CFLAGS) ftp.c
httprs.obj: http.c httprs.obj: http.c
$(CCRS) $(CFLAGS) http.c $(CCR) $(CFLAGS) http.c
http_chunksrs.obj: http_chunks.c
$(CCRS) $(CFLAGS) http_chunks.c
ldaprs.obj: ldap.c ldaprs.obj: ldap.c
$(CCRS) $(CFLAGS) ldap.c $(CCRS) $(CFLAGS) ldap.c
dictrs.obj: dict.c dictrs.obj: dict.c

View File

@@ -1,367 +1,368 @@
# Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="curllib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=curllib - Win32 Debug CFG=curllib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "curllib.mak". !MESSAGE NMAKE /f "curllib.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug" !MESSAGE NMAKE /f "curllib.mak" CFG="curllib - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "curllib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "curllib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "" # PROP Scc_ProjName ""
# PROP Scc_LocalPath "" # PROP Scc_LocalPath ""
CPP=cl.exe CPP=cl.exe
MTL=midl.exe MTL=midl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "curllib - Win32 Release" !IF "$(CFG)" == "curllib - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release" # PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release" # PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\jdk1.3.0_01\include" /I "C:\jdk1.3.0_01\include\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /machine:I386 /out:"Release/curl.dll" # ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /machine:I386 /out:"Release/curl.dll"
!ELSEIF "$(CFG)" == "curllib - Win32 Debug" !ELSEIF "$(CFG)" == "curllib - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug" # PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug" # PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug" # PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug" # PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\jdk1.3.0_01\include" /I "C:\jdk1.3.0_01\include\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CURLLIB_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/curl.dll" /pdbtype:sept # ADD LINK32 kernel32.lib wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/curl.dll" /pdbtype:sept
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
!ENDIF
# Begin Target
# Begin Target
# Name "curllib - Win32 Release"
# Name "curllib - Win32 Debug" # Name "curllib - Win32 Release"
# Begin Group "Source Files" # Name "curllib - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\base64.c
# End Source File SOURCE=.\base64.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\cookie.c
# End Source File SOURCE=.\cookie.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\dict.c
# End Source File SOURCE=.\dict.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\dllinit.c
# End Source File SOURCE=.\dllinit.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\easy.c
# End Source File SOURCE=.\easy.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\easyswig.c
# End Source File SOURCE=.\escape.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\easyswig_wrap.c
# End Source File SOURCE=.\file.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\escape.c
# End Source File SOURCE=.\formdata.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\file.c
# End Source File SOURCE=.\ftp.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\formdata.c
# End Source File SOURCE=.\getdate.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ftp.c
# End Source File SOURCE=.\getenv.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getdate.c
# End Source File SOURCE=.\getinfo.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getenv.c
# End Source File SOURCE=.\getpass.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getinfo.c
# End Source File SOURCE=.\hostip.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getpass.c
# End Source File SOURCE=.\http.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\hostip.c
# End Source File SOURCE=.\http_chunks.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\http.c
# End Source File SOURCE=.\if2ip.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\if2ip.c
# End Source File SOURCE=.\krb4.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\krb4.c
# End Source File SOURCE=.\ldap.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ldap.c
# End Source File SOURCE=.\libcurl.def
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\libcurl.def
# End Source File SOURCE=.\memdebug.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\memdebug.c
# End Source File SOURCE=.\mprintf.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\mprintf.c
# End Source File SOURCE=.\netrc.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\netrc.c
# End Source File SOURCE=.\progress.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\progress.c
# End Source File SOURCE=.\security.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\security.c
# End Source File SOURCE=.\sendf.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\sendf.c
# End Source File SOURCE=.\speedcheck.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\speedcheck.c
# End Source File SOURCE=.\ssluse.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ssluse.c
# End Source File SOURCE=.\strequal.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\strequal.c
# End Source File SOURCE=.\telnet.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\telnet.c
# End Source File SOURCE=.\timeval.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\timeval.c
# End Source File SOURCE=.\transfer.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\transfer.c
# End Source File SOURCE=.\url.c
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\url.c
# End Source File SOURCE=.\version.c
# Begin Source File # End Source File
# End Group
SOURCE=.\version.c # Begin Group "Header Files"
# End Source File
# End Group # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Group "Header Files" # Begin Source File
# PROP Default_Filter "h;hpp;hxx;hm;inl" SOURCE=.\arpa_telnet.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\arpa_telnet.h
# End Source File SOURCE=.\base64.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\base64.h
# End Source File SOURCE=.\cookie.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\cookie.h
# End Source File SOURCE=.\dict.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\dict.h
# End Source File SOURCE=.\escape.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\escape.h
# End Source File SOURCE=.\file.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\file.h
# End Source File SOURCE=.\formdata.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\formdata.h
# End Source File SOURCE=.\ftp.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ftp.h
# End Source File SOURCE=.\getdate.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getdate.h
# End Source File SOURCE=.\getenv.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getenv.h
# End Source File SOURCE=.\getpass.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\getpass.h
# End Source File SOURCE=.\hostip.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\hostip.h
# End Source File SOURCE=.\http.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\http.h
# End Source File SOURCE=.\http_chunks.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\if2ip.h
# End Source File SOURCE=.\if2ip.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\inet_ntoa_r.h
# End Source File SOURCE=.\inet_ntoa_r.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\krb4.h
# End Source File SOURCE=.\krb4.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ldap.h
# End Source File SOURCE=.\ldap.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\memdebug.h
# End Source File SOURCE=.\memdebug.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\netrc.h
# End Source File SOURCE=.\netrc.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\progress.h
# End Source File SOURCE=.\progress.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\security.h
# End Source File SOURCE=.\security.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\sendf.h
# End Source File SOURCE=.\sendf.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\setup.h
# End Source File SOURCE=.\setup.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\speedcheck.h
# End Source File SOURCE=.\speedcheck.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\ssluse.h
# End Source File SOURCE=.\ssluse.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\strequal.h
# End Source File SOURCE=.\strequal.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\telnet.h
# End Source File SOURCE=.\telnet.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\timeval.h
# End Source File SOURCE=.\timeval.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\transfer.h
# End Source File SOURCE=.\transfer.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\url.h
# End Source File SOURCE=.\url.h
# Begin Source File # End Source File
# Begin Source File
SOURCE=.\urldata.h
# End Source File SOURCE=.\urldata.h
# End Group # End Source File
# Begin Group "Resource Files" # End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Target # End Group
# End Project # End Target
# End Project

View File

@@ -1,29 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00 Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
############################################################################### ###############################################################################
Project: "curllib"=".\curllib.dsp" - Package Owner=<4> Project: "curllib"=".\curllib.dsp" - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<4> Package=<4>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################
Global: Global:
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<3> Package=<3>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################

View File

@@ -100,7 +100,7 @@ CURLcode Curl_dict(struct connectdata *conn)
char *path = conn->path; char *path = conn->path;
long *bytecount = &conn->bytecount; long *bytecount = &conn->bytecount;
if(data->bits.user_passwd) { if(conn->bits.user_passwd) {
/* AUTH is missing */ /* AUTH is missing */
} }

View File

@@ -83,15 +83,11 @@ CURL *curl_easy_init(void)
CURLcode res; CURLcode res;
struct UrlData *data; struct UrlData *data;
if(curl_init())
return NULL;
/* We use curl_open() with undefined URL so far */ /* We use curl_open() with undefined URL so far */
res = curl_open((CURL **)&data, NULL); res = Curl_open((CURL **)&data, NULL);
if(res != CURLE_OK) if(res != CURLE_OK)
return NULL; return NULL;
data->interf = CURLI_EASY; /* mark it as an easy one */
/* SAC */ /* SAC */
data->device = NULL; data->device = NULL;
@@ -119,16 +115,16 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
if(tag < CURLOPTTYPE_OBJECTPOINT) { if(tag < CURLOPTTYPE_OBJECTPOINT) {
/* This is a LONG type */ /* This is a LONG type */
param_long = va_arg(arg, long); param_long = va_arg(arg, long);
curl_setopt(data, tag, param_long); Curl_setopt(data, tag, param_long);
} }
else if(tag < CURLOPTTYPE_FUNCTIONPOINT) { else if(tag < CURLOPTTYPE_FUNCTIONPOINT) {
/* This is a object pointer type */ /* This is a object pointer type */
param_obj = va_arg(arg, void *); param_obj = va_arg(arg, void *);
curl_setopt(data, tag, param_obj); Curl_setopt(data, tag, param_obj);
} }
else { else {
param_func = va_arg(arg, func_T ); param_func = va_arg(arg, func_T );
curl_setopt(data, tag, param_func); Curl_setopt(data, tag, param_func);
} }
va_end(arg); va_end(arg);
@@ -137,13 +133,12 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
CURLcode curl_easy_perform(CURL *curl) CURLcode curl_easy_perform(CURL *curl)
{ {
return curl_transfer(curl); return Curl_perform(curl);
} }
void curl_easy_cleanup(CURL *curl) void curl_easy_cleanup(CURL *curl)
{ {
curl_close(curl); Curl_close(curl);
curl_free();
} }
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...) CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
@@ -153,5 +148,5 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
va_start(arg, info); va_start(arg, info);
paramp = va_arg(arg, void *); paramp = va_arg(arg, void *);
return curl_getinfo(curl, info, paramp); return Curl_getinfo(curl, info, paramp);
} }

View File

@@ -25,6 +25,7 @@
* allocated string or NULL if an error occurred. */ * allocated string or NULL if an error occurred. */
#include "setup.h" #include "setup.h"
#include <ctype.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <stdio.h> #include <stdio.h>
@@ -36,74 +37,89 @@
#include "memdebug.h" #include "memdebug.h"
#endif #endif
char *curl_escape(char *string) char *curl_escape(char *string, int length)
{ {
int alloc=strlen(string)+1; int alloc = (length?length:strlen(string))+1;
char *ns = malloc(alloc); char *ns = malloc(alloc);
unsigned char in; unsigned char in;
int newlen = alloc; int newlen = alloc;
int index=0; int index=0;
while(*string) { length = alloc-1;
in = *string; while(length--) {
if(' ' == in) in = *string;
ns[index++] = '+'; if(' ' == in)
else if(!(in >= 'a' && in <= 'z') && ns[index++] = '+';
!(in >= 'A' && in <= 'Z') && else if(!(in >= 'a' && in <= 'z') &&
!(in >= '0' && in <= '9')) { !(in >= 'A' && in <= 'Z') &&
/* encode it */ !(in >= '0' && in <= '9')) {
newlen += 2; /* the size grows with two, since this'll become a %XX */ /* encode it */
if(newlen > alloc) { if(('%' == in) &&
alloc *= 2; (length>=2) &&
ns = realloc(ns, alloc); isxdigit((int)string[1]) &&
if(!ns) isxdigit((int)string[2]) ) {
return NULL; /*
} * This is an already encoded letter, leave it!
sprintf(&ns[index], "%%%02X", in); */
index+=3; memcpy(&ns[index], string, 3);
string+=2;
} }
else { else {
/* just copy this */ /* encode this now */
ns[index++]=in;
newlen += 2; /* the size grows with two, since this'll become a %XX */
if(newlen > alloc) {
alloc *= 2;
ns = realloc(ns, alloc);
if(!ns)
return NULL;
}
sprintf(&ns[index], "%%%02X", in);
} }
string++; index+=3;
} }
ns[index]=0; /* terminate it */ else {
return ns; /* just copy this */
ns[index++]=in;
}
string++;
}
ns[index]=0; /* terminate it */
return ns;
} }
char *curl_unescape(char *string, int length) char *curl_unescape(char *string, int length)
{ {
int alloc = (length?length:strlen(string))+1; int alloc = (length?length:strlen(string))+1;
char *ns = malloc(alloc); char *ns = malloc(alloc);
unsigned char in; unsigned char in;
int index=0; int index=0;
int hex; unsigned int hex;
char querypart=FALSE; /* everything to the right of a '?' letter is char querypart=FALSE; /* everything to the right of a '?' letter is
the "query part" where '+' should become ' '. the "query part" where '+' should become ' '.
RFC 2316, section 3.10 */ RFC 2316, section 3.10 */
while(--alloc > 0) { while(--alloc > 0) {
in = *string; in = *string;
if(querypart && ('+' == in)) if(querypart && ('+' == in))
in = ' '; in = ' ';
else if(!querypart && ('?' == in)) { else if(!querypart && ('?' == in)) {
/* we have "walked in" to the query part */ /* we have "walked in" to the query part */
querypart=TRUE; querypart=TRUE;
}
else if('%' == in) {
/* encoded part */
if(sscanf(string+1, "%02X", &hex)) {
in = hex;
string+=2;
alloc-=2;
} }
else if('%' == in) { }
/* encoded part */
if(sscanf(string+1, "%02X", &hex)) { ns[index++] = in;
in = hex; string++;
string+=2; }
alloc-=2; ns[index]=0; /* terminate it */
} return ns;
}
ns[index++] = in;
string++;
}
ns[index]=0; /* terminate it */
return ns;
} }

View File

@@ -26,7 +26,7 @@
/* Escape and unescape URL encoding in strings. The functions return a new /* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */ * allocated string or NULL if an error occurred. */
char *curl_escape(char *string); char *curl_escape(char *string, int length);
char *curl_unescape(char *string, int length); char *curl_unescape(char *string, int length);
#endif #endif

View File

@@ -97,6 +97,9 @@ CURLcode Curl_file_connect(struct connectdata *conn)
char *actual_path = curl_unescape(conn->path, 0); char *actual_path = curl_unescape(conn->path, 0);
struct FILE *file; struct FILE *file;
int fd; int fd;
#if defined(WIN32) || defined(__EMX__)
int i;
#endif
file = (struct FILE *)malloc(sizeof(struct FILE)); file = (struct FILE *)malloc(sizeof(struct FILE));
if(!file) if(!file)
@@ -106,8 +109,6 @@ CURLcode Curl_file_connect(struct connectdata *conn)
conn->proto.file = file; conn->proto.file = file;
#if defined(WIN32) || defined(__EMX__) #if defined(WIN32) || defined(__EMX__)
int i;
/* change path separators from '/' to '\\' for Windows and OS/2 */ /* change path separators from '/' to '\\' for Windows and OS/2 */
for (i=0; actual_path[i] != '\0'; ++i) for (i=0; actual_path[i] != '\0'; ++i)
if (actual_path[i] == '/') if (actual_path[i] == '/')
@@ -182,11 +183,11 @@ CURLcode Curl_file(struct connectdata *conn)
return res; return res;
now = Curl_tvnow(); now = Curl_tvnow();
if(Curl_pgrsUpdate(data)) if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK; res = CURLE_ABORTED_BY_CALLBACK;
} }
now = Curl_tvnow(); now = Curl_tvnow();
if(Curl_pgrsUpdate(data)) if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK; res = CURLE_ABORTED_BY_CALLBACK;
close(fd); close(fd);

View File

@@ -371,6 +371,7 @@ char *Curl_FormBoundary(void)
void Curl_FormFree(struct FormData *form) void Curl_FormFree(struct FormData *form)
{ {
struct FormData *next; struct FormData *next;
do { do {
next=form->next; /* the following form line */ next=form->next; /* the following form line */
free(form->line); /* free the line */ free(form->line); /* free the line */
@@ -383,6 +384,11 @@ void Curl_FormFree(struct FormData *form)
void curl_formfree(struct HttpPost *form) void curl_formfree(struct HttpPost *form)
{ {
struct HttpPost *next; struct HttpPost *next;
if(!form)
/* no form to free, just get out of this */
return;
do { do {
next=form->next; /* the following form line */ next=form->next; /* the following form line */

300
lib/ftp.c
View File

@@ -77,6 +77,9 @@
#include "krb4.h" #include "krb4.h"
#endif #endif
#include "strequal.h"
#include "ssluse.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -119,8 +122,8 @@ static CURLcode AllowServerConnect(struct UrlData *data,
size_t size = sizeof(struct sockaddr_in); size_t size = sizeof(struct sockaddr_in);
struct sockaddr_in add; struct sockaddr_in add;
getsockname(sock, (struct sockaddr *) &add, (int *)&size); getsockname(sock, (struct sockaddr *) &add, (socklen_t *)&size);
s=accept(sock, (struct sockaddr *) &add, (int *)&size); s=accept(sock, (struct sockaddr *) &add, (socklen_t *)&size);
sclose(sock); /* close the first socket */ sclose(sock); /* close the first socket */
@@ -144,6 +147,165 @@ static CURLcode AllowServerConnect(struct UrlData *data,
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \ #define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
isdigit((int)line[2]) && (' ' == line[3])) isdigit((int)line[2]) && (' ' == line[3]))
int Curl_GetFTPResponse(int sockfd,
char *buf,
struct connectdata *conn,
int *ftpcode)
{
/* Brand new implementation.
* We cannot read just one byte per read() and then go back to select()
* as it seems that the OpenSSL read() stuff doesn't grok that properly.
*
* Alas, read as much as possible, split up into lines, use the ending
* line in a response or continue reading.
*/
int nread; /* total size read */
int perline; /* count bytes per line */
bool keepon=TRUE;
ssize_t gotbytes;
char *ptr;
int timeout = 3600; /* default timeout in seconds */
struct timeval interval;
fd_set rkeepfd;
fd_set readfd;
struct UrlData *data = conn->data;
char *line_start;
int code;
#define SELECT_OK 0
#define SELECT_ERROR 1
#define SELECT_TIMEOUT 2
int error = SELECT_OK;
if(ftpcode)
*ftpcode=0; /* 0 for errors */
if(data->timeout) {
/* if timeout is requested, find out how much remaining time we have */
timeout = data->timeout - /* timeout time */
(Curl_tvlong(Curl_tvnow()) - Curl_tvlong(conn->now)); /* spent time */
if(timeout <=0 ) {
failf(data, "Transfer aborted due to timeout");
return -SELECT_TIMEOUT; /* already too little time */
}
}
FD_ZERO (&readfd); /* clear it */
FD_SET (sockfd, &readfd); /* read socket */
/* get this in a backup variable to be able to restore it on each lap in the
select() loop */
rkeepfd = readfd;
ptr=buf;
line_start = buf;
nread=0;
perline=0;
keepon=TRUE;
while((nread<BUFSIZE) && (keepon && !error)) {
readfd = rkeepfd; /* set every lap */
interval.tv_sec = timeout;
interval.tv_usec = 0;
switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
case -1: /* select() error, stop reading */
error = SELECT_ERROR;
failf(data, "Transfer aborted due to select() error");
break;
case 0: /* timeout */
error = SELECT_TIMEOUT;
failf(data, "Transfer aborted due to timeout");
break;
default:
/*
* This code previously didn't use the kerberos sec_read() code
* to read, but when we use Curl_read() it may do so. Do confirm
* that this is still ok and then remove this comment!
*/
if(CURLE_OK != Curl_read(conn, sockfd, ptr, BUFSIZE-nread, &gotbytes))
keepon = FALSE;
else if(gotbytes <= 0) {
keepon = FALSE;
error = SELECT_ERROR;
failf(data, "Connection aborted");
}
else {
/* we got a whole chunk of data, which can be anything from one
* byte to a set of lines and possible just a piece of the last
* line */
int i;
nread += gotbytes;
for(i=0; i< gotbytes; ptr++, i++) {
perline++;
if(*ptr=='\n') {
/* a newline is CRLF in ftp-talk, so the CR is ignored as
the line isn't really terminated until the LF comes */
/* output debug output if that is requested */
if(data->bits.verbose) {
fputs("< ", data->err);
fwrite(line_start, 1, perline, data->err);
/* no need to output LF here, it is part of the data */
}
if(perline>3 && lastline(line_start)) {
/* This is the end of the last line, copy the last
* line to the start of the buffer and zero terminate,
* for old times sake (and krb4)! */
char *moo;
int i;
for(moo=line_start, i=0; moo<ptr; moo++, i++)
buf[i] = *moo;
moo[i]=0; /* zero terminate */
keepon=FALSE;
break;
}
perline=0; /* line starts over here */
line_start = ptr+1;
}
}
}
break;
} /* switch */
} /* while there's buffer left and loop is requested */
if(!error)
code = atoi(buf);
#if KRB4
/* handle the security-oriented responses 6xx ***/
/* FIXME: some errorchecking perhaps... ***/
switch(code) {
case 631:
sec_read_msg(conn, buf, prot_safe);
break;
case 632:
sec_read_msg(conn, buf, prot_private);
break;
case 633:
sec_read_msg(conn, buf, prot_confidential);
break;
default:
/* normal ftp stuff we pass through! */
break;
}
#endif
if(error)
return -error;
if(ftpcode)
*ftpcode=code; /* return the initial number like this */
return nread; /* total amount of bytes read */
}
#if 0
/* /*
* We allow the ftpcode pointer to be NULL if no reply integer is wanted * We allow the ftpcode pointer to be NULL if no reply integer is wanted
*/ */
@@ -154,6 +316,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
{ {
int nread; int nread;
ssize_t keepon=TRUE; ssize_t keepon=TRUE;
size_t got;
char *ptr; char *ptr;
int timeout = 3600; /* in seconds */ int timeout = 3600; /* in seconds */
struct timeval interval; struct timeval interval;
@@ -257,6 +420,7 @@ int Curl_GetFTPResponse(int sockfd, char *buf,
return nread; return nread;
} }
#endif
/* -- who are we? -- */ /* -- who are we? -- */
char *Curl_getmyhost(char *buf, int buf_size) char *Curl_getmyhost(char *buf, int buf_size)
@@ -314,6 +478,14 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
return result; return result;
} }
if(conn->protocol & PROT_FTPS) {
/* FTPS is simply ftp with SSL for the control channel */
/* now, perform the SSL initialization for this socket */
if(Curl_SSLConnect(conn))
return CURLE_SSL_CONNECT_ERROR;
}
/* The first thing we do is wait for the "220*" line: */ /* The first thing we do is wait for the "220*" line: */
nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode);
if(nread < 0) if(nread < 0)
@@ -335,8 +507,6 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
set a valid level */ set a valid level */
sec_request_prot(conn, data->krb4_level); sec_request_prot(conn, data->krb4_level);
data->cmdchannel = fdopen(conn->firstsocket, "w");
if(sec_login(conn) != 0) if(sec_login(conn) != 0)
infof(data, "Logging in with password in cleartext!\n"); infof(data, "Logging in with password in cleartext!\n");
else else
@@ -549,13 +719,14 @@ CURLcode _ftp(struct connectdata *conn)
char *buf = data->buffer; /* this is our buffer */ char *buf = data->buffer; /* this is our buffer */
/* for the ftp PORT mode */ /* for the ftp PORT mode */
int portsock=-1; int portsock=-1;
struct sockaddr_in serv_addr;
char hostent_buf[8192];
#if defined (HAVE_INET_NTOA_R) #if defined (HAVE_INET_NTOA_R)
char ntoa_buf[64]; char ntoa_buf[64];
#endif #endif
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct addrinfo *ai; struct addrinfo *ai;
#else
struct sockaddr_in serv_addr;
char hostent_buf[8192];
#endif #endif
struct curl_slist *qitem; /* QUOTE item */ struct curl_slist *qitem; /* QUOTE item */
@@ -715,20 +886,20 @@ CURLcode _ftp(struct connectdata *conn)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct addrinfo hints, *res, *ai; struct addrinfo hints, *res, *ai;
struct sockaddr_storage ss; struct sockaddr_storage ss;
int sslen; socklen_t sslen;
char hbuf[NI_MAXHOST]; char hbuf[NI_MAXHOST];
char *localaddr;
struct sockaddr *sa=(struct sockaddr *)&ss; struct sockaddr *sa=(struct sockaddr *)&ss;
#ifdef NI_WITHSCOPEID #ifdef NI_WITHSCOPEID
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID; const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else #else
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV; const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif #endif
unsigned char *ap; char *ap;
unsigned char *pp; char *pp;
int alen, plen; int alen, plen;
char portmsgbuf[4096], tmp[4096]; char portmsgbuf[4096], tmp[4096];
char *p;
char *mode[] = { "EPRT", "LPRT", "PORT", NULL }; char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
char **modep; char **modep;
@@ -761,13 +932,13 @@ CURLcode _ftp(struct connectdata *conn)
continue; continue;
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) { if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
close(portsock); sclose(portsock);
portsock = -1; portsock = -1;
continue; continue;
} }
if (listen(portsock, 1) < 0) { if (listen(portsock, 1) < 0) {
close(portsock); sclose(portsock);
portsock = -1; portsock = -1;
continue; continue;
} }
@@ -827,7 +998,8 @@ CURLcode _ftp(struct connectdata *conn)
} }
ftpsendf(conn->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf, ftpsendf(conn->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf,
portmsgbuf, tmp); portmsgbuf, tmp);
} else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) { } else if (strcmp(*modep, "LPRT") == 0 ||
strcmp(*modep, "PORT") == 0) {
int i; int i;
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0) if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
@@ -839,7 +1011,7 @@ CURLcode _ftp(struct connectdata *conn)
if (strcmp(*modep, "LPRT") == 0) { if (strcmp(*modep, "LPRT") == 0) {
snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen); snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again; continue;
} }
} }
for (i = 0; i < alen; i++) { for (i = 0; i < alen; i++) {
@@ -848,18 +1020,18 @@ CURLcode _ftp(struct connectdata *conn)
else else
snprintf(tmp, sizeof(tmp), "%u", ap[i]); snprintf(tmp, sizeof(tmp), "%u", ap[i]);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again; continue;
} }
} }
if (strcmp(*modep, "LPRT") == 0) { if (strcmp(*modep, "LPRT") == 0) {
snprintf(tmp, sizeof(tmp), ",%d", plen); snprintf(tmp, sizeof(tmp), ",%d", plen);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
goto again; continue;
} }
for (i = 0; i < plen; i++) { for (i = 0; i < plen; i++) {
snprintf(tmp, sizeof(tmp), ",%u", pp[i]); snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) { if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
goto again; continue;
} }
} }
ftpsendf(conn->firstsocket, conn, "%s %s", *modep, portmsgbuf); ftpsendf(conn->firstsocket, conn, "%s %s", *modep, portmsgbuf);
@@ -878,7 +1050,7 @@ again:;
} }
if (!*modep) { if (!*modep) {
close(portsock); sclose(portsock);
freeaddrinfo(res); freeaddrinfo(res);
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
@@ -932,7 +1104,7 @@ again:;
size = sizeof(add); size = sizeof(add);
if(getsockname(portsock, (struct sockaddr *) &add, if(getsockname(portsock, (struct sockaddr *) &add,
(int *)&size)<0) { (socklen_t *)&size)<0) {
failf(data, "getsockname() failed"); failf(data, "getsockname() failed");
return CURLE_FTP_PORT_FAILED; return CURLE_FTP_PORT_FAILED;
} }
@@ -1027,9 +1199,10 @@ again:;
struct addrinfo *res; struct addrinfo *res;
#else #else
struct hostent *he; struct hostent *he;
#endif
char *str=buf,*ip_addr;
char *hostdataptr=NULL; char *hostdataptr=NULL;
char *ip_addr;
#endif
char *str=buf;
/* /*
* New 227-parser June 3rd 1999. * New 227-parser June 3rd 1999.
@@ -1261,7 +1434,7 @@ again:;
CURLE_FTP_COULDNT_SET_BINARY; CURLE_FTP_COULDNT_SET_BINARY;
} }
if(data->resume_from) { if(conn->resume_from) {
/* we're about to continue the uploading of a file */ /* we're about to continue the uploading of a file */
/* 1. get already existing file's size. We use the SIZE /* 1. get already existing file's size. We use the SIZE
command for this which may not exist in the server! command for this which may not exist in the server!
@@ -1275,7 +1448,7 @@ again:;
/* 4. lower the infilesize counter */ /* 4. lower the infilesize counter */
/* => transfer as usual */ /* => transfer as usual */
if(data->resume_from < 0 ) { if(conn->resume_from < 0 ) {
/* we could've got a specified offset from the command line, /* we could've got a specified offset from the command line,
but now we know we didn't */ but now we know we didn't */
@@ -1291,10 +1464,10 @@ again:;
} }
/* get the size from the ascii string: */ /* get the size from the ascii string: */
data->resume_from = atoi(buf+4); conn->resume_from = atoi(buf+4);
} }
if(data->resume_from) { if(conn->resume_from) {
/* do we still game? */ /* do we still game? */
int passed=0; int passed=0;
/* enable append instead */ /* enable append instead */
@@ -1304,7 +1477,7 @@ again:;
input. If we knew it was a proper file we could've just input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */ fseek()ed but we only have a stream here */
do { do {
int readthisamountnow = (data->resume_from - passed); int readthisamountnow = (conn->resume_from - passed);
int actuallyread; int actuallyread;
if(readthisamountnow > BUFSIZE) if(readthisamountnow > BUFSIZE)
@@ -1320,11 +1493,11 @@ again:;
return CURLE_FTP_COULDNT_USE_REST; return CURLE_FTP_COULDNT_USE_REST;
} }
} }
while(passed != data->resume_from); while(passed != conn->resume_from);
/* now, decrease the size of the read */ /* now, decrease the size of the read */
if(data->infilesize>0) { if(data->infilesize>0) {
data->infilesize -= data->resume_from; data->infilesize -= conn->resume_from;
if(data->infilesize <= 0) { if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n"); failf(data, "File already completely uploaded\n");
@@ -1376,13 +1549,13 @@ again:;
bool dirlist=FALSE; bool dirlist=FALSE;
long downloadsize=-1; long downloadsize=-1;
if(data->bits.set_range && data->range) { if(conn->bits.use_range && conn->range) {
long from, to; long from, to;
int totalsize=-1; int totalsize=-1;
char *ptr; char *ptr;
char *ptr2; char *ptr2;
from=strtol(data->range, &ptr, 0); from=strtol(conn->range, &ptr, 0);
while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-'))) while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
ptr++; ptr++;
to=strtol(ptr, &ptr2, 0); to=strtol(ptr, &ptr2, 0);
@@ -1392,22 +1565,23 @@ again:;
} }
if((-1 == to) && (from>=0)) { if((-1 == to) && (from>=0)) {
/* X - */ /* X - */
data->resume_from = from; conn->resume_from = from;
infof(data, "FTP RANGE %d to end of file\n", from); infof(data, "FTP RANGE %d to end of file\n", from);
} }
else if(from < 0) { else if(from < 0) {
/* -Y */ /* -Y */
totalsize = -from; totalsize = -from;
conn->maxdownload = -from; conn->maxdownload = -from;
data->resume_from = from; conn->resume_from = from;
infof(data, "FTP RANGE the last %d bytes\n", totalsize); infof(data, "FTP RANGE the last %d bytes\n", totalsize);
} }
else { else {
/* X-Y */ /* X-Y */
totalsize = to-from; totalsize = to-from;
conn->maxdownload = totalsize+1; /* include the last mentioned byte */ conn->maxdownload = totalsize+1; /* include the last mentioned byte */
data->resume_from = from; conn->resume_from = from;
infof(data, "FTP RANGE from %d getting %d bytes\n", from, conn->maxdownload); infof(data, "FTP RANGE from %d getting %d bytes\n", from,
conn->maxdownload);
} }
infof(data, "range-download from %d to %d, totally %d bytes\n", infof(data, "range-download from %d to %d, totally %d bytes\n",
from, to, totalsize); from, to, totalsize);
@@ -1455,7 +1629,7 @@ again:;
CURLE_FTP_COULDNT_SET_BINARY; CURLE_FTP_COULDNT_SET_BINARY;
} }
if(data->resume_from) { if(conn->resume_from) {
/* Daniel: (August 4, 1999) /* Daniel: (August 4, 1999)
* *
@@ -1480,34 +1654,39 @@ again:;
int foundsize=atoi(buf+4); int foundsize=atoi(buf+4);
/* We got a file size report, so we check that there actually is a /* We got a file size report, so we check that there actually is a
part of the file left to get, or else we go home. */ part of the file left to get, or else we go home. */
if(data->resume_from< 0) { if(conn->resume_from< 0) {
/* We're supposed to download the last abs(from) bytes */ /* We're supposed to download the last abs(from) bytes */
if(foundsize < -data->resume_from) { if(foundsize < -conn->resume_from) {
failf(data, "Offset (%d) was beyond file size (%d)", failf(data, "Offset (%d) was beyond file size (%d)",
data->resume_from, foundsize); conn->resume_from, foundsize);
return CURLE_FTP_BAD_DOWNLOAD_RESUME; return CURLE_FTP_BAD_DOWNLOAD_RESUME;
} }
/* convert to size to download */ /* convert to size to download */
downloadsize = -data->resume_from; downloadsize = -conn->resume_from;
/* download from where? */ /* download from where? */
data->resume_from = foundsize - downloadsize; conn->resume_from = foundsize - downloadsize;
} }
else { else {
if(foundsize <= data->resume_from) { if(foundsize < conn->resume_from) {
failf(data, "Offset (%d) was beyond file size (%d)", failf(data, "Offset (%d) was beyond file size (%d)",
data->resume_from, foundsize); conn->resume_from, foundsize);
return CURLE_FTP_BAD_DOWNLOAD_RESUME; return CURLE_FTP_BAD_DOWNLOAD_RESUME;
} }
/* Now store the number of bytes we are expected to download */ /* Now store the number of bytes we are expected to download */
downloadsize = foundsize-data->resume_from; downloadsize = foundsize-conn->resume_from;
} }
} }
if (downloadsize == 0) {
failf(data, "File already complete");
return CURLE_ALREADY_COMPLETE;
}
/* Set resume file transfer offset */ /* Set resume file transfer offset */
infof(data, "Instructs server to resume from offset %d\n", infof(data, "Instructs server to resume from offset %d\n",
data->resume_from); conn->resume_from);
ftpsendf(conn->firstsocket, conn, "REST %d", data->resume_from); ftpsendf(conn->firstsocket, conn, "REST %d", conn->resume_from);
nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode); nread = Curl_GetFTPResponse(conn->firstsocket, buf, conn, &ftpcode);
if(nread < 0) if(nread < 0)
@@ -1698,16 +1877,9 @@ size_t Curl_ftpsendf(int fd, struct connectdata *conn, char *fmt, ...)
strcat(s, "\r\n"); /* append a trailing CRLF */ strcat(s, "\r\n"); /* append a trailing CRLF */
#ifdef KRB4 bytes_written=0;
if(conn->sec_complete && conn->data->cmdchannel) { Curl_write(conn, fd, s, strlen(s), &bytes_written);
bytes_written = sec_fprintf(conn, conn->data->cmdchannel, s);
fflush(conn->data->cmdchannel);
}
else
#endif /* KRB4 */
{
bytes_written = swrite(fd, s, strlen(s));
}
return(bytes_written); return(bytes_written);
} }
@@ -1716,12 +1888,14 @@ CURLcode Curl_ftp_disconnect(struct connectdata *conn)
{ {
struct FTP *ftp= conn->proto.ftp; struct FTP *ftp= conn->proto.ftp;
if(ftp->user) /* The FTP session may or may not have been allocated/setup at this point! */
free(ftp->user); if(ftp) {
if(ftp->passwd) if(ftp->user)
free(ftp->passwd); free(ftp->user);
if(ftp->entrypath) if(ftp->passwd)
free(ftp->entrypath); free(ftp->passwd);
if(ftp->entrypath)
free(ftp->entrypath);
}
return CURLE_OK; return CURLE_OK;
} }

View File

@@ -104,6 +104,11 @@
# include <string.h> # include <string.h>
#endif #endif
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __attribute__(x) # define __attribute__(x)
#endif #endif
@@ -127,44 +132,44 @@
then those parser generators need to be fixed instead of adding those then those parser generators need to be fixed instead of adding those
names to this list. */ names to this list. */
#define yymaxdepth gd_maxdepth #define yymaxdepth Curl_gd_maxdepth
#define yyparse gd_parse #define yyparse Curl_gd_parse
#define yylex gd_lex #define yylex Curl_gd_lex
#define yyerror gd_error #define yyerror Curl_gd_error
#define yylval gd_lval #define yylval Curl_gd_lval
#define yychar gd_char #define yychar Curl_gd_char
#define yydebug gd_debug #define yydebug Curl_gd_debug
#define yypact gd_pact #define yypact Curl_gd_pact
#define yyr1 gd_r1 #define yyr1 Curl_gd_r1
#define yyr2 gd_r2 #define yyr2 Curl_gd_r2
#define yydef gd_def #define yydef Curl_gd_def
#define yychk gd_chk #define yychk Curl_gd_chk
#define yypgo gd_pgo #define yypgo Curl_gd_pgo
#define yyact gd_act #define yyact Curl_gd_act
#define yyexca gd_exca #define yyexca Curl_gd_exca
#define yyerrflag gd_errflag #define yyerrflag Curl_gd_errflag
#define yynerrs gd_nerrs #define yynerrs Curl_gd_nerrs
#define yyps gd_ps #define yyps Curl_gd_ps
#define yypv gd_pv #define yypv Curl_gd_pv
#define yys gd_s #define yys Curl_gd_s
#define yy_yys gd_yys #define yy_yys Curl_gd_yys
#define yystate gd_state #define yystate Curl_gd_state
#define yytmp gd_tmp #define yytmp Curl_gd_tmp
#define yyv gd_v #define yyv Curl_gd_v
#define yy_yyv gd_yyv #define yy_yyv Curl_gd_yyv
#define yyval gd_val #define yyval Curl_gd_val
#define yylloc gd_lloc #define yylloc Curl_gd_lloc
#define yyreds gd_reds /* With YYDEBUG defined */ #define yyreds Curl_gd_reds /* With YYDEBUG defined */
#define yytoks gd_toks /* With YYDEBUG defined */ #define yytoks Curl_gd_toks /* With YYDEBUG defined */
#define yylhs gd_yylhs #define yylhs Curl_gd_yylhs
#define yylen gd_yylen #define yylen Curl_gd_yylen
#define yydefred gd_yydefred #define yydefred Curl_gd_yydefred
#define yydgoto gd_yydgoto #define yydgoto Curl_gd_yydgoto
#define yysindex gd_yysindex #define yysindex Curl_gd_yysindex
#define yyrindex gd_yyrindex #define yyrindex Curl_gd_yyrindex
#define yygindex gd_yygindex #define yygindex Curl_gd_yygindex
#define yytable gd_yytable #define yytable Curl_gd_yytable
#define yycheck gd_yycheck #define yycheck Curl_gd_yycheck
static int yylex (); static int yylex ();
static int yyerror (); static int yyerror ();
@@ -222,7 +227,7 @@ static int yyRelSeconds;
static int yyRelYear; static int yyRelYear;
#line 205 "getdate.y" #line 210 "getdate.y"
typedef union { typedef union {
int Number; int Number;
enum _MERIDIAN Meridian; enum _MERIDIAN Meridian;
@@ -305,11 +310,11 @@ static const short yyrhs[] = { -1,
#if YYDEBUG != 0 #if YYDEBUG != 0
static const short yyrline[] = { 0, static const short yyrline[] = { 0,
221, 222, 225, 228, 231, 234, 237, 240, 243, 249, 226, 227, 230, 233, 236, 239, 242, 245, 248, 254,
255, 264, 270, 282, 285, 288, 294, 298, 302, 308, 260, 269, 275, 287, 290, 293, 299, 303, 307, 313,
312, 330, 336, 342, 346, 351, 355, 362, 370, 373, 317, 335, 341, 347, 351, 356, 360, 367, 375, 378,
376, 379, 382, 385, 388, 391, 394, 397, 400, 403, 381, 384, 387, 390, 393, 396, 399, 402, 405, 408,
406, 409, 412, 415, 418, 421, 424, 429, 462, 466 411, 414, 417, 420, 423, 426, 429, 434, 467, 471
}; };
#endif #endif
@@ -933,37 +938,37 @@ yyreduce:
switch (yyn) { switch (yyn) {
case 3: case 3:
#line 225 "getdate.y" #line 230 "getdate.y"
{ {
yyHaveTime++; yyHaveTime++;
; ;
break;} break;}
case 4: case 4:
#line 228 "getdate.y" #line 233 "getdate.y"
{ {
yyHaveZone++; yyHaveZone++;
; ;
break;} break;}
case 5: case 5:
#line 231 "getdate.y" #line 236 "getdate.y"
{ {
yyHaveDate++; yyHaveDate++;
; ;
break;} break;}
case 6: case 6:
#line 234 "getdate.y" #line 239 "getdate.y"
{ {
yyHaveDay++; yyHaveDay++;
; ;
break;} break;}
case 7: case 7:
#line 237 "getdate.y" #line 242 "getdate.y"
{ {
yyHaveRel++; yyHaveRel++;
; ;
break;} break;}
case 9: case 9:
#line 243 "getdate.y" #line 248 "getdate.y"
{ {
yyHour = yyvsp[-1].Number; yyHour = yyvsp[-1].Number;
yyMinutes = 0; yyMinutes = 0;
@@ -972,7 +977,7 @@ case 9:
; ;
break;} break;}
case 10: case 10:
#line 249 "getdate.y" #line 254 "getdate.y"
{ {
yyHour = yyvsp[-3].Number; yyHour = yyvsp[-3].Number;
yyMinutes = yyvsp[-1].Number; yyMinutes = yyvsp[-1].Number;
@@ -981,7 +986,7 @@ case 10:
; ;
break;} break;}
case 11: case 11:
#line 255 "getdate.y" #line 260 "getdate.y"
{ {
yyHour = yyvsp[-3].Number; yyHour = yyvsp[-3].Number;
yyMinutes = yyvsp[-1].Number; yyMinutes = yyvsp[-1].Number;
@@ -993,7 +998,7 @@ case 11:
; ;
break;} break;}
case 12: case 12:
#line 264 "getdate.y" #line 269 "getdate.y"
{ {
yyHour = yyvsp[-5].Number; yyHour = yyvsp[-5].Number;
yyMinutes = yyvsp[-3].Number; yyMinutes = yyvsp[-3].Number;
@@ -1002,7 +1007,7 @@ case 12:
; ;
break;} break;}
case 13: case 13:
#line 270 "getdate.y" #line 275 "getdate.y"
{ {
yyHour = yyvsp[-5].Number; yyHour = yyvsp[-5].Number;
yyMinutes = yyvsp[-3].Number; yyMinutes = yyvsp[-3].Number;
@@ -1015,53 +1020,53 @@ case 13:
; ;
break;} break;}
case 14: case 14:
#line 282 "getdate.y" #line 287 "getdate.y"
{ {
yyTimezone = yyvsp[0].Number; yyTimezone = yyvsp[0].Number;
; ;
break;} break;}
case 15: case 15:
#line 285 "getdate.y" #line 290 "getdate.y"
{ {
yyTimezone = yyvsp[0].Number - 60; yyTimezone = yyvsp[0].Number - 60;
; ;
break;} break;}
case 16: case 16:
#line 289 "getdate.y" #line 294 "getdate.y"
{ {
yyTimezone = yyvsp[-1].Number - 60; yyTimezone = yyvsp[-1].Number - 60;
; ;
break;} break;}
case 17: case 17:
#line 294 "getdate.y" #line 299 "getdate.y"
{ {
yyDayOrdinal = 1; yyDayOrdinal = 1;
yyDayNumber = yyvsp[0].Number; yyDayNumber = yyvsp[0].Number;
; ;
break;} break;}
case 18: case 18:
#line 298 "getdate.y" #line 303 "getdate.y"
{ {
yyDayOrdinal = 1; yyDayOrdinal = 1;
yyDayNumber = yyvsp[-1].Number; yyDayNumber = yyvsp[-1].Number;
; ;
break;} break;}
case 19: case 19:
#line 302 "getdate.y" #line 307 "getdate.y"
{ {
yyDayOrdinal = yyvsp[-1].Number; yyDayOrdinal = yyvsp[-1].Number;
yyDayNumber = yyvsp[0].Number; yyDayNumber = yyvsp[0].Number;
; ;
break;} break;}
case 20: case 20:
#line 308 "getdate.y" #line 313 "getdate.y"
{ {
yyMonth = yyvsp[-2].Number; yyMonth = yyvsp[-2].Number;
yyDay = yyvsp[0].Number; yyDay = yyvsp[0].Number;
; ;
break;} break;}
case 21: case 21:
#line 312 "getdate.y" #line 317 "getdate.y"
{ {
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY. /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
The goal in recognizing YYYY/MM/DD is solely to support legacy The goal in recognizing YYYY/MM/DD is solely to support legacy
@@ -1082,7 +1087,7 @@ case 21:
; ;
break;} break;}
case 22: case 22:
#line 330 "getdate.y" #line 335 "getdate.y"
{ {
/* ISO 8601 format. yyyy-mm-dd. */ /* ISO 8601 format. yyyy-mm-dd. */
yyYear = yyvsp[-2].Number; yyYear = yyvsp[-2].Number;
@@ -1091,7 +1096,7 @@ case 22:
; ;
break;} break;}
case 23: case 23:
#line 336 "getdate.y" #line 341 "getdate.y"
{ {
/* e.g. 17-JUN-1992. */ /* e.g. 17-JUN-1992. */
yyDay = yyvsp[-2].Number; yyDay = yyvsp[-2].Number;
@@ -1100,14 +1105,14 @@ case 23:
; ;
break;} break;}
case 24: case 24:
#line 342 "getdate.y" #line 347 "getdate.y"
{ {
yyMonth = yyvsp[-1].Number; yyMonth = yyvsp[-1].Number;
yyDay = yyvsp[0].Number; yyDay = yyvsp[0].Number;
; ;
break;} break;}
case 25: case 25:
#line 346 "getdate.y" #line 351 "getdate.y"
{ {
yyMonth = yyvsp[-3].Number; yyMonth = yyvsp[-3].Number;
yyDay = yyvsp[-2].Number; yyDay = yyvsp[-2].Number;
@@ -1115,14 +1120,14 @@ case 25:
; ;
break;} break;}
case 26: case 26:
#line 351 "getdate.y" #line 356 "getdate.y"
{ {
yyMonth = yyvsp[0].Number; yyMonth = yyvsp[0].Number;
yyDay = yyvsp[-1].Number; yyDay = yyvsp[-1].Number;
; ;
break;} break;}
case 27: case 27:
#line 355 "getdate.y" #line 360 "getdate.y"
{ {
yyMonth = yyvsp[-1].Number; yyMonth = yyvsp[-1].Number;
yyDay = yyvsp[-2].Number; yyDay = yyvsp[-2].Number;
@@ -1130,7 +1135,7 @@ case 27:
; ;
break;} break;}
case 28: case 28:
#line 362 "getdate.y" #line 367 "getdate.y"
{ {
yyRelSeconds = -yyRelSeconds; yyRelSeconds = -yyRelSeconds;
yyRelMinutes = -yyRelMinutes; yyRelMinutes = -yyRelMinutes;
@@ -1141,115 +1146,115 @@ case 28:
; ;
break;} break;}
case 30: case 30:
#line 373 "getdate.y" #line 378 "getdate.y"
{ {
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 31: case 31:
#line 376 "getdate.y" #line 381 "getdate.y"
{ {
yyRelYear += yyvsp[-1].Number * yyvsp[0].Number; yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 32: case 32:
#line 379 "getdate.y" #line 384 "getdate.y"
{ {
yyRelYear += yyvsp[0].Number; yyRelYear += yyvsp[0].Number;
; ;
break;} break;}
case 33: case 33:
#line 382 "getdate.y" #line 387 "getdate.y"
{ {
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 34: case 34:
#line 385 "getdate.y" #line 390 "getdate.y"
{ {
yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 35: case 35:
#line 388 "getdate.y" #line 393 "getdate.y"
{ {
yyRelMonth += yyvsp[0].Number; yyRelMonth += yyvsp[0].Number;
; ;
break;} break;}
case 36: case 36:
#line 391 "getdate.y" #line 396 "getdate.y"
{ {
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 37: case 37:
#line 394 "getdate.y" #line 399 "getdate.y"
{ {
yyRelDay += yyvsp[-1].Number * yyvsp[0].Number; yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 38: case 38:
#line 397 "getdate.y" #line 402 "getdate.y"
{ {
yyRelDay += yyvsp[0].Number; yyRelDay += yyvsp[0].Number;
; ;
break;} break;}
case 39: case 39:
#line 400 "getdate.y" #line 405 "getdate.y"
{ {
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 40: case 40:
#line 403 "getdate.y" #line 408 "getdate.y"
{ {
yyRelHour += yyvsp[-1].Number * yyvsp[0].Number; yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 41: case 41:
#line 406 "getdate.y" #line 411 "getdate.y"
{ {
yyRelHour += yyvsp[0].Number; yyRelHour += yyvsp[0].Number;
; ;
break;} break;}
case 42: case 42:
#line 409 "getdate.y" #line 414 "getdate.y"
{ {
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 43: case 43:
#line 412 "getdate.y" #line 417 "getdate.y"
{ {
yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number; yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 44: case 44:
#line 415 "getdate.y" #line 420 "getdate.y"
{ {
yyRelMinutes += yyvsp[0].Number; yyRelMinutes += yyvsp[0].Number;
; ;
break;} break;}
case 45: case 45:
#line 418 "getdate.y" #line 423 "getdate.y"
{ {
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 46: case 46:
#line 421 "getdate.y" #line 426 "getdate.y"
{ {
yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number; yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
; ;
break;} break;}
case 47: case 47:
#line 424 "getdate.y" #line 429 "getdate.y"
{ {
yyRelSeconds += yyvsp[0].Number; yyRelSeconds += yyvsp[0].Number;
; ;
break;} break;}
case 48: case 48:
#line 430 "getdate.y" #line 435 "getdate.y"
{ {
if (yyHaveTime && yyHaveDate && !yyHaveRel) if (yyHaveTime && yyHaveDate && !yyHaveRel)
yyYear = yyvsp[0].Number; yyYear = yyvsp[0].Number;
@@ -1282,13 +1287,13 @@ case 48:
; ;
break;} break;}
case 49: case 49:
#line 463 "getdate.y" #line 468 "getdate.y"
{ {
yyval.Meridian = MER24; yyval.Meridian = MER24;
; ;
break;} break;}
case 50: case 50:
#line 467 "getdate.y" #line 472 "getdate.y"
{ {
yyval.Meridian = yyvsp[0].Meridian; yyval.Meridian = yyvsp[0].Meridian;
; ;
@@ -1515,7 +1520,7 @@ yyerrhandle:
} }
return 1; return 1;
} }
#line 472 "getdate.y" #line 477 "getdate.y"
/* Include this file down here because bison inserts code above which /* Include this file down here because bison inserts code above which

View File

@@ -80,6 +80,11 @@
# include <string.h> # include <string.h>
#endif #endif
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
# define __attribute__(x) # define __attribute__(x)
#endif #endif
@@ -103,44 +108,44 @@
then those parser generators need to be fixed instead of adding those then those parser generators need to be fixed instead of adding those
names to this list. */ names to this list. */
#define yymaxdepth gd_maxdepth #define yymaxdepth Curl_gd_maxdepth
#define yyparse gd_parse #define yyparse Curl_gd_parse
#define yylex gd_lex #define yylex Curl_gd_lex
#define yyerror gd_error #define yyerror Curl_gd_error
#define yylval gd_lval #define yylval Curl_gd_lval
#define yychar gd_char #define yychar Curl_gd_char
#define yydebug gd_debug #define yydebug Curl_gd_debug
#define yypact gd_pact #define yypact Curl_gd_pact
#define yyr1 gd_r1 #define yyr1 Curl_gd_r1
#define yyr2 gd_r2 #define yyr2 Curl_gd_r2
#define yydef gd_def #define yydef Curl_gd_def
#define yychk gd_chk #define yychk Curl_gd_chk
#define yypgo gd_pgo #define yypgo Curl_gd_pgo
#define yyact gd_act #define yyact Curl_gd_act
#define yyexca gd_exca #define yyexca Curl_gd_exca
#define yyerrflag gd_errflag #define yyerrflag Curl_gd_errflag
#define yynerrs gd_nerrs #define yynerrs Curl_gd_nerrs
#define yyps gd_ps #define yyps Curl_gd_ps
#define yypv gd_pv #define yypv Curl_gd_pv
#define yys gd_s #define yys Curl_gd_s
#define yy_yys gd_yys #define yy_yys Curl_gd_yys
#define yystate gd_state #define yystate Curl_gd_state
#define yytmp gd_tmp #define yytmp Curl_gd_tmp
#define yyv gd_v #define yyv Curl_gd_v
#define yy_yyv gd_yyv #define yy_yyv Curl_gd_yyv
#define yyval gd_val #define yyval Curl_gd_val
#define yylloc gd_lloc #define yylloc Curl_gd_lloc
#define yyreds gd_reds /* With YYDEBUG defined */ #define yyreds Curl_gd_reds /* With YYDEBUG defined */
#define yytoks gd_toks /* With YYDEBUG defined */ #define yytoks Curl_gd_toks /* With YYDEBUG defined */
#define yylhs gd_yylhs #define yylhs Curl_gd_yylhs
#define yylen gd_yylen #define yylen Curl_gd_yylen
#define yydefred gd_yydefred #define yydefred Curl_gd_yydefred
#define yydgoto gd_yydgoto #define yydgoto Curl_gd_yydgoto
#define yysindex gd_yysindex #define yysindex Curl_gd_yysindex
#define yyrindex gd_yyrindex #define yyrindex Curl_gd_yyrindex
#define yygindex gd_yygindex #define yygindex Curl_gd_yygindex
#define yytable gd_yytable #define yytable Curl_gd_yytable
#define yycheck gd_yycheck #define yycheck Curl_gd_yycheck
static int yylex (); static int yylex ();
static int yyerror (); static int yyerror ();

View File

@@ -31,7 +31,7 @@
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
CURLcode curl_getinfo(CURL *curl, CURLINFO info, ...) CURLcode Curl_getinfo(CURL *curl, CURLINFO info, ...)
{ {
va_list arg; va_list arg;
long *param_longp; long *param_longp;

View File

@@ -66,6 +66,11 @@
# endif # endif
#endif #endif
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
/* no perror? make an fprintf! */ /* no perror? make an fprintf! */
#ifndef HAVE_PERROR #ifndef HAVE_PERROR
# define perror(x) fprintf(stderr, "Error in: %s\n", x) # define perror(x) fprintf(stderr, "Error in: %s\n", x)

View File

@@ -283,7 +283,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
"%s" "%s"
"\r\n", "\r\n",
hostname, remote_port, hostname, remote_port,
(data->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"", (conn->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"",
(data->useragent?conn->allocptr.uagent:"") (data->useragent?conn->allocptr.uagent:"")
); );
@@ -340,7 +340,7 @@ CURLcode Curl_http_connect(struct connectdata *conn)
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
if(data->bits.user_passwd && !data->bits.this_is_a_follow) { if(conn->bits.user_passwd && !data->bits.this_is_a_follow) {
/* Authorization: is requested, this is not a followed location, get the /* Authorization: is requested, this is not a followed location, get the
original host name */ original host name */
data->auth_host = strdup(conn->hostname); data->auth_host = strdup(conn->hostname);
@@ -423,7 +423,7 @@ CURLcode Curl_http(struct connectdata *conn)
conn->allocptr.uagent=NULL; conn->allocptr.uagent=NULL;
} }
if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) { if((conn->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
char *authorization; char *authorization;
/* To prevent the user+password to get sent to other than the original /* To prevent the user+password to get sent to other than the original
@@ -469,10 +469,14 @@ CURLcode Curl_http(struct connectdata *conn)
http->sendit = Curl_getFormData(data->httppost, &http->postsize); http->sendit = Curl_getFormData(data->httppost, &http->postsize);
} }
if(!checkheaders(data, "Host:") && if(!checkheaders(data, "Host:")) {
!conn->allocptr.host) { /* if ptr_host is already set, it is almost OK since we only re-use
/* if ptr_host is already set, it is OK since we only re-use connections connections to the very same host and port, but when we use a HTTP
to the very same host and port */ proxy we have a persistant connect and yet we must change the Host:
header! */
if(conn->allocptr.host)
free(conn->allocptr.host);
if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) || if(((conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTPS)) ||
(!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) ) (!(conn->protocol&PROT_HTTPS) && (conn->remote_port == PORT_HTTP)) )
@@ -493,7 +497,7 @@ CURLcode Curl_http(struct connectdata *conn)
if((data->bits.http_post || if((data->bits.http_post ||
data->bits.http_formpost || data->bits.http_formpost ||
data->bits.http_put) && data->bits.http_put) &&
data->resume_from) { conn->resume_from) {
/********************************************************************** /**********************************************************************
* Resuming upload in HTTP means that we PUT or POST and that we have * Resuming upload in HTTP means that we PUT or POST and that we have
* got a resume_from value set. The resume value has already created * got a resume_from value set. The resume value has already created
@@ -502,15 +506,15 @@ CURLcode Curl_http(struct connectdata *conn)
* file size before we continue this venture in the dark lands of HTTP. * file size before we continue this venture in the dark lands of HTTP.
*********************************************************************/ *********************************************************************/
if(data->resume_from < 0 ) { if(conn->resume_from < 0 ) {
/* /*
* This is meant to get the size of the present remote-file by itself. * This is meant to get the size of the present remote-file by itself.
* We don't support this now. Bail out! * We don't support this now. Bail out!
*/ */
data->resume_from = 0; conn->resume_from = 0;
} }
if(data->resume_from) { if(conn->resume_from) {
/* do we still game? */ /* do we still game? */
int passed=0; int passed=0;
@@ -518,7 +522,7 @@ CURLcode Curl_http(struct connectdata *conn)
input. If we knew it was a proper file we could've just input. If we knew it was a proper file we could've just
fseek()ed but we only have a stream here */ fseek()ed but we only have a stream here */
do { do {
int readthisamountnow = (data->resume_from - passed); int readthisamountnow = (conn->resume_from - passed);
int actuallyread; int actuallyread;
if(readthisamountnow > BUFSIZE) if(readthisamountnow > BUFSIZE)
@@ -533,11 +537,11 @@ CURLcode Curl_http(struct connectdata *conn)
passed); passed);
return CURLE_READ_ERROR; return CURLE_READ_ERROR;
} }
} while(passed != data->resume_from); /* loop until done */ } while(passed != conn->resume_from); /* loop until done */
/* now, decrease the size of the read */ /* now, decrease the size of the read */
if(data->infilesize>0) { if(data->infilesize>0) {
data->infilesize -= data->resume_from; data->infilesize -= conn->resume_from;
if(data->infilesize <= 0) { if(data->infilesize <= 0) {
failf(data, "File already completely uploaded\n"); failf(data, "File already completely uploaded\n");
@@ -547,7 +551,7 @@ CURLcode Curl_http(struct connectdata *conn)
/* we've passed, proceed as normal */ /* we've passed, proceed as normal */
} }
} }
if(data->bits.set_range) { if(conn->bits.use_range) {
/* /*
* A range is selected. We use different headers whether we're downloading * A range is selected. We use different headers whether we're downloading
* or uploading and we always let customized headers override our internal * or uploading and we always let customized headers override our internal
@@ -555,23 +559,23 @@ CURLcode Curl_http(struct connectdata *conn)
*/ */
if((data->httpreq == HTTPREQ_GET) && if((data->httpreq == HTTPREQ_GET) &&
!checkheaders(data, "Range:")) { !checkheaders(data, "Range:")) {
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->range); conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", conn->range);
} }
else if((data->httpreq != HTTPREQ_GET) && else if((data->httpreq != HTTPREQ_GET) &&
!checkheaders(data, "Content-Range:")) { !checkheaders(data, "Content-Range:")) {
if(data->resume_from) { if(conn->resume_from) {
/* This is because "resume" was selected */ /* This is because "resume" was selected */
long total_expected_size= data->resume_from + data->infilesize; long total_expected_size= conn->resume_from + data->infilesize;
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n", conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
data->range, total_expected_size-1, conn->range, total_expected_size-1,
total_expected_size); total_expected_size);
} }
else { else {
/* Range was selected and then we just pass the incoming range and /* Range was selected and then we just pass the incoming range and
append total size */ append total size */
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n", conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
data->range, data->infilesize); conn->range, data->infilesize);
} }
} }
} }
@@ -602,10 +606,14 @@ CURLcode Curl_http(struct connectdata *conn)
(data->bits.http_post || data->bits.http_formpost)?"POST": (data->bits.http_post || data->bits.http_formpost)?"POST":
(data->bits.http_put)?"PUT":"GET"), (data->bits.http_put)?"PUT":"GET"),
ppath, ppath,
(data->bits.proxy_user_passwd && conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"", (conn->bits.proxy_user_passwd &&
(data->bits.user_passwd && conn->allocptr.userpwd)?conn->allocptr.userpwd:"", conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
(data->bits.set_range && conn->allocptr.rangeline)?conn->allocptr.rangeline:"", (conn->bits.user_passwd && conn->allocptr.userpwd)?
(data->useragent && *data->useragent && conn->allocptr.uagent)?conn->allocptr.uagent:"", conn->allocptr.userpwd:"",
(conn->bits.use_range && conn->allocptr.rangeline)?
conn->allocptr.rangeline:"",
(data->useragent && *data->useragent && conn->allocptr.uagent)?
conn->allocptr.uagent:"",
(conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */ (conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
http->p_pragma?http->p_pragma:"", http->p_pragma?http->p_pragma:"",
@@ -638,12 +646,21 @@ CURLcode Curl_http(struct connectdata *conn)
if(data->timecondition) { if(data->timecondition) {
struct tm *thistime; struct tm *thistime;
/* Phil Karn (Fri, 13 Apr 2001) pointed out that the If-Modified-Since
* header family should have their times set in GMT as RFC2616 defines:
* "All HTTP date/time stamps MUST be represented in Greenwich Mean Time
* (GMT), without exception. For the purposes of HTTP, GMT is exactly
* equal to UTC (Coordinated Universal Time)." (see page 20 of RFC2616).
*/
#ifdef HAVE_LOCALTIME_R #ifdef HAVE_LOCALTIME_R
/* thread-safe version */ /* thread-safe version */
/* We assume that the presense of localtime_r() proves the presense
of gmtime_r() which is a bit ugly but might work */
struct tm keeptime; struct tm keeptime;
thistime = (struct tm *)localtime_r(&data->timevalue, &keeptime); thistime = (struct tm *)gmtime_r(&data->timevalue, &keeptime);
#else #else
thistime = localtime(&data->timevalue); thistime = gmtime(&data->timevalue);
#endif #endif
if(NULL == thistime) { if(NULL == thistime) {
failf(data, "localtime() failed!"); failf(data, "localtime() failed!");

View File

@@ -115,10 +115,15 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
ch->hexindex++; ch->hexindex++;
} }
else { else {
return 1; /* longer hex than we support */ return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */
} }
} }
else { else {
if(0 == ch->hexindex) {
/* This is illegal data, we received junk where we expected
a hexadecimal digit. */
return CHUNKE_ILLEGAL_HEX;
}
/* length and datap are unmodified */ /* length and datap are unmodified */
ch->hexbuffer[ch->hexindex]=0; ch->hexbuffer[ch->hexindex]=0;
ch->datasize=strtoul(ch->hexbuffer, NULL, 16); ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
@@ -127,7 +132,9 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break; break;
case CHUNK_POSTHEX: case CHUNK_POSTHEX:
/* just a lame state waiting for CRLF to arrive */ /* In this state, we're waiting for CRLF to arrive. We support
this to allow so called chunk-extensions to show up here
before the CRLF comes. */
if(*datap == '\r') if(*datap == '\r')
ch->state = CHUNK_CR; ch->state = CHUNK_CR;
length--; length--;
@@ -174,10 +181,34 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
length -= piece; /* decrease space left in this round */ length -= piece; /* decrease space left in this round */
if(0 == ch->datasize) if(0 == ch->datasize)
/* end of data this round, go back to get a new size */ /* end of data this round, we now expect a trailing CRLF */
Curl_httpchunk_init(conn); ch->state = CHUNK_POSTCR;
break; break;
case CHUNK_POSTCR:
if(*datap == '\r') {
ch->state = CHUNK_POSTLF;
datap++;
length--;
}
else
return CHUNKE_BAD_CHUNK;
break;
case CHUNK_POSTLF:
if(*datap == '\n') {
/*
* The last one before we go back to hex state and start all
* over.
*/
Curl_httpchunk_init(conn);
datap++;
length--;
}
else
return CHUNKE_BAD_CHUNK;
break;
case CHUNK_STOP: case CHUNK_STOP:
/* If we arrive here, there is data left in the end of the buffer /* If we arrive here, there is data left in the end of the buffer
even if there's no more chunks to read */ even if there's no more chunks to read */

View File

@@ -24,13 +24,13 @@
*****************************************************************************/ *****************************************************************************/
/* /*
* The longest possible hexadecimal number we support in a chunked transfer. * The longest possible hexadecimal number we support in a chunked transfer.
* Weird enoug, RFC2616 doesn't set a maximum size! Since we use strtoul() * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
* to convert it, we "only" support 2^32 bytes chunk data. * to convert it, we "only" support 2^32 bytes chunk data.
*/ */
#define MAXNUM_SIZE 16 #define MAXNUM_SIZE 16
typedef enum { typedef enum {
CHUNK_LOST, /* never use */ CHUNK_FIRST, /* never use */
/* In this we await and buffer all hexadecimal digits until we get one /* In this we await and buffer all hexadecimal digits until we get one
that isn't a hexadecimal digit. When done, we go POSTHEX */ that isn't a hexadecimal digit. When done, we go POSTHEX */
@@ -45,10 +45,17 @@ typedef enum {
If the size given was zero, we set state to STOP and return. */ If the size given was zero, we set state to STOP and return. */
CHUNK_CR, CHUNK_CR,
/* We eat the amount of data specified. When done, we move back to the /* We eat the amount of data specified. When done, we move on to the
HEX state. */ POST_CR state. */
CHUNK_DATA, CHUNK_DATA,
/* POSTCR should get a CR and nothing else, then move to POSTLF */
CHUNK_POSTCR,
/* POSTLF should get a LF and nothing else, then move back to HEX as
the CRLF combination marks the end of a chunk */
CHUNK_POSTLF,
/* This is mainly used to really mark that we're out of the game. /* This is mainly used to really mark that we're out of the game.
NOTE: that there's a 'dataleft' field in the struct that will tell how NOTE: that there's a 'dataleft' field in the struct that will tell how
many bytes that were not passed to the client in the end of the last many bytes that were not passed to the client in the end of the last
@@ -62,6 +69,8 @@ typedef enum {
CHUNKE_STOP = -1, CHUNKE_STOP = -1,
CHUNKE_OK = 0, CHUNKE_OK = 0,
CHUNKE_TOO_LONG_HEX = 1, CHUNKE_TOO_LONG_HEX = 1,
CHUNKE_ILLEGAL_HEX,
CHUNKE_BAD_CHUNK,
CHUNKE_WRITE_ERROR, CHUNKE_WRITE_ERROR,
CHUNKE_STATE_ERROR, CHUNKE_STATE_ERROR,
CHUNKE_LAST CHUNKE_LAST

View File

@@ -70,6 +70,11 @@
#include "inet_ntoa_r.h" #include "inet_ntoa_r.h"
#endif #endif
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
#define SYS_ERROR -1 #define SYS_ERROR -1
char *Curl_if2ip(char *interface, char *buf, int buf_size) char *Curl_if2ip(char *interface, char *buf, int buf_size)
@@ -90,6 +95,7 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
strcpy(req.ifr_name, interface); strcpy(req.ifr_name, interface);
req.ifr_addr.sa_family = AF_INET; req.ifr_addr.sa_family = AF_INET;
if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) { if (SYS_ERROR == ioctl(dummy, SIOCGIFADDR, &req, sizeof(req))) {
sclose(dummy);
return NULL; return NULL;
} }
else { else {
@@ -104,7 +110,7 @@ char *Curl_if2ip(char *interface, char *buf, int buf_size)
ip[buf_size - 1] = 0; ip[buf_size - 1] = 0;
#endif #endif
} }
close(dummy); sclose(dummy);
} }
return ip; return ip;
} }

View File

@@ -2,41 +2,31 @@
; Definition file for the DLL version of the LIBCURL library from curl ; Definition file for the DLL version of the LIBCURL library from curl
; ;
LIBRARY CURL LIBRARY LIBCURL
DESCRIPTION 'curl libcurl - http://curl.haxx.se' DESCRIPTION 'curl libcurl - http://curl.haxx.se'
EXPORTS EXPORTS
curl_close @ 1 ; curl_easy_cleanup @ 1 ;
curl_connect @ 2 ; curl_easy_getinfo @ 2 ;
curl_disconnect @ 3 ; curl_easy_init @ 3 ;
curl_do @ 4 ; curl_easy_perform @ 4 ;
curl_done @ 5 ; curl_easy_setopt @ 5 ;
curl_easy_cleanup @ 6 ; curl_escape @ 6 ;
curl_easy_getinfo @ 7 ; curl_formparse @ 7 ;
curl_easy_init @ 8 ; curl_formfree @ 8 ;
curl_easy_perform @ 9 ; curl_getdate @ 9 ;
curl_easy_setopt @ 10 ; curl_getenv @ 10 ;
curl_escape @ 11 ; curl_slist_append @ 11 ;
curl_formparse @ 12 ; curl_slist_free_all @ 12 ;
curl_free @ 13 ; curl_unescape @ 13 ;
curl_getdate @ 14 ; curl_version @ 14 ;
curl_getenv @ 15 ; curl_maprintf @ 15 ;
curl_init @ 16 ; curl_mfprintf @ 16 ;
curl_open @ 17 ; curl_mprintf @ 17 ;
curl_read @ 18 ; curl_msprintf @ 18 ;
curl_setopt @ 19 ; curl_msnprintf @ 19 ;
curl_slist_append @ 20 ; curl_mvfprintf @ 20 ;
curl_slist_free_all @ 21 ; curl_strequal @ 21 ;
curl_transfer @ 22 ; curl_strnequal @ 22 ;
curl_unescape @ 23 ;
curl_version @ 24 ;
curl_write @ 25 ;
curl_maprintf @ 26 ;
curl_mfprintf @ 27 ;
curl_mprintf @ 28 ;
curl_msprintf @ 29 ;
curl_msnprintf @ 30 ;
curl_mvfprintf @ 31 ;
Curl_strequal @ 32 ;
Curl_strnequal @ 33 ;

View File

@@ -120,7 +120,7 @@ int curl_socket(int domain, int type, int protocol, int line, char *source)
return sockfd; return sockfd;
} }
int curl_accept(int s, struct sockaddr *addr, int *addrlen, int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen,
int line, char *source) int line, char *source)
{ {
int sockfd=(accept)(s, addr, addrlen); int sockfd=(accept)(s, addr, addrlen);

View File

@@ -13,7 +13,7 @@ void curl_memdebug(char *logname);
/* file descriptor manipulators */ /* file descriptor manipulators */
int curl_socket(int domain, int type, int protocol, int, char *); int curl_socket(int domain, int type, int protocol, int, char *);
int curl_sclose(int sockfd, int, char *); int curl_sclose(int sockfd, int, char *);
int curl_accept(int s, struct sockaddr *addr, int *addrlen, int curl_accept(int s, struct sockaddr *addr, socklen_t *addrlen,
int line, char *source); int line, char *source);
/* FILE functions */ /* FILE functions */

View File

@@ -27,10 +27,26 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <curl/curl.h> #include <curl/curl.h>
#include "strequal.h" #include "strequal.h"
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
/* Debug this single source file with: /* Debug this single source file with:
'make netrc' then run './netrc'! 'make netrc' then run './netrc'!
@@ -60,7 +76,7 @@ int Curl_parsenetrc(char *host,
char netrcbuffer[256]; char netrcbuffer[256];
int retcode=1; int retcode=1;
char *home = curl_getenv("HOME"); /* portable environment reader */ char *home = NULL;
int state=NOTHING; int state=NOTHING;
char state_login=0; char state_login=0;
@@ -68,11 +84,25 @@ int Curl_parsenetrc(char *host,
#define NETRC DOT_CHAR "netrc" #define NETRC DOT_CHAR "netrc"
if(!home) #if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
return -1; struct passwd *pw;
pw= getpwuid(geteuid());
if (pw)
home = pw->pw_dir;
#else
void *pw=NULL;
#endif
if(NULL == pw) {
home = curl_getenv("HOME"); /* portable environment reader */
if(!home) {
return -1;
}
}
if(strlen(home)>(sizeof(netrcbuffer)-strlen(NETRC))) { if(strlen(home)>(sizeof(netrcbuffer)-strlen(NETRC))) {
free(home); if(NULL==pw)
free(home);
return -1; return -1;
} }
@@ -140,7 +170,8 @@ int Curl_parsenetrc(char *host,
fclose(file); fclose(file);
} }
free(home); if(NULL==pw)
free(home);
return retcode; return retcode;
} }

View File

@@ -91,11 +91,12 @@ static char *max5data(double bytes, char *max5)
*/ */
void Curl_pgrsDone(struct UrlData *data) void Curl_pgrsDone(struct connectdata *conn)
{ {
struct UrlData *data = conn->data;
if(!(data->progress.flags & PGRS_HIDE)) { if(!(data->progress.flags & PGRS_HIDE)) {
data->progress.lastshow=0; data->progress.lastshow=0;
Curl_pgrsUpdate(data); /* the final (forced) update */ Curl_pgrsUpdate(conn); /* the final (forced) update */
fprintf(data->err, "\n"); fprintf(data->err, "\n");
} }
} }
@@ -134,6 +135,7 @@ void Curl_pgrsTime(struct UrlData *data, timerid timer)
void Curl_pgrsStartNow(struct UrlData *data) void Curl_pgrsStartNow(struct UrlData *data)
{ {
data->progress.speeder_c = 0; /* reset the progress meter display */
data->progress.start = Curl_tvnow(); data->progress.start = Curl_tvnow();
} }
@@ -171,7 +173,7 @@ void Curl_pgrsSetUploadSize(struct UrlData *data, double size)
*/ */
int Curl_pgrsUpdate(struct UrlData *data) int Curl_pgrsUpdate(struct connectdata *conn)
{ {
struct timeval now; struct timeval now;
int result; int result;
@@ -184,6 +186,8 @@ int Curl_pgrsUpdate(struct UrlData *data)
double total_transfer; double total_transfer;
double total_expected_transfer; double total_expected_transfer;
struct UrlData *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME; int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex; int checkindex;
int count; int count;
@@ -197,15 +201,16 @@ int Curl_pgrsUpdate(struct UrlData *data)
double total_estimate; double total_estimate;
if(data->progress.flags & PGRS_HIDE) if(data->progress.flags & PGRS_HIDE)
; /* We do enter this function even if we don't wanna see anything, since ; /* We do enter this function even if we don't wanna see anything, since
this is were lots of the calculations are being made that will be used this is were lots of the calculations are being made that will be used
even when not displayed! */ even when not displayed! */
else if(!(data->progress.flags & PGRS_HEADERS_OUT)) { else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
if (!data->progress.callback) { if (!data->progress.callback) {
if(data->resume_from) if(conn->resume_from)
fprintf(data->err, "** Resuming transfer from byte position %d\n", fprintf(data->err, "** Resuming transfer from byte position %d\n",
data->resume_from); conn->resume_from);
fprintf(data->err, fprintf(data->err,
" %% Total %% Received %% Xferd Average Speed Time Curr.\n" " %% Total %% Received %% Xferd Average Speed Time Curr.\n"
" Dload Upload Total Current Left Speed\n"); " Dload Upload Total Current Left Speed\n");

View File

@@ -36,13 +36,13 @@ typedef enum {
TIMER_LAST /* must be last */ TIMER_LAST /* must be last */
} timerid; } timerid;
void Curl_pgrsDone(struct UrlData *data); void Curl_pgrsDone(struct connectdata *);
void Curl_pgrsStartNow(struct UrlData *data); void Curl_pgrsStartNow(struct UrlData *data);
void Curl_pgrsSetDownloadSize(struct UrlData *data, double size); void Curl_pgrsSetDownloadSize(struct UrlData *data, double size);
void Curl_pgrsSetUploadSize(struct UrlData *data, double size); void Curl_pgrsSetUploadSize(struct UrlData *data, double size);
void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size); void Curl_pgrsSetDownloadCounter(struct UrlData *data, double size);
void Curl_pgrsSetUploadCounter(struct UrlData *data, double size); void Curl_pgrsSetUploadCounter(struct UrlData *data, double size);
int Curl_pgrsUpdate(struct UrlData *data); int Curl_pgrsUpdate(struct connectdata *);
void Curl_pgrsTime(struct UrlData *data, timerid timer); void Curl_pgrsTime(struct UrlData *data, timerid timer);

View File

@@ -120,7 +120,7 @@ void curl_slist_free_all(struct curl_slist *list)
} }
/* infof() is for info message along the way */ /* Curl_infof() is for info message along the way */
void Curl_infof(struct UrlData *data, char *fmt, ...) void Curl_infof(struct UrlData *data, char *fmt, ...)
{ {
@@ -133,7 +133,7 @@ void Curl_infof(struct UrlData *data, char *fmt, ...)
} }
} }
/* failf() is for messages stating why we failed, the LAST one will be /* Curl_failf() is for messages stating why we failed, the LAST one will be
returned for the user (if requested) */ returned for the user (if requested) */
void Curl_failf(struct UrlData *data, char *fmt, ...) void Curl_failf(struct UrlData *data, char *fmt, ...)
@@ -142,7 +142,7 @@ void Curl_failf(struct UrlData *data, char *fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
if(data->errorbuffer) if(data->errorbuffer)
vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap); vsnprintf(data->errorbuffer, CURL_ERROR_SIZE, fmt, ap);
else { else if(!data->bits.mute) {
/* no errorbuffer receives this, write to data->err instead */ /* no errorbuffer receives this, write to data->err instead */
vfprintf(data->err, fmt, ap); vfprintf(data->err, fmt, ap);
fprintf(data->err, "\n"); fprintf(data->err, "\n");
@@ -213,23 +213,6 @@ CURLcode Curl_write(struct connectdata *conn, int sockfd,
return CURLE_OK; return CURLE_OK;
} }
/*
* External write-function, writes to the data-socket.
* Takes care of plain sockets, SSL or kerberos transparently.
*/
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_write(conn, conn->sockfd, buf, amount, n);
}
/* client_write() sends data to the write callback(s) /* client_write() sends data to the write callback(s)
The bit pattern defines to what "streams" to write to. Body and/or header. The bit pattern defines to what "streams" to write to. Body and/or header.
@@ -253,7 +236,14 @@ CURLcode Curl_client_write(struct UrlData *data,
} }
} }
if((type & CLIENTWRITE_HEADER) && data->writeheader) { if((type & CLIENTWRITE_HEADER) && data->writeheader) {
wrote = data->fwrite(ptr, 1, len, data->writeheader); /*
* Write headers to the same callback or to the especially setup
* header callback function (added after version 7.7.1).
*/
curl_write_callback writeit=
data->fwrite_header?data->fwrite_header:data->fwrite;
wrote = writeit(ptr, 1, len, data->writeheader);
if(wrote != len) { if(wrote != len) {
failf (data, "Failed writing header"); failf (data, "Failed writing header");
return CURLE_WRITE_ERROR; return CURLE_WRITE_ERROR;
@@ -299,19 +289,3 @@ CURLcode Curl_read(struct connectdata *conn, int sockfd,
return CURLE_OK; return CURLE_OK;
} }
/*
* The public read function reads from the 'sockfd' file descriptor only.
* Use the Curl_read() internally when you want to specify fd.
*/
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
ssize_t *n)
{
struct connectdata *conn = (struct connectdata *)c_conn;
if(!n || !conn || (conn->handle != STRUCT_CONNECT))
return CURLE_FAILED_INIT;
return Curl_read(conn, conn->sockfd, buf, buffersize, n);
}

View File

@@ -24,6 +24,7 @@
#include "setup.h" #include "setup.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#if defined(__MINGW32__) #if defined(__MINGW32__)
#include <winsock.h> #include <winsock.h>
#endif #endif

View File

@@ -37,6 +37,11 @@
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
#include <openssl/rand.h> #include <openssl/rand.h>
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
static char global_passwd[64]; static char global_passwd[64];
static int passwd_callback(char *buf, int num, int verify static int passwd_callback(char *buf, int num, int verify
@@ -80,34 +85,39 @@ int random_the_seed(struct connectdata *conn)
{ {
char *buf = conn->data->buffer; /* point to the big buffer */ char *buf = conn->data->buffer; /* point to the big buffer */
int nread=0; int nread=0;
struct UrlData *data=conn->data;
/* Q: should we add support for a random file name as a libcurl option? /* Q: should we add support for a random file name as a libcurl option?
A: Yes */ A: Yes, it is here */
#if 0
/* something like this */ #ifndef RANDOM_FILE
nread += RAND_load_file(filename, number_of_bytes); /* if RANDOM_FILE isn't defined, we only perform this if an option tells
us to! */
if(data->ssl.random_file)
#define RANDOM_FILE "" /* doesn't matter won't be used */
#endif #endif
/* generates a default path for the random seed file */ {
buf[0]=0; /* blank it first */ /* let the option override the define */
RAND_file_name(buf, BUFSIZE); nread += RAND_load_file((data->ssl.random_file?
if ( buf[0] ) { data->ssl.random_file:RANDOM_FILE),
/* we got a file name to try */ 16384);
nread += RAND_load_file(buf, 16384);
if(seed_enough(conn, nread)) if(seed_enough(conn, nread))
return nread; return nread;
} }
#ifdef RANDOM_FILE #if defined(HAVE_RAND_EGD)
nread += RAND_load_file(RANDOM_FILE, 16384);
if(seed_enough(conn, nread))
return nread;
#endif
#if defined(HAVE_RAND_EGD) && defined(EGD_SOCKET)
/* only available in OpenSSL 0.9.5 and later */ /* only available in OpenSSL 0.9.5 and later */
/* EGD_SOCKET is set at configure time */ /* EGD_SOCKET is set at configure time or not at all */
#ifndef EGD_SOCKET
/* If we don't have the define set, we only do this if the egd-option
is set */
if(data->ssl.egdsocket)
#define EGD_SOCKET "" /* doesn't matter won't be used */
#endif
{ {
int ret = RAND_egd(EGD_SOCKET); /* If there's an option and a define, the option overrides the
define */
int ret = RAND_egd(data->ssl.egdsocket?data->ssl.egdsocket:EGD_SOCKET);
if(-1 != ret) { if(-1 != ret) {
nread += ret; nread += ret;
if(seed_enough(conn, nread)) if(seed_enough(conn, nread))
@@ -133,7 +143,17 @@ int random_the_seed(struct connectdata *conn)
RAND_seed(area, len); RAND_seed(area, len);
free(area); /* now remove the random junk */ free(area); /* now remove the random junk */
}
#endif #endif
/* generates a default path for the random seed file */
buf[0]=0; /* blank it first */
RAND_file_name(buf, BUFSIZE);
if ( buf[0] ) {
/* we got a file name to try */
nread += RAND_load_file(buf, 16384);
if(seed_enough(conn, nread))
return nread;
} }
infof(conn->data, "Your connection is using a weak random seed!\n"); infof(conn->data, "Your connection is using a weak random seed!\n");
@@ -343,7 +363,7 @@ Curl_SSLConnect(struct connectdata *conn)
X509_free(conn->ssl.server_cert); X509_free(conn->ssl.server_cert);
#else /* USE_SSLEAY */ #else /* USE_SSLEAY */
/* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */
(void) data; (void) conn;
#endif #endif
return 0; return 0;
} }

View File

@@ -25,7 +25,7 @@
#include <string.h> #include <string.h>
int Curl_strequal(const char *first, const char *second) int curl_strequal(const char *first, const char *second)
{ {
#if defined(HAVE_STRCASECMP) #if defined(HAVE_STRCASECMP)
return !strcasecmp(first, second); return !strcasecmp(first, second);
@@ -45,7 +45,7 @@ int Curl_strequal(const char *first, const char *second)
#endif #endif
} }
int Curl_strnequal(const char *first, const char *second, size_t max) int curl_strnequal(const char *first, const char *second, size_t max)
{ {
#if defined(HAVE_STRCASECMP) #if defined(HAVE_STRCASECMP)
return !strncasecmp(first, second, max); return !strncasecmp(first, second, max);

View File

@@ -22,10 +22,18 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
int Curl_strequal(const char *first, const char *second);
int Curl_strnequal(const char *first, const char *second, size_t max);
#define strequal(a,b) Curl_strequal(a,b) /*
#define strnequal(a,b,c) Curl_strnequal(a,b,c) * These two actually are public functions.
*/
int curl_strequal(const char *first, const char *second);
int curl_strnequal(const char *first, const char *second, size_t max);
#define strequal(a,b) curl_strequal(a,b)
#define strnequal(a,b,c) curl_strnequal(a,b,c)
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#endif #endif

View File

@@ -82,6 +82,11 @@
#include "arpa_telnet.h" #include "arpa_telnet.h"
/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif
#define SUBBUFSIZE 512 #define SUBBUFSIZE 512
#define SB_CLEAR(x) x->subpointer = x->subbuffer; #define SB_CLEAR(x) x->subpointer = x->subbuffer;
@@ -745,7 +750,7 @@ static int check_telnet_options(struct connectdata *conn)
/* Add the user name as an environment variable if it /* Add the user name as an environment variable if it
was given on the command line */ was given on the command line */
if(data->bits.user_passwd) if(conn->bits.user_passwd)
{ {
char *buf = malloc(256); char *buf = malloc(256);
sprintf(buf, "USER,%s", data->user); sprintf(buf, "USER,%s", data->user);

View File

@@ -53,7 +53,7 @@ gettimeofday (struct timeval *tp, void *nothing)
#endif #endif
#endif #endif
struct timeval Curl_tvnow () struct timeval Curl_tvnow (void)
{ {
struct timeval now; struct timeval now;
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY

View File

@@ -107,7 +107,7 @@
<butlerm@xmission.com>. */ <butlerm@xmission.com>. */
CURLcode static CURLcode static
_Transfer(struct connectdata *c_conn) Transfer(struct connectdata *c_conn)
{ {
ssize_t nread; /* number of bytes read */ ssize_t nread; /* number of bytes read */
int bytecount = 0; /* total number of bytes read */ int bytecount = 0; /* total number of bytes read */
@@ -127,7 +127,7 @@ _Transfer(struct connectdata *c_conn)
bool content_range = FALSE; /* set TRUE if Content-Range: was found */ bool content_range = FALSE; /* set TRUE if Content-Range: was found */
int offset = 0; /* possible resume offset read from the int offset = 0; /* possible resume offset read from the
Content-Range: header */ Content-Range: header */
int code = 0; /* error code from the 'HTTP/1.? XXX' line */ int httpcode = 0; /* error code from the 'HTTP/1.? XXX' line */
int httpversion = -1; /* the last digit in the HTTP/1.1 string */ int httpversion = -1; /* the last digit in the HTTP/1.1 string */
/* for the low speed checks: */ /* for the low speed checks: */
@@ -142,9 +142,6 @@ _Transfer(struct connectdata *c_conn)
char *buf; char *buf;
int maxfd; int maxfd;
if(!conn || (conn->handle != STRUCT_CONNECT))
return CURLE_BAD_FUNCTION_ARGUMENT;
data = conn->data; /* there's the root struct */ data = conn->data; /* there's the root struct */
buf = data->buffer; buf = data->buffer;
maxfd = (conn->sockfd>conn->writesockfd?conn->sockfd:conn->writesockfd)+1; maxfd = (conn->sockfd>conn->writesockfd?conn->sockfd:conn->writesockfd)+1;
@@ -184,7 +181,7 @@ _Transfer(struct connectdata *c_conn)
int keepon=0; int keepon=0;
/* timeout every X second /* timeout every X second
- makes a better progressmeter (i.e even when no data is read, the - makes a better progress meter (i.e even when no data is read, the
meter can be updated and reflect reality) meter can be updated and reflect reality)
- allows removal of the alarm() crap - allows removal of the alarm() crap
- variable timeout is easier - variable timeout is easier
@@ -313,8 +310,11 @@ _Transfer(struct connectdata *c_conn)
/* we now have a full line that p points to */ /* we now have a full line that p points to */
if (('\n' == *p) || ('\r' == *p)) { if (('\n' == *p) || ('\r' == *p)) {
/* Zero-length line means end of header! */ /* Zero-length line means end of header! */
#if 0
if (-1 != conn->size) /* if known */ if (-1 != conn->size) /* if known */
conn->size += bytecount; /* we append the already read size */ conn->size += bytecount; /* we append the already read
size */
#endif
if ('\r' == *p) if ('\r' == *p)
@@ -324,7 +324,20 @@ _Transfer(struct connectdata *c_conn)
#if 0 /* headers are not included in the size */ #if 0 /* headers are not included in the size */
Curl_pgrsSetDownloadSize(data, conn->size); Curl_pgrsSetDownloadSize(data, conn->size);
#endif #endif
header = FALSE; /* no more header to parse! */
if(100 == httpcode) {
/*
* we have made a HTTP PUT or POST and this is 1.1-lingo
* that tells us that the server is OK with this and ready
* to receive our stuff.
* However, we'll get more headers now so we must get
* back into the header-parsing state!
*/
header = TRUE;
headerline = 0; /* we restart the header line counter */
}
else
header = FALSE; /* no more header to parse! */
/* now, only output this if the header AND body are requested: /* now, only output this if the header AND body are requested:
*/ */
@@ -339,29 +352,53 @@ _Transfer(struct connectdata *c_conn)
data->header_size += p - data->headerbuff; data->header_size += p - data->headerbuff;
if(!header) {
/*
* end-of-headers.
*
* If we requested a "no body", this is a good time to get
* out and return home.
*/
if(data->bits.no_body)
return CURLE_OK;
/* if(!conn->bits.close) {
* end-of-headers. /* If this is not the last request before a close, we must
* set the maximum download size to the size of the
* If we requested a "no body" and this isn't a "close" expected document or else, we won't know when to stop
* connection, this is a good time to get out and return reading! */
* home. if(-1 != conn->size)
*/ conn->maxdownload = conn->size;
if(!conn->bits.close && data->bits.no_body)
return CURLE_OK;
break; /* exit header line loop */ /* If max download size is *zero* (nothing) we already
have nothing and can safely return ok now! */
if(0 == conn->maxdownload)
return CURLE_OK;
/* What to do if the size is *not* known? */
}
break; /* exit header line loop */
}
/* We continue reading headers, so reset the line-based
header parsing variables hbufp && hbuflen */
hbufp = data->headerbuff;
hbuflen = 0;
continue;
} }
if (!headerline++) { if (!headerline++) {
/* This is the first header, it MUST be the error code line /* This is the first header, it MUST be the error code line
or else we consiser this to be the body right away! */ or else we consiser this to be the body right away! */
if (2 == sscanf (p, " HTTP/1.%d %3d", &httpversion, &code)) { if (2 == sscanf (p, " HTTP/1.%d %3d", &httpversion,
&httpcode)) {
/* 404 -> URL not found! */ /* 404 -> URL not found! */
if ( if (
( ((data->bits.http_follow_location) && (code >= 400)) ( ((data->bits.http_follow_location) &&
(httpcode >= 400))
|| ||
(!data->bits.http_follow_location && (code >= 300))) (!data->bits.http_follow_location &&
(httpcode >= 300)))
&& (data->bits.http_fail_on_error)) { && (data->bits.http_fail_on_error)) {
/* If we have been told to fail hard on HTTP-errors, /* If we have been told to fail hard on HTTP-errors,
here is the check for that: */ here is the check for that: */
@@ -369,7 +406,23 @@ _Transfer(struct connectdata *c_conn)
failf (data, "The requested file was not found"); failf (data, "The requested file was not found");
return CURLE_HTTP_NOT_FOUND; return CURLE_HTTP_NOT_FOUND;
} }
data->progress.httpcode = code; data->progress.httpcode = httpcode;
data->progress.httpversion = httpversion;
if(httpversion == 0)
/* Default action for HTTP/1.0 must be to close, unless
we get one of those fancy headers that tell us the
server keeps it open for us! */
conn->bits.close = TRUE;
if (httpcode == 304)
/* (quote from RFC2616, section 10.3.5):
* The 304 response MUST NOT contain a
* message-body, and thus is always
* terminated by the first empty line
* after the header fields.
*/
conn->size=0;
} }
else { else {
header = FALSE; /* this is not a header line */ header = FALSE; /* this is not a header line */
@@ -382,6 +435,31 @@ _Transfer(struct connectdata *c_conn)
conn->size = contentlength; conn->size = contentlength;
Curl_pgrsSetDownloadSize(data, contentlength); Curl_pgrsSetDownloadSize(data, contentlength);
} }
else if((httpversion == 0) &&
conn->bits.httpproxy &&
strnequal("Proxy-Connection: keep-alive", p,
strlen("Proxy-Connection: keep-alive"))) {
/*
* When a HTTP/1.0 reply comes when using a proxy, the
* 'Proxy-Connection: keep-alive' line tells us the
* connection will be kept alive for our pleasure.
* Default action for 1.0 is to close.
*/
conn->bits.close = FALSE; /* don't close when done */
infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
}
else if((httpversion == 0) &&
strnequal("Connection: keep-alive", p,
strlen("Connection: keep-alive"))) {
/*
* A HTTP/1.0 reply with the 'Connection: keep-alive' line
* tells us the connection will be kept alive for our
* pleasure. Default action for 1.0 is to close.
*
* [RFC2068, section 19.7.1] */
conn->bits.close = FALSE; /* don't close when done */
infof(data, "HTTP/1.0 connection set to keep alive!\n");
}
else if (strnequal("Connection: close", p, else if (strnequal("Connection: close", p,
strlen("Connection: close"))) { strlen("Connection: close"))) {
/* /*
@@ -413,7 +491,7 @@ _Transfer(struct connectdata *c_conn)
/* This second format was added August 1st 2000 by Igor /* This second format was added August 1st 2000 by Igor
Khristophorov since Sun's webserver JavaWebServer/1.1.1 Khristophorov since Sun's webserver JavaWebServer/1.1.1
obviously sends the header this way! :-( */ obviously sends the header this way! :-( */
if (data->resume_from == offset) { if (conn->resume_from == offset) {
/* we asked for a resume and we got it */ /* we asked for a resume and we got it */
content_range = TRUE; content_range = TRUE;
} }
@@ -431,7 +509,7 @@ _Transfer(struct connectdata *c_conn)
if(data->bits.get_filetime) if(data->bits.get_filetime)
data->progress.filetime = timeofdoc; data->progress.filetime = timeofdoc;
} }
else if ((code >= 300 && code < 400) && else if ((httpcode >= 300 && httpcode < 400) &&
(data->bits.http_follow_location) && (data->bits.http_follow_location) &&
strnequal("Location: ", p, 10)) { strnequal("Location: ", p, 10)) {
/* this is the URL that the server advices us to get instead */ /* this is the URL that the server advices us to get instead */
@@ -446,7 +524,7 @@ _Transfer(struct connectdata *c_conn)
ptr++; ptr++;
backup = *ptr; /* store the ending letter */ backup = *ptr; /* store the ending letter */
*ptr = '\0'; /* zero terminate */ *ptr = '\0'; /* zero terminate */
data->newurl = strdup(start); /* clone string */ conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */ *ptr = backup; /* restore ending letter */
} }
@@ -490,12 +568,12 @@ _Transfer(struct connectdata *c_conn)
write a piece of the body */ write a piece of the body */
if(conn->protocol&PROT_HTTP) { if(conn->protocol&PROT_HTTP) {
/* HTTP-only checks */ /* HTTP-only checks */
if (data->newurl) { if (conn->newurl) {
/* abort after the headers if "follow Location" is set */ /* abort after the headers if "follow Location" is set */
infof (data, "Follow to new URL: %s\n", data->newurl); infof (data, "Follow to new URL: %s\n", conn->newurl);
return CURLE_OK; return CURLE_OK;
} }
else if (data->resume_from && else if (conn->resume_from &&
!content_range && !content_range &&
(data->httpreq==HTTPREQ_GET)) { (data->httpreq==HTTPREQ_GET)) {
/* we wanted to resume a download, although the server /* we wanted to resume a download, although the server
@@ -505,7 +583,7 @@ _Transfer(struct connectdata *c_conn)
"byte ranges. Cannot resume."); "byte ranges. Cannot resume.");
return CURLE_HTTP_RANGE_ERROR; return CURLE_HTTP_RANGE_ERROR;
} }
else if(data->timecondition && !data->range) { else if(data->timecondition && !conn->range) {
/* A time condition has been set AND no ranges have been /* A time condition has been set AND no ranges have been
requested. This seems to be what chapter 13.3.4 of requested. This seems to be what chapter 13.3.4 of
RFC 2616 defines to be the correct action for a RFC 2616 defines to be the correct action for a
@@ -530,15 +608,6 @@ _Transfer(struct connectdata *c_conn)
} /* switch */ } /* switch */
} /* two valid time strings */ } /* two valid time strings */
} /* we have a time condition */ } /* we have a time condition */
if(!conn->bits.close && (httpversion == 1)) {
/* If this is not the last request before a close, we must
set the maximum download size to the size of the expected
document or else, we won't know when to stop reading! */
if(-1 != conn->size)
conn->maxdownload = conn->size;
/* What to do if the size is *not* known? */
}
} /* this is HTTP */ } /* this is HTTP */
} /* this is the first time we write a body part */ } /* this is the first time we write a body part */
@@ -554,20 +623,22 @@ _Transfer(struct connectdata *c_conn)
CHUNKcode res = CHUNKcode res =
Curl_httpchunk_read(conn, str, nread, &nread); Curl_httpchunk_read(conn, str, nread, &nread);
if(CHUNKE_OK < res) if(CHUNKE_OK < res) {
failf(data, "Receeived problem in the chunky parser");
return CURLE_READ_ERROR; return CURLE_READ_ERROR;
}
else if(CHUNKE_STOP == res) { else if(CHUNKE_STOP == res) {
/* we're done reading chunks! */ /* we're done reading chunks! */
keepon &= ~KEEP_READ; /* read no more */ keepon &= ~KEEP_READ; /* read no more */
/* There are now possibly bytes at the end of the str buffer /* There are now possibly N number of bytes at the end of the
that weren't written to the client, but we don't care str buffer that weren't written to the client, but we don't
about them right now. */ care about them right now. */
} }
/* If it returned OK, we just keep going */ /* If it returned OK, we just keep going */
} }
if(conn->maxdownload && if((-1 != conn->maxdownload) &&
(bytecount + nread >= conn->maxdownload)) { (bytecount + nread >= conn->maxdownload)) {
nread = conn->maxdownload - bytecount; nread = conn->maxdownload - bytecount;
if((signed int)nread < 0 ) /* this should be unusual */ if((signed int)nread < 0 ) /* this should be unusual */
@@ -579,7 +650,7 @@ _Transfer(struct connectdata *c_conn)
Curl_pgrsSetDownloadCounter(data, (double)bytecount); Curl_pgrsSetDownloadCounter(data, (double)bytecount);
if(! conn->bits.chunk) { if(!conn->bits.chunk && nread) {
/* If this is chunky transfer, it was already written */ /* If this is chunky transfer, it was already written */
urg = Curl_client_write(data, CLIENTWRITE_BODY, str, nread); urg = Curl_client_write(data, CLIENTWRITE_BODY, str, nread);
if(urg) if(urg)
@@ -641,7 +712,7 @@ _Transfer(struct connectdata *c_conn)
} }
now = Curl_tvnow(); now = Curl_tvnow();
if(Curl_pgrsUpdate(data)) if(Curl_pgrsUpdate(conn))
urg = CURLE_ABORTED_BY_CALLBACK; urg = CURLE_ABORTED_BY_CALLBACK;
else else
urg = Curl_speedcheck (data, now); urg = Curl_speedcheck (data, now);
@@ -670,7 +741,12 @@ _Transfer(struct connectdata *c_conn)
contentlength-bytecount); contentlength-bytecount);
return CURLE_PARTIAL_FILE; return CURLE_PARTIAL_FILE;
} }
if(Curl_pgrsUpdate(data)) else if(conn->bits.chunk && conn->proto.http->chunk.datasize) {
failf(data, "transfer closed with at least %d bytes remaining",
conn->proto.http->chunk.datasize);
return CURLE_PARTIAL_FILE;
}
if(Curl_pgrsUpdate(conn))
return CURLE_ABORTED_BY_CALLBACK; return CURLE_ABORTED_BY_CALLBACK;
if(conn->bytecountp) if(conn->bytecountp)
@@ -681,27 +757,47 @@ _Transfer(struct connectdata *c_conn)
return CURLE_OK; return CURLE_OK;
} }
CURLcode curl_transfer(CURL *curl) CURLcode Curl_perform(CURL *curl)
{ {
CURLcode res; CURLcode res;
struct UrlData *data = curl; struct UrlData *data = (struct UrlData *)curl;
struct connectdata *c_connect=NULL; struct connectdata *conn=NULL;
bool port=TRUE; /* allow data->use_port to set port to use */ bool port=TRUE; /* allow data->use_port to set port to use */
char *newurl = NULL; /* possibly a new URL to follow to! */
if(!data->url)
/* we can't do anything wihout URL */
return CURLE_URL_MALFORMAT;
data->followlocation=0; /* reset the location-follow counter */
data->bits.this_is_a_follow = FALSE; /* reset this */
Curl_pgrsStartNow(data); Curl_pgrsStartNow(data);
do { do {
Curl_pgrsTime(data, TIMER_STARTSINGLE); Curl_pgrsTime(data, TIMER_STARTSINGLE);
res = curl_connect(curl, (CURLconnect **)&c_connect, port); res = Curl_connect(data, &conn, port);
if(res == CURLE_OK) { if(res == CURLE_OK) {
res = curl_do(c_connect); res = Curl_do(conn);
if(res == CURLE_OK) { if(res == CURLE_OK) {
res = _Transfer(c_connect); /* now fetch that URL please */ res = Transfer(conn); /* now fetch that URL please */
if(res == CURLE_OK) if(res == CURLE_OK) {
res = curl_done(c_connect); /*
* We must duplicate the new URL here as the connection data
* may be free()ed in the Curl_done() function.
*/
newurl = conn->newurl?strdup(conn->newurl):NULL;
res = Curl_done(conn);
}
} }
if((res == CURLE_OK) && data->newurl) { /*
* Important: 'conn' cannot be used here, since it may have been closed
* in 'Curl_done' or other functions.
*/
if((res == CURLE_OK) && newurl) {
/* Location: redirect /* Location: redirect
This is assumed to happen for HTTP(S) only! This is assumed to happen for HTTP(S) only!
@@ -714,9 +810,6 @@ CURLcode curl_transfer(CURL *curl)
if (data->maxredirs && (data->followlocation >= data->maxredirs)) { if (data->maxredirs && (data->followlocation >= data->maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->maxredirs); failf(data,"Maximum (%d) redirects followed", data->maxredirs);
#ifdef USE_OLD_DISCONNECT
curl_disconnect(c_connect);
#endif
res=CURLE_TOO_MANY_REDIRECTS; res=CURLE_TOO_MANY_REDIRECTS;
break; break;
} }
@@ -741,7 +834,7 @@ CURLcode curl_transfer(CURL *curl)
data->bits.http_set_referer = TRUE; /* might have been false */ data->bits.http_set_referer = TRUE; /* might have been false */
} }
if(2 != sscanf(data->newurl, "%15[^:]://%c", prot, &letter)) { if(2 != sscanf(newurl, "%15[^:]://%c", prot, &letter)) {
/*** /***
*DANG* this is an RFC 2068 violation. The URL is supposed *DANG* this is an RFC 2068 violation. The URL is supposed
to be absolute and this doesn't seem to be that! to be absolute and this doesn't seem to be that!
@@ -754,19 +847,21 @@ CURLcode curl_transfer(CURL *curl)
char *pathsep; char *pathsep;
char *newest; char *newest;
/* we must make our own copy of the URL to play with, as it may
point to read-only data */
char *url_clone=strdup(data->url);
if(!url_clone)
return CURLE_OUT_OF_MEMORY;
/* protsep points to the start of the host name */ /* protsep points to the start of the host name */
protsep=strstr(data->url, "//"); protsep=strstr(url_clone, "//");
if(!protsep) if(!protsep)
protsep=data->url; protsep=url_clone;
else { else
port=FALSE; /* we got a full URL and thus we should not obey the
port number that might have been set by the user
in data->use_port */
protsep+=2; /* pass the slashes */ protsep+=2; /* pass the slashes */
}
if('/' != data->newurl[0]) { if('/' != newurl[0]) {
/* First we need to find out if there's a ?-letter in the URL, /* First we need to find out if there's a ?-letter in the URL,
and cut it and the right-side of that off */ and cut it and the right-side of that off */
pathsep = strrchr(protsep, '?'); pathsep = strrchr(protsep, '?');
@@ -787,16 +882,17 @@ CURLcode curl_transfer(CURL *curl)
*pathsep=0; *pathsep=0;
} }
newest=(char *)malloc( strlen(data->url) + newest=(char *)malloc( strlen(url_clone) +
1 + /* possible slash */ 1 + /* possible slash */
strlen(data->newurl) + 1/* zero byte */); strlen(newurl) + 1/* zero byte */);
if(!newest) if(!newest)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
sprintf(newest, "%s%s%s", data->url, ('/' == data->newurl[0])?"":"/", sprintf(newest, "%s%s%s", url_clone, ('/' == newurl[0])?"":"/",
data->newurl); newurl);
free(data->newurl); free(newurl);
data->newurl = newest; free(url_clone);
newurl = newest;
} }
else { else {
/* This is an absolute URL, don't use the custom port number */ /* This is an absolute URL, don't use the custom port number */
@@ -807,8 +903,8 @@ CURLcode curl_transfer(CURL *curl)
free(data->url); free(data->url);
/* TBD: set the URL with curl_setopt() */ /* TBD: set the URL with curl_setopt() */
data->url = data->newurl; data->url = newurl;
data->newurl = NULL; /* don't show! */
data->bits.urlstringalloc = TRUE; /* the URL is allocated */ data->bits.urlstringalloc = TRUE; /* the URL is allocated */
infof(data, "Follows Location: to new URL: '%s'\n", data->url); infof(data, "Follows Location: to new URL: '%s'\n", data->url);
@@ -822,7 +918,6 @@ CURLcode curl_transfer(CURL *curl)
switch(data->progress.httpcode) { switch(data->progress.httpcode) {
case 300: /* Multiple Choices */ case 300: /* Multiple Choices */
case 301: /* Moved Permanently */ case 301: /* Moved Permanently */
case 302: /* Found */
case 306: /* Not used */ case 306: /* Not used */
case 307: /* Temporary Redirect */ case 307: /* Temporary Redirect */
default: /* for all unknown ones */ default: /* for all unknown ones */
@@ -830,6 +925,24 @@ CURLcode curl_transfer(CURL *curl)
* seem to be OK to POST to. * seem to be OK to POST to.
*/ */
break; break;
case 302: /* Found */
/* (From 10.3.3)
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
(From 10.3.4)
Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303.
*/
case 303: /* See Other */ case 303: /* See Other */
/* Disable both types of POSTs, since doing a second POST when /* Disable both types of POSTs, since doing a second POST when
* following isn't what anyone would want! */ * following isn't what anyone would want! */
@@ -853,22 +966,19 @@ CURLcode curl_transfer(CURL *curl)
*/ */
break; break;
} }
#ifdef USE_OLD_DISCONNECT
curl_disconnect(c_connect);
#endif
continue; continue;
} }
#ifdef USE_OLD_DISCONNECT
curl_disconnect(c_connect);
#endif
} }
break; /* it only reaches here when this shouldn't loop */ break; /* it only reaches here when this shouldn't loop */
} while(1); /* loop if Location: */ } while(1); /* loop if Location: */
if(data->newurl) if(newurl)
free(data->newurl); free(newurl);
/* make sure the alarm is switched off! */
if(data->timeout || data->connecttimeout)
myalarm(0);
return res; return res;
} }

View File

@@ -22,8 +22,9 @@
* *
* $Id$ * $Id$
*****************************************************************************/ *****************************************************************************/
CURLcode curl_transfer(CURL *curl); CURLcode Curl_perform(CURL *curl);
/* This sets up a forthcoming transfer */
CURLcode CURLcode
Curl_Transfer (struct connectdata *data, Curl_Transfer (struct connectdata *data,
int sockfd, /* socket to read from or -1 */ int sockfd, /* socket to read from or -1 */

889
lib/url.c

File diff suppressed because it is too large Load Diff

View File

@@ -98,27 +98,6 @@
#define MAX(x,y) ((x)>(y)?(x):(y)) #define MAX(x,y) ((x)>(y)?(x):(y))
#endif #endif
/* Type of handle. All publicly returned 'handles' in the curl interface
have a handle first in the struct that describes what kind of handle it
is. Used to detect bad handle usage. */
typedef enum {
STRUCT_NONE,
STRUCT_OPEN,
STRUCT_CONNECT,
STRUCT_LAST
} Handle;
/* Connecting to a remote server using the curl interface is moving through
a state machine, this type is used to store the current state */
typedef enum {
CONN_NONE, /* illegal state */
CONN_INIT, /* curl_connect() has been called */
CONN_DO, /* curl_do() has been called successfully */
CONN_DONE, /* curl_done() has been called successfully */
CONN_ERROR, /* and error has occurred */
CONN_LAST /* illegal state */
} ConnState;
#ifdef KRB4 #ifdef KRB4
/* Types needed for krb4-ftp connections */ /* Types needed for krb4-ftp connections */
struct krb4buffer { struct krb4buffer {
@@ -152,6 +131,8 @@ struct ssl_config_data {
long verifypeer; /* set TRUE if this is desired */ long verifypeer; /* set TRUE if this is desired */
char *CApath; /* DOES NOT WORK ON WINDOWS */ char *CApath; /* DOES NOT WORK ON WINDOWS */
char *CAfile; /* cerficate to verify peer against */ char *CAfile; /* cerficate to verify peer against */
char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */
}; };
/**************************************************************************** /****************************************************************************
@@ -201,6 +182,12 @@ struct ConnectBits {
bool close; /* if set, we close the connection after this request */ bool close; /* if set, we close the connection after this request */
bool reuse; /* if set, this is a re-used connection */ bool reuse; /* if set, this is a re-used connection */
bool chunk; /* if set, this is a chunked transfer-encoding */ bool chunk; /* if set, this is a chunked transfer-encoding */
bool httpproxy; /* if set, this transfer is done through a http proxy */
bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */
bool use_range;
bool rangestringalloc; /* the range string is malloc()'ed */
}; };
/* /*
@@ -209,18 +196,10 @@ struct ConnectBits {
*/ */
struct connectdata { struct connectdata {
/**** Fields set when inited and not modified again */ /**** Fields set when inited and not modified again */
/* To better see what kind of struct that is passed as input, *ALL* publicly
returned handles MUST have this initial 'Handle'. */
Handle handle; /* struct identifier */
struct UrlData *data; /* link to the root CURL struct */ struct UrlData *data; /* link to the root CURL struct */
int connectindex; /* what index in the connects index this particular int connectindex; /* what index in the connects index this particular
struct has */ struct has */
/**** curl_connect() phase fields */
ConnState state; /* for state dependent actions */
long protocol; /* PROT_* flags concerning the protocol set */ long protocol; /* PROT_* flags concerning the protocol set */
#define PROT_MISSING (1<<0) #define PROT_MISSING (1<<0)
#define PROT_GOPHER (1<<1) #define PROT_GOPHER (1<<1)
@@ -231,6 +210,7 @@ struct connectdata {
#define PROT_DICT (1<<6) #define PROT_DICT (1<<6)
#define PROT_LDAP (1<<7) #define PROT_LDAP (1<<7)
#define PROT_FILE (1<<8) #define PROT_FILE (1<<8)
#define PROT_FTPS (1<<9)
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
struct addrinfo *hp; /* host info pointer list */ struct addrinfo *hp; /* host info pointer list */
@@ -250,7 +230,15 @@ struct connectdata {
not the proxy port! */ not the proxy port! */
char *ppath; char *ppath;
long bytecount; long bytecount;
struct timeval now; /* current time */
char *range; /* range, if used. See README for detailed specification on
this syntax. */
int resume_from; /* continue [ftp] transfer from here */
char *proxyhost; /* name of the http proxy host */
struct timeval now; /* "current" time */
struct timeval created; /* creation time */
int firstsocket; /* the main socket to use */ int firstsocket; /* the main socket to use */
int secondarysocket; /* for i.e ftp transfers */ int secondarysocket; /* for i.e ftp transfers */
@@ -309,8 +297,10 @@ struct connectdata {
char *host; /* free later if not NULL */ char *host; /* free later if not NULL */
} allocptr; } allocptr;
#ifdef KRB4 char *newurl; /* This can only be set if a Location: was in the
document headers */
#ifdef KRB4
enum protection_level command_prot; enum protection_level command_prot;
enum protection_level data_prot; enum protection_level data_prot;
enum protection_level request_data_prot; enum protection_level request_data_prot;
@@ -366,6 +356,7 @@ struct Progress {
double t_connect; double t_connect;
double t_pretransfer; double t_pretransfer;
int httpcode; int httpcode;
int httpversion;
time_t filetime; /* If requested, this is might get set. It may be 0 if time_t filetime; /* If requested, this is might get set. It may be 0 if
the time was unretrievable */ the time was unretrievable */
@@ -409,28 +400,21 @@ struct Configbits {
bool httpproxy; bool httpproxy;
bool mute; bool mute;
bool no_body; bool no_body;
bool proxy_user_passwd;
bool set_port; bool set_port;
bool set_range; bool set_range;
bool upload; bool upload;
bool use_netrc; bool use_netrc;
bool user_passwd;
bool verbose; bool verbose;
bool this_is_a_follow; /* this is a followed Location: request */ bool this_is_a_follow; /* this is a followed Location: request */
bool krb4; /* kerberos4 connection requested */ bool krb4; /* kerberos4 connection requested */
bool proxystringalloc; /* the http proxy string is malloc()'ed */ bool proxystringalloc; /* the http proxy string is malloc()'ed */
bool rangestringalloc; /* the range string is malloc()'ed */
bool urlstringalloc; /* the URL string is malloc()'ed */ bool urlstringalloc; /* the URL string is malloc()'ed */
bool reuse_forbid; /* if this is forbidden to be reused, close
after use */
bool reuse_fresh; /* do not re-use an existing connection for this
transfer */
}; };
/* What type of interface that intiated this struct */
typedef enum {
CURLI_NONE,
CURLI_EASY,
CURLI_NORMAL,
CURLI_LAST
} CurlInterface;
/* /*
* As of April 11, 2000 we're now trying to split up the urldata struct in * As of April 11, 2000 we're now trying to split up the urldata struct in
* three different parts: * three different parts:
@@ -457,9 +441,6 @@ typedef enum {
*/ */
struct UrlData { struct UrlData {
Handle handle; /* struct identifier */
CurlInterface interf; /* created by WHAT interface? */
/*************** Global - specific items ************/ /*************** Global - specific items ************/
FILE *err; /* the stderr writes goes here */ FILE *err; /* the stderr writes goes here */
char *errorbuffer; /* store failure messages in here */ char *errorbuffer; /* store failure messages in here */
@@ -475,9 +456,10 @@ struct UrlData {
long header_size; /* size of read header(s) in bytes */ long header_size; /* size of read header(s) in bytes */
long request_size; /* the amount of bytes sent in the request(s) */ long request_size; /* the amount of bytes sent in the request(s) */
FILE *out; /* the fetched file goes here */ void *out; /* the fetched file goes here */
FILE *in; /* the uploaded file is read from here */ void *in; /* the uploaded file is read from here */
FILE *writeheader; /* write the header to this is non-NULL */ void *writeheader; /* write the header to this is non-NULL */
char *url; /* what to get */ char *url; /* what to get */
char *freethis; /* if non-NULL, an allocated string for the URL */ char *freethis; /* if non-NULL, an allocated string for the URL */
long use_port; /* which port to use (when not using default) */ long use_port; /* which port to use (when not using default) */
@@ -485,8 +467,8 @@ struct UrlData {
struct ssl_config_data ssl; /* this is for ssl-stuff */ struct ssl_config_data ssl; /* this is for ssl-stuff */
char *userpwd; /* <user:password>, if used */ char *userpwd; /* <user:password>, if used */
char *range; /* range, if used. See README for detailed specification on char *set_range; /* range, if used. See README for detailed specification on
this syntax. */ this syntax. */
/* stuff related to HTTP */ /* stuff related to HTTP */
@@ -510,6 +492,9 @@ struct UrlData {
/* function that stores the output:*/ /* function that stores the output:*/
curl_write_callback fwrite; curl_write_callback fwrite;
/* optional function that stores the header output:*/
curl_write_callback fwrite_header;
/* function that reads the input:*/ /* function that reads the input:*/
curl_read_callback fread; curl_read_callback fread;
@@ -521,8 +506,9 @@ struct UrlData {
curl_passwd_callback fpasswd; curl_passwd_callback fpasswd;
void *passwd_client; /* pointer to pass to the passwd callback */ void *passwd_client; /* pointer to pass to the passwd callback */
long timeout; /* in seconds, 0 means no timeout */ long timeout; /* in seconds, 0 means no timeout */
long infilesize; /* size of file to upload, -1 means unknown */ long connecttimeout; /* in seconds, 0 means no timeout */
long infilesize; /* size of file to upload, -1 means unknown */
char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */ char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
@@ -531,13 +517,10 @@ struct UrlData {
long low_speed_limit; /* bytes/second */ long low_speed_limit; /* bytes/second */
long low_speed_time; /* number of seconds */ long low_speed_time; /* number of seconds */
int resume_from; /* continue [ftp] transfer from here */ int set_resume_from; /* continue [ftp] transfer from here */
char *cookie; /* HTTP cookie string to send */ char *cookie; /* HTTP cookie string to send */
char *newurl; /* This can only be set if a Location: was in the
document headers */
struct curl_slist *headers; /* linked list of extra headers */ struct curl_slist *headers; /* linked list of extra headers */
struct HttpPost *httppost; /* linked list of POST data */ struct HttpPost *httppost; /* linked list of POST data */
@@ -580,10 +563,6 @@ struct UrlData {
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
char *krb4_level; /* what security level */ char *krb4_level; /* what security level */
#ifdef KRB4
FILE *cmdchannel;
#endif
struct timeval keeps_speed; /* this should be request-specific */ struct timeval keeps_speed; /* this should be request-specific */
/* 'connects' will be an allocated array with pointers. If the pointer is /* 'connects' will be an allocated array with pointers. If the pointer is
@@ -597,191 +576,26 @@ struct UrlData {
#define LIBCURL_NAME "libcurl" #define LIBCURL_NAME "libcurl"
#define LIBCURL_ID LIBCURL_NAME " " LIBCURL_VERSION " " SSL_ID #define LIBCURL_ID LIBCURL_NAME " " LIBCURL_VERSION " " SSL_ID
CURLcode Curl_getinfo(CURL *curl, CURLINFO info, ...);
/* /*
* Here follows function prototypes from what we used to plan to call * Here follows function prototypes from what we used to plan to call
* the "low level" interface. It is no longer prioritized and it is not likely * the "low level" interface. It is no longer prioritized and it is not likely
* to ever be supported to external users. * to ever be supported to external users.
*
* I removed all the comments to them as well, as they were no longer accurate
* and they're not meant for "public use" anymore.
*/ */
/* CURLcode Curl_open(CURL **curl, char *url);
* NAME curl_init() CURLcode Curl_setopt(CURL *handle, CURLoption option, ...);
* CURLcode Curl_close(CURL *curl); /* the opposite of curl_open() */
* DESCRIPTION CURLcode Curl_connect(struct UrlData *,
* struct connectdata **,
* Inits libcurl globally. This must be used before any libcurl calls can
* be used. This may install global plug-ins or whatever. (This does not
* do winsock inits in Windows.)
*
* EXAMPLE
*
* curl_init();
*
*/
CURLcode curl_init(void);
/*
* NAME curl_init()
*
* DESCRIPTION
*
* Frees libcurl globally. This must be used after all libcurl calls have
* been used. This may remove global plug-ins or whatever. (This does not
* do winsock cleanups in Windows.)
*
* EXAMPLE
*
* curl_free(curl);
*
*/
void curl_free(void);
/*
* NAME curl_open()
*
* DESCRIPTION
*
* Opens a general curl session. It does not try to connect or do anything
* on the network because of this call. The specified URL is only required
* to enable curl to figure out what protocol to "activate".
*
* A session should be looked upon as a series of requests to a single host. A
* session interacts with one host only, using one single protocol.
*
* The URL is not required. If set to "" or NULL, it can still be set later
* using the curl_setopt() function. If the curl_connect() function is called
* without the URL being known, it will return error.
*
* EXAMPLE
*
* CURLcode result;
* CURL *curl;
* result = curl_open(&curl, "http://curl.haxx.nu/libcurl/");
* if(result != CURL_OK) {
* return result;
* }
* */
CURLcode curl_open(CURL **curl, char *url);
/*
* NAME curl_setopt()
*
* DESCRIPTION
*
* Sets a particular option to the specified value.
*
* EXAMPLE
*
* CURL curl;
* curl_setopt(curl, CURL_HTTP_FOLLOW_LOCATION, TRUE);
*/
CURLcode curl_setopt(CURL *handle, CURLoption option, ...);
/*
* NAME curl_close()
*
* DESCRIPTION
*
* Closes a session previously opened with curl_open()
*
* EXAMPLE
*
* CURL *curl;
* CURLcode result;
*
* result = curl_close(curl);
*/
CURLcode curl_close(CURL *curl); /* the opposite of curl_open() */
CURLcode curl_read(CURLconnect *c_conn, char *buf, size_t buffersize,
ssize_t *n);
CURLcode curl_write(CURLconnect *c_conn, char *buf, size_t amount,
size_t *n);
/*
* NAME curl_connect()
*
* DESCRIPTION
*
* Connects to the peer server and performs the initial setup. This function
* writes a connect handle to its second argument that is a unique handle for
* this connect. This allows multiple connects from the same handle returned
* by curl_open().
*
* By setting 'allow_port' to FALSE, the data->use_port will *NOT* be
* respected.
*
* EXAMPLE
*
* CURLCode result;
* CURL curl;
* CURLconnect connect;
* result = curl_connect(curl, &connect); */
CURLcode curl_connect(CURL *curl,
CURLconnect **in_connect,
bool allow_port); bool allow_port);
CURLcode Curl_do(struct connectdata *);
/* CURLcode Curl_done(struct connectdata *);
* NAME curl_do() CURLcode Curl_disconnect(struct connectdata *);
*
* DESCRIPTION
*
* (Note: May 3rd 2000: this function does not currently allow you to
* specify a document, it will use the one set previously)
*
* This function asks for the particular document, file or resource that
* resides on the server we have connected to. You may specify a full URL,
* just an absolute path or even a relative path. That means, if you're just
* getting one file from the remote site, you can use the same URL as input
* for both curl_open() as well as for this function.
*
* In the even there is a host name, port number, user name or password parts
* in the URL, you can use the 'flags' argument to ignore them completely, or
* at your choice, make the function fail if you're trying to get a URL from
* different host than you connected to with curl_connect().
*
* You can only get one document at a time using the same connection. When one
* document has been received you can although request again.
*
* When the transfer is done, curl_done() MUST be called.
*
* EXAMPLE
*
* CURLCode result;
* char *url;
* CURLconnect *connect;
* result = curl_do(connect, url, CURL_DO_NONE); */
CURLcode curl_do(CURLconnect *in_conn);
/*
* NAME curl_done()
*
* DESCRIPTION
*
* When the transfer following a curl_do() call is done, this function should
* get called.
*
* EXAMPLE
*
* CURLCode result;
* char *url;
* CURLconnect *connect;
* result = curl_done(connect); */
CURLcode curl_done(CURLconnect *connect);
/*
* NAME curl_disconnect()
*
* DESCRIPTION
*
* Disconnects from the peer server and performs connection cleanup.
*
* EXAMPLE
*
* CURLcode result;
* CURLconnect *connect;
* result = curl_disconnect(connect); */
CURLcode curl_disconnect(CURLconnect *connect);
#endif #endif

View File

@@ -38,6 +38,24 @@ char *curl_version(void)
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
#if (SSLEAY_VERSION_NUMBER >= 0x906000)
{
char sub[2];
sub[1]='\0';
if(SSLEAY_VERSION_NUMBER&0xff0) {
sub[0]=((SSLEAY_VERSION_NUMBER>>4)&0xff) + 'a' -1;
}
else
sub[0]='\0';
sprintf(ptr, " (OpenSSL %lx.%lx.%lx%s)",
(SSLEAY_VERSION_NUMBER>>28)&0xf,
(SSLEAY_VERSION_NUMBER>>20)&0xff,
(SSLEAY_VERSION_NUMBER>>12)&0xff,
sub);
}
#else
#if (SSLEAY_VERSION_NUMBER >= 0x900000) #if (SSLEAY_VERSION_NUMBER >= 0x900000)
sprintf(ptr, " (SSL %lx.%lx.%lx)", sprintf(ptr, " (SSL %lx.%lx.%lx)",
(SSLEAY_VERSION_NUMBER>>28)&0xff, (SSLEAY_VERSION_NUMBER>>28)&0xff,
@@ -46,17 +64,19 @@ char *curl_version(void)
#else #else
{ {
char sub[2]; char sub[2];
sub[1]='\0';
if(SSLEAY_VERSION_NUMBER&0x0f) { if(SSLEAY_VERSION_NUMBER&0x0f) {
sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1; sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1;
} }
else else
sub[0]=0; sub[0]='\0';
sprintf(ptr, " (SSL %x.%x.%x%s)", sprintf(ptr, " (SSL %x.%x.%x%s)",
(SSLEAY_VERSION_NUMBER>>12)&0xff, (SSLEAY_VERSION_NUMBER>>12)&0xff,
(SSLEAY_VERSION_NUMBER>>8)&0xf, (SSLEAY_VERSION_NUMBER>>8)&0xf,
(SSLEAY_VERSION_NUMBER>>4)&0xf, sub); (SSLEAY_VERSION_NUMBER>>4)&0xf, sub);
} }
#endif
#endif #endif
ptr=strchr(ptr, '\0'); ptr=strchr(ptr, '\0');
#endif #endif

View File

@@ -12,12 +12,21 @@ do {
} }
} while (shift @ARGV); } while (shift @ARGV);
my $maxmem;
sub newtotal {
my ($newtot)=@_;
# count a max here
if($newtot > $maxmem) {
$maxmem= $newtot;
}
}
while(<STDIN>) { while(<STDIN>) {
chomp $_; chomp $_;
$line = $_; $line = $_;
if($verbose) {
print "IN: $line\n";
}
if($line =~ /^MEM ([^:]*):(\d*) (.*)/) { if($line =~ /^MEM ([^:]*):(\d*) (.*)/) {
# generic match for the filename+linenumber # generic match for the filename+linenumber
$source = $1; $source = $1;
@@ -34,17 +43,39 @@ while(<STDIN>) {
print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n"; print "FREE ERROR: Previously freed at: ".$getmem{$addr}."\n";
} }
else { else {
if(0 && $verbose) {
print "malloc at ".$getmem{$addr}." is freed again at $source:$linenum\n";
}
$totalmem -= $sizeataddr{$addr}; $totalmem -= $sizeataddr{$addr};
newtotal($totalmem);
$frees++;
$sizeataddr{$addr}=-1; # set -1 to mark as freed $sizeataddr{$addr}=-1; # set -1 to mark as freed
$getmem{$addr}="$source:$linenum"; $getmem{$addr}="$source:$linenum";
} }
} }
elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) { elsif($function =~ /malloc\((\d*)\) = 0x([0-9a-f]*)/) {
$size = $1; $size = $1;
$addr = $2; $addr = $2;
if($sizeataddr{$addr}>0) {
# this means weeeeeirdo
print "Fucked up debug compile, rebuild curl now\n";
}
$sizeataddr{$addr}=$size; $sizeataddr{$addr}=$size;
$totalmem += $size; $totalmem += $size;
if(0 && $verbose) {
print "malloc($size) at $source:$linenum\n";
}
newtotal($totalmem);
$mallocs++;
$getmem{$addr}="$source:$linenum"; $getmem{$addr}="$source:$linenum";
} }
elsif($function =~ /realloc\(0x([0-9a-f]*), (\d*)\) = 0x([0-9a-f]*)/) { elsif($function =~ /realloc\(0x([0-9a-f]*), (\d*)\) = 0x([0-9a-f]*)/) {
@@ -58,6 +89,9 @@ while(<STDIN>) {
$totalmem += $newsize; $totalmem += $newsize;
$sizeataddr{$newaddr}=$newsize; $sizeataddr{$newaddr}=$newsize;
newtotal($totalmem);
$reallocs++;
$getmem{$oldaddr}=""; $getmem{$oldaddr}="";
$getmem{$newaddr}="$source:$linenum"; $getmem{$newaddr}="$source:$linenum";
} }
@@ -71,6 +105,9 @@ while(<STDIN>) {
$sizeataddr{$addr}=$size; $sizeataddr{$addr}=$size;
$totalmem += $size; $totalmem += $size;
newtotal($totalmem);
$strdups++;
} }
else { else {
print "Not recognized input line: $function\n"; print "Not recognized input line: $function\n";
@@ -134,9 +171,6 @@ while(<STDIN>) {
else { else {
print "Not recognized prefix line: $line\n"; print "Not recognized prefix line: $line\n";
} }
if($verbose) {
print "TOTAL: $totalmem\n";
}
} }
if($totalmem) { if($totalmem) {
@@ -168,3 +202,12 @@ if($fopens) {
} }
} }
} }
if($verbose) {
print "Mallocs: $mallocs\n",
"Reallocs: $reallocs\n",
"Strdups: $strdups\n",
"Frees: $frees\n";
print "Maximum allocated: $maxmem\n";
}

View File

@@ -1 +1,3 @@
SUBDIRS = Win32 Linux SUBDIRS = Win32 Linux
EXTRA_DIST = README

76
perl/Curl_easy/Changes Normal file
View File

@@ -0,0 +1,76 @@
Revision history for Perl extension Curl::easy.
Check out the file README for more info.
1.1.5 Fri Apr 20 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Add latest CURLOPT_ and CURLINFO_ constants to the constants list
1.1.4 Fri Apr 20 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Fix case where curl_slists such as 'HTTPHEADERS' need to
be re-set over persistant requests
1.1.3 Wed Apr 18 2001: - Cris Bailiff <c.bailiff@devsecure.com>
- Change/shorten module function names: Curl::easy::curl_easy_setopt
becomes Curl::easy::setopt etc. This requires minor changes to existing
scripts....
- Added callback function support to pass arbitrary SV * (including
FILE globs) from perl through libcurl to the perl callback.
- Make callbacks still work with existing scripts which use STDIO
- Initial support for libcurl 7.7.2 HEADERFUNCTION callback feature
- Minor API cleanups/changes in the callback function signatures
- Added Curl::easy::version function to return curl version string
- Callback documentation added in easy.pm
- More tests in test.pl
1.1.2 Mon Apr 16 2001: - Georg Horn <horn@koblenz-net.de>
- Added support for callback functions. This is for the curl_easy_setopt()
options WRITEFUNCTION, READFUNCTION, PROGRESSFUNCTION and PASSWDFUNCTION.
Still missing, but not really neccessary: Passing a FILE * pointer,
that is passed in from libcurl, on to the perl callback function.
- Various cleanups, fixes and enhancements to easy.xs and test.pl.
1.1.1 Thu Apr 12 2001:
- Made more options of curl_easy_setopt() work: Options that require
a list of curl_slist structs to be passed in, like CURLOPT_HTTPHEADER,
are now working by passing a perl array containing the list elements.
As always, look at the test script test.pl for an example.
1.1.0 Wed Apr 11 2001:
- tested against libcurl 7.7
- Added new function Curl::easy::internal_setopt(). By calling
Curl::easy::internal_setopt(Curl::easy::USE_INTERNAL_VARS, 1);
the headers and content of the fetched page are no longer stored
into files (or written to stdout) but are stored into internal
Variables $Curl::easy::headers and $Curl::easy::content.
1.0.2 Tue Oct 10 2000:
- runs with libcurl 7.4
- modified curl_easy_getinfo(). It now calls curl_getinfo() that has
been added to libcurl in version 7.4.
1.0.1 Tue Oct 10 2000:
- Added some missing features of curl_easy_setopt():
- CURLOPT_ERRORBUFFER now works by passing the name of a perl
variable that shall be crated and the errormessage (if any)
be stored to.
- Passing filehandles (Options FILE, INFILE and WRITEHEADER) now works.
Have a look at test.pl to see how it works...
- Added a new function, curl_easy_getinfo(), that for now always
returns the number of bytes that where written to disk during the last
download. If the curl_easy_getinfo() function is included in libcurl,
(as promised by Daniel ;-)) i will turn this into just a call to this
function.
1.0 Thu Oct 5 2000:
- first released version
- runs with libcurl 7.3
- some features of curl_easy_setopt() are still missing:
- passing function pointers doesn't work (options WRITEFUNCTION,
READFUNCTION and PROGRESSFUNCTION).
- passing FILE * pointers doesn't work (options FILE, INFILE and
WRITEHEADER).
- passing linked lists doesn't work (options HTTPHEADER and
HTTPPOST).
- setting the buffer where to store error messages in doesn't work
(option ERRORBUFFER).

7
perl/Curl_easy/MANIFEST Normal file
View File

@@ -0,0 +1,7 @@
Changes
MANIFEST
Makefile.PL
README
easy.pm
easy.xs
test.pl

View File

@@ -0,0 +1,14 @@
# Makefile.PL for Perl extension Curl::easy.
# Check out the file README for more info.
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'Curl::easy',
'VERSION_FROM' => 'easy.pm', # finds $VERSION
'LIBS' => ['-lcurl '], # e.g., '-lm'
'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
'INC' => '', # e.g., '-I/usr/include/other'
'clean' => {FILES => "head.out body.out"}
);

View File

@@ -0,0 +1 @@
EXTRA_DIST = Changes easy.pm easy.xs Makefile.PL MANIFEST README test.pl

27
perl/Curl_easy/README Normal file
View File

@@ -0,0 +1,27 @@
README for Perl extension Curl::easy.
The perl module Curl::easy provides an interface to the cURL library "libcurl".
See http://curl.haxx.se/ for more information on cURL and libcurl.
This module requires libcurl and the corresponding headerfiles to be
installed. You then may install this module via the usual way:
perl Makefile.PL
make
make test
make install
The module provides the same functionality as libcurl provides to C programs,
please refer to the documentation of libcurl. Some examples may be found in
test.pl.
This software is distributed AS IS, WITHOUT WARRANTY OF ANY KIND, either
express or implied. Send praise, patches, money, beer and pizza to the author.
Send complaints to /dev/null. ;-)
The author of this software is Georg Horn <horn@koblenz-net.de>
Parts of the callback support have been added by Cris Bailiff
<c.bailiff@awayweb.com> and Forrest Cahoon <forrest.cahoon@merrillcorp.com>
The latest version can be downloaded from http://koblenz-net.de/~horn/export/

264
perl/Curl_easy/easy.pm Normal file
View File

@@ -0,0 +1,264 @@
# Perl interface for libcurl. Check out the file README for more info.
package Curl::easy;
use strict;
use Carp;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
require Exporter;
require DynaLoader;
require AutoLoader;
@ISA = qw(Exporter DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
CURLOPT_AUTOREFERER
CURLOPT_COOKIE
CURLOPT_COOKIEFILE
CURLOPT_CRLF
CURLOPT_CUSTOMREQUEST
CURLOPT_ERRORBUFFER
CURLOPT_FAILONERROR
CURLOPT_FILE
CURLOPT_FOLLOWLOCATION
CURLOPT_FTPAPPEND
CURLOPT_FTPASCII
CURLOPT_FTPLISTONLY
CURLOPT_FTPPORT
CURLOPT_HEADER
CURLOPT_HEADERFUNCTION
CURLOPT_HTTPHEADER
CURLOPT_HTTPPOST
CURLOPT_HTTPPROXYTUNNEL
CURLOPT_HTTPREQUEST
CURLOPT_INFILE
CURLOPT_INFILESIZE
CURLOPT_INTERFACE
CURLOPT_KRB4LEVEL
CURLOPT_LOW_SPEED_LIMIT
CURLOPT_LOW_SPEED_TIME
CURLOPT_MUTE
CURLOPT_NETRC
CURLOPT_NOBODY
CURLOPT_NOPROGRESS
CURLOPT_NOTHING
CURLOPT_PASSWDDATA
CURLOPT_PASSWDFUNCTION
CURLOPT_PORT
CURLOPT_POST
CURLOPT_POSTFIELDS
CURLOPT_POSTFIELDSIZE
CURLOPT_POSTQUOTE
CURLOPT_PROGRESSDATA
CURLOPT_PROGRESSFUNCTION
CURLOPT_PROXY
CURLOPT_PROXYPORT
CURLOPT_PROXYUSERPWD
CURLOPT_PUT
CURLOPT_QUOTE
CURLOPT_RANGE
CURLOPT_READFUNCTION
CURLOPT_REFERER
CURLOPT_RESUME_FROM
CURLOPT_SSLCERT
CURLOPT_SSLCERTPASSWD
CURLOPT_SSLVERSION
CURLOPT_STDERR
CURLOPT_TIMECONDITION
CURLOPT_TIMEOUT
CURLOPT_TIMEVALUE
CURLOPT_TRANSFERTEXT
CURLOPT_UPLOAD
CURLOPT_URL
CURLOPT_USERAGENT
CURLOPT_USERPWD
CURLOPT_VERBOSE
CURLOPT_WRITEFUNCTION
CURLOPT_WRITEHEADER
CURLOPT_MAXREDIRS
CURLOPT_FILETIME
CURLOPT_TELNETOPTIONS
CURLOPT_MAXCONNECTS
CURLOPT_CLOSEPOLICY
CURLOPT_CLOSEFUNCTION
CURLOPT_FRESH_CONNECT
CURLOPT_FORBID_REUSE
CURLOPT_RANDOM_FILE
CURLOPT_EGD_SOCKET
CURLOPT_CONNECTTIMEOUT
CURLINFO_EFFECTIVE_URL
CURLINFO_HTTP_CODE
CURLINFO_TOTAL_TIME
CURLINFO_NAMELOOKUP_TIME
CURLINFO_CONNECT_TIME
CURLINFO_PRETRANSFER_TIME
CURLINFO_SIZE_UPLOAD
CURLINFO_SIZE_DOWNLOAD
CURLINFO_SPEED_DOWNLOAD
CURLINFO_SPEED_UPLOAD
CURLINFO_HEADER_SIZE
CURLINFO_REQUEST_SIZE
CURLINFO_SSL_VERIFYRESULT
CURLINFO_FILETIME
CURLINFO_CONTENT_LENGTH_DOWNLOAD
CURLINFO_CONTENT_LENGTH_UPLOAD
USE_INTERNAL_VARS
);
$VERSION = '1.1.5';
$Curl::easy::headers = "";
$Curl::easy::content = "";
sub AUTOLOAD {
# This AUTOLOAD is used to 'autoload' constants from the constant()
# XS function.
(my $constname = $AUTOLOAD) =~ s/.*:://;
return constant($constname, 0);
}
bootstrap Curl::easy $VERSION;
# Preloaded methods go here.
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
Curl::easy - Perl extension for libcurl
=head1 SYNOPSIS
use Curl::easy;
$curl = Curl::easy::init();
$CURLcode = Curl::easy::setopt($curl, CURLoption, Value);
$CURLcode = Curl::easy::perform($curl);
Curl::easy::cleanup($curl);
=head1 DESCRIPTION
This perl module provides an interface to the libcurl C library. See
http://curl.haxx.se/ for more information on cURL and libcurl.
=head1 FILES and CALLBACKS
Curl::easy supports the various options of curl_easy_setopt which require either a FILE * or
a callback function.
The perl callback functions are handled through a C wrapper which takes care of converting
from C to perl variables and back again. This wrapper simplifies some C arguments to make
them behave in a more 'perl' like manner. In particular, the read and write callbacks do not
look just like the 'fread' and 'fwrite' C functions - perl variables do not need separate length
parameters, and perl functions can return a list of variables, instead of needing a pointer
to modify. The details are described below.
=head2 FILE handles (GLOBS)
Curl options which take a FILE, such as CURLOPT_FILE, CURLOPT_WRITEHEADER, CURLOPT_INFILE
can be passed a perl file handle:
open BODY,">body.out";
$CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, BODY);
=head2 WRITE callback
The CUROPT_WRITEFUNCTION option may be set which will cause libcurl to callback to
the given subroutine:
sub chunk { my ($data,$pointer)=@_; ...; return length($data) }
$CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&chunk );
$CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, );
In this case, the subroutine will be passed whatever is defined by CURLOPT_FILE. This can be
a ref to a scalar, or a GLOB or anything else you like.
The callback function must return the number of bytes 'handled' ( length($data) ) or the transfer
will abort. A transfer can be aborted by returning a 'length' of '-1'.
The option CURLOPT_WRITEHEADER can be set to pass a different '$pointer' into the CURLOPT_WRITEFUNCTION
for header values. This lets you collect the headers and body separately:
my $headers="";
my $body="";
sub chunk { my ($data,$pointer)=@_; ${$pointer}.=$data; return length($data) }
$CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&chunk );
$CURLcode = Curl::easy::setopt($curl, CURLOPT_WRITEHEADER, \$header );
$CURLcode = Curl::easy::setopt($curl, CURLOPT_FILE, \$body );
If you have libcurl > 7.7.1, then you could instead set CURLOPT_HEADERFUNCTION to a different callback,
and have the header collected that way.
=head2 READ callback
Curl::easy supports CURLOPT_READFUNCTION. This function should look something like this:
sub read_callback {
my ($maxlength,$pointer)=@_;
....
return $data;
}
The subroutine must return an empty string "" at the end of the data. Note that this function
isn't told how much data to provide - $maxlength is just the maximum size of the buffer
provided by libcurl. If you are doing an HTTP POST or PUT for example, it is important that this
function only returns as much data as the 'Content-Length' header specifies, followed by a
an empty (0 length) buffer.
=head2 PROGRESS callback
Curl::easy supports CURLOPT_PROGRESSFUNCTION. This function should look something like this:
sub prog_callb
{
my ($clientp,$dltotal,$dlnow,$ultotal,$ulnow)=@_;
....
return 0;
}
The function should return 0 normally, or -1 which will abort/cancel the transfer. $clientp is whatever
value/scalar is set using the CURLOPT_PROGRESSDATA option.
=head2 PASSWD callback
Curl::easy supports CURLOPT_PASSWDFUNCTION. This function should look something like this:
sub passwd_callb
{
my ($clientp,$prompt,$buflen)=@_;
...
return (0,$data);
}
$clientp is whatever scalar is set using the CURLOPT_PASSWDDATA option.
$prompt is a text string which can be used to prompt for a password.
$buflen is the maximum accepted password reply.
The function must return 0 (for 'OK') and the password data as a list. Return (-1,"") to
indicate an error.
=head1 AUTHOR
Georg Horn <horn@koblenz-net.de>
Additional callback,pod and tes work by Cris Bailiff <c.bailiff@devsecure.com>
and Forrest Cahoon <forrest.cahoon@merrillcorp.com>
=head1 SEE ALSO
http://curl.haxx.se/
=cut

773
perl/Curl_easy/easy.xs Normal file
View File

@@ -0,0 +1,773 @@
/* Perl interface for libcurl. Check out the file README for more info. */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <curl/curl.h>
#include <curl/easy.h>
#if (LIBCURL_VERSION_NUM<0x070702)
#define CURLOPT_HEADERFUNCTION 20079
#define header_callback_func write_callback_func
#else
#define header_callback_func writeheader_callback_func
#endif
/* Lists that can be set via curl_easy_setopt() */
static struct curl_slist *httpheader = NULL, *quote = NULL, *postquote = NULL;
/* Buffer and varname for option CURLOPT_ERRORBUFFER */
static char errbuf[CURL_ERROR_SIZE];
static char *errbufvarname = NULL;
/* Callback functions */
static SV *read_callback = NULL, *write_callback = NULL,
*progress_callback = NULL, *passwd_callback = NULL,
*header_callback = NULL;
/* *closepolicy_callback = NULL; */
/* For storing the content */
static char *contbuf = NULL, *bufptr = NULL;
static int bufsize = 32768, contlen = 0;
/* Internal options for this perl module */
#define USE_INTERNAL_VARS 0x01
static int internal_options = 0;
/* Setup these global vars */
static void init_globals(void)
{
if (httpheader) curl_slist_free_all(httpheader);
if (quote) curl_slist_free_all(quote);
if (postquote) curl_slist_free_all(postquote);
httpheader = quote = postquote = NULL;
if (errbufvarname) free(errbufvarname);
errbufvarname = NULL;
if (contbuf == NULL) {
contbuf = malloc(bufsize + 1);
}
bufptr = contbuf;
*bufptr = '\0';
contlen = 0;
internal_options = 0;
}
/* Register a callback function */
static void register_callback(SV **callback, SV *function)
{
if (*callback == NULL) {
/* First time, create new SV */
*callback = newSVsv(function);
} else {
/* Been there, done that. Just overwrite the SV */
SvSetSV(*callback, function);
}
}
/* generic fwrite callback, which decides which callback to call */
static size_t
fwrite_wrapper (const void *ptr,
size_t size,
size_t nmemb,
void *stream,
void *call_function)
{
dSP;
int count, status;
SV *sv;
if (call_function) {
/* then we are doing a callback to perl */
ENTER;
SAVETMPS;
PUSHMARK(SP);
if (stream == stdout) {
sv = newSViv(0); /* FIXME: should cast stdout to GLOB somehow? */
} else { /* its already an SV */
sv = stream;
}
if (ptr != NULL) {
XPUSHs(sv_2mortal(newSVpvn(ptr, size * nmemb)));
} else {
XPUSHs(sv_2mortal(newSVpv("", 0)));
}
XPUSHs(sv_2mortal(newSVsv(sv))); /* CURLOPT_FILE SV* */
PUTBACK;
count = perl_call_sv((SV *) call_function, G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Big trouble, perl_call_sv(write_callback) didn't return status\n");
status = POPi;
PUTBACK;
FREETMPS;
LEAVE;
return status;
} else {
/* default to a normal 'fwrite' */
/* stream could be a FILE * or an SV * */
FILE *f;
if (stream == stdout) { /* the only possible FILE ? Think so */
f = stream;
} else { /* its a GLOB */
f = IoIFP(sv_2io(stream)); /* may barf if not a GLOB */
}
return fwrite(ptr, size, nmemb, f);
}
}
/* Write callback for calling a perl callback */
size_t
write_callback_func( const void *ptr, size_t size,
size_t nmemb, void *stream)
{
return fwrite_wrapper(ptr,size,nmemb,stream,
write_callback);
}
/* header callback for calling a perl callback */
size_t
writeheader_callback_func( const void *ptr, size_t size,
size_t nmemb, void *stream)
{
return fwrite_wrapper(ptr,size,nmemb,stream,
header_callback);
}
size_t
read_callback_func( void *ptr, size_t size,
size_t nmemb, void *stream)
{
dSP ;
int count;
SV *sv;
STRLEN len;
size_t maxlen,mylen;
char *p;
maxlen = size*nmemb;
if (read_callback) {
/* we are doing a callback to perl */
ENTER ;
SAVETMPS ;
PUSHMARK(SP) ;
if (stream == stdin) {
sv = newSViv(0); /* should cast stdin to GLOB somehow? */
} else { /* its an SV */
sv = stream;
}
XPUSHs(sv_2mortal(newSViv(maxlen))); /* send how many bytes please */
XPUSHs(sv_2mortal(newSVsv(sv))); /* CURLOPT_INFILE SV* */
PUTBACK ;
count = perl_call_sv(read_callback, G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Big trouble, perl_call_sv(read_callback) didn't return data\n");
sv = POPs;
p = SvPV(sv,len);
/* only allowed to return the number of bytes asked for */
mylen = len<maxlen ? len : maxlen;
memcpy(ptr,p,(size_t)mylen);
PUTBACK ;
FREETMPS ;
LEAVE ;
return (size_t) (mylen/size);
} else {
/* default to a normal 'fread' */
/* stream could be a FILE * or an SV * */
FILE *f;
if (stream == stdin) { /* the only possible FILE ? Think so*/
f = stream;
} else { /* its a GLOB */
f = IoIFP(sv_2io(stream)); /* may barf if not a GLOB */
}
return fread(ptr,size,nmemb,f);
}
}
/* Porgress callback for calling a perl callback */
static int progress_callback_func(void *clientp, size_t dltotal, size_t dlnow,
size_t ultotal, size_t ulnow)
{
dSP;
int count;
ENTER;
SAVETMPS;
PUSHMARK(sp);
if (clientp != NULL) {
XPUSHs(sv_2mortal(newSVpv(clientp, 0)));
} else {
XPUSHs(sv_2mortal(newSVpv("", 0)));
}
XPUSHs(sv_2mortal(newSViv(dltotal)));
XPUSHs(sv_2mortal(newSViv(dlnow)));
XPUSHs(sv_2mortal(newSViv(ultotal)));
XPUSHs(sv_2mortal(newSViv(ulnow)));
PUTBACK;
count = perl_call_sv(progress_callback, G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Big trouble, perl_call_sv(progress_callback) didn't return 1\n");
count = POPi;
PUTBACK;
FREETMPS;
LEAVE;
return count;
}
/* Password callback for calling a perl callback */
static int passwd_callback_func(void *clientp, char *prompt, char *buffer,
int buflen)
{
dSP;
int count;
SV *sv;
STRLEN len;
size_t mylen;
char *p;
ENTER;
SAVETMPS;
PUSHMARK(sp);
if (clientp != NULL) {
XPUSHs(sv_2mortal(newSVsv(clientp)));
} else {
XPUSHs(sv_2mortal(newSVpv("", 0)));
}
XPUSHs(sv_2mortal(newSVpv(prompt, 0)));
XPUSHs(sv_2mortal(newSViv(buflen)));
PUTBACK;
count = perl_call_sv(passwd_callback, G_ARRAY);
SPAGAIN;
if (count != 2)
croak("Big trouble, perl_call_sv(passwd_callback) didn't return status + data\n");
sv = POPs;
count = POPi;
p = SvPV(sv,len);
/* only allowed to return the number of bytes asked for */
mylen = len<(buflen-1) ? len : (buflen-1);
memcpy(buffer,p,mylen);
buffer[buflen]=0; /* ensure C string terminates */
PUTBACK;
FREETMPS;
LEAVE;
return count;
}
#if 0
/* awaiting closepolicy prototype */
int
closepolicy_callback_func(void *clientp)
{
dSP;
int argc, status;
SV *pl_status;
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUTBACK;
argc = perl_call_sv(closepolicy_callback, G_SCALAR);
SPAGAIN;
if (argc != 1) {
croak("Unexpected number of arguments returned from closefunction callback\n");
}
pl_status = POPs;
status = SvTRUE(pl_status) ? 0 : 1;
PUTBACK;
FREETMPS;
LEAVE;
return status;
}
#endif
/* Internal write callback. Only used if USE_INTERNAL_VARS was specified */
static size_t internal_write_callback(char *data, size_t size, size_t num,
FILE *fp)
{
int i;
size *= num;
if ((contlen + size) >= bufsize) {
bufsize *= 2;
contbuf = realloc(contbuf, bufsize + 1);
bufptr = contbuf + contlen;
}
contlen += size;
for (i = 0; i < size; i++) {
*bufptr++ = *data++;
}
*bufptr = '\0';
return size;
}
static int
constant(char *name, int arg)
{
errno = 0;
if (strncmp(name, "CURLINFO_", 9) == 0) {
name += 9;
switch (*name) {
case 'A':
case 'B':
case 'C':
if (strEQ(name, "CONNECT_TIME")) return CURLINFO_CONNECT_TIME;
if (strEQ(name, "CONTENT_LENGTH_DOWNLOAD")) return CURLINFO_CONTENT_LENGTH_DOWNLOAD;
if (strEQ(name, "CONTENT_LENGTH_UPLOAD")) return CURLINFO_CONTENT_LENGTH_UPLOAD;
break;
case 'D':
case 'E':
if (strEQ(name, "EFFECTIVE_URL")) return CURLINFO_EFFECTIVE_URL;
break;
case 'F':
if (strEQ(name, "FILETIME")) return CURLINFO_FILETIME;
break;
case 'G':
case 'H':
if (strEQ(name, "HEADER_SIZE")) return CURLINFO_HEADER_SIZE;
if (strEQ(name, "HTTP_CODE")) return CURLINFO_HTTP_CODE;
break;
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
if (strEQ(name, "NAMELOOKUP_TIME")) return CURLINFO_NAMELOOKUP_TIME;
break;
case 'O':
case 'P':
if (strEQ(name, "PRETRANSFER_TIME")) return CURLINFO_PRETRANSFER_TIME;
break;
case 'Q':
case 'R':
if (strEQ(name, "REQUEST_SIZE")) return CURLINFO_REQUEST_SIZE;
break;
case 'S':
if (strEQ(name, "SSL_VERIFYRESULT")) return CURLINFO_SSL_VERIFYRESULT;
break;
case 'T':
if (strEQ(name, "SIZE_DOWNLOAD")) return CURLINFO_SIZE_DOWNLOAD;
if (strEQ(name, "SIZE_UPLOAD")) return CURLINFO_SIZE_UPLOAD;
if (strEQ(name, "SPEED_DOWNLOAD")) return CURLINFO_SPEED_DOWNLOAD;
if (strEQ(name, "SPEED_UPLOAD")) return CURLINFO_SPEED_UPLOAD;
if (strEQ(name, "TOTAL_TIME")) return CURLINFO_TOTAL_TIME;
break;
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
break;
}
}
if (strncmp(name, "CURLOPT_", 8) == 0) {
name += 8;
switch (*name) {
case 'A':
case 'B':
if (strEQ(name, "AUTOREFERER")) return CURLOPT_AUTOREFERER;
break;
case 'C':
if (strEQ(name, "CONNECTTIMEOUT")) return CURLOPT_CONNECTTIMEOUT;
if (strEQ(name, "COOKIE")) return CURLOPT_COOKIE;
if (strEQ(name, "COOKIEFILE")) return CURLOPT_COOKIEFILE;
if (strEQ(name, "CLOSEFUNCTION")) return CURLOPT_CLOSEFUNCTION;
if (strEQ(name, "CLOSEPOLICY")) return CURLOPT_CLOSEPOLICY;
if (strEQ(name, "CRLF")) return CURLOPT_CRLF;
if (strEQ(name, "CUSTOMREQUEST")) return CURLOPT_CUSTOMREQUEST;
break;
case 'D':
case 'E':
if (strEQ(name, "EGDSOCKET")) return CURLOPT_EGDSOCKET;
if (strEQ(name, "ERRORBUFFER")) return CURLOPT_ERRORBUFFER;
break;
case 'F':
if (strEQ(name, "FAILONERROR")) return CURLOPT_FAILONERROR;
if (strEQ(name, "FILE")) return CURLOPT_FILE;
if (strEQ(name, "FILETIME")) return CURLOPT_FILETIME;
if (strEQ(name, "FOLLOWLOCATION")) return CURLOPT_FOLLOWLOCATION;
if (strEQ(name, "FORBID_REUSE")) return CURLOPT_FORBID_REUSE;
if (strEQ(name, "FTPAPPEND")) return CURLOPT_FTPAPPEND;
if (strEQ(name, "FTPASCII")) return CURLOPT_FTPASCII;
if (strEQ(name, "FTPLISTONLY")) return CURLOPT_FTPLISTONLY;
if (strEQ(name, "FTPPORT")) return CURLOPT_FTPPORT;
if (strEQ(name, "FRESH_CONNECT")) return CURLOPT_FRESH_CONNECT;
break;
case 'G':
case 'H':
if (strEQ(name, "HEADER")) return CURLOPT_HEADER;
if (strEQ(name, "HEADERFUNCTION")) return CURLOPT_HEADERFUNCTION;
if (strEQ(name, "HTTPHEADER")) return CURLOPT_HTTPHEADER;
if (strEQ(name, "HTTPPOST")) return CURLOPT_HTTPPOST;
if (strEQ(name, "HTTPPROXYTUNNEL")) return CURLOPT_HTTPPROXYTUNNEL;
if (strEQ(name, "HTTPREQUEST")) return CURLOPT_HTTPREQUEST;
break;
case 'I':
case 'J':
if (strEQ(name, "INFILE")) return CURLOPT_INFILE;
if (strEQ(name, "INFILESIZE")) return CURLOPT_INFILESIZE;
if (strEQ(name, "INTERFACE")) return CURLOPT_INTERFACE;
break;
case 'K':
case 'L':
if (strEQ(name, "KRB4LEVEL")) return CURLOPT_KRB4LEVEL;
if (strEQ(name, "LOW_SPEED_LIMIT")) return CURLOPT_LOW_SPEED_LIMIT;
if (strEQ(name, "LOW_SPEED_TIME")) return CURLOPT_LOW_SPEED_TIME;
break;
case 'M':
if (strEQ(name, "MAXCONNECTS")) return CURLOPT_MAXCONNECTS;
if (strEQ(name, "MAXREDIRS")) return CURLOPT_MAXREDIRS;
break;
case 'N':
if (strEQ(name, "MUTE")) return CURLOPT_MUTE;
if (strEQ(name, "NETRC")) return CURLOPT_NETRC;
if (strEQ(name, "NOBODY")) return CURLOPT_NOBODY;
if (strEQ(name, "NOPROGRESS")) return CURLOPT_NOPROGRESS;
if (strEQ(name, "NOTHING")) return CURLOPT_NOTHING;
break;
case 'O':
case 'P':
if (strEQ(name, "PASSWDDATA")) return CURLOPT_PASSWDDATA;
if (strEQ(name, "PASSWDFUNCTION")) return CURLOPT_PASSWDFUNCTION;
if (strEQ(name, "PORT")) return CURLOPT_PORT;
if (strEQ(name, "POST")) return CURLOPT_POST;
if (strEQ(name, "POSTFIELDS")) return CURLOPT_POSTFIELDS;
if (strEQ(name, "POSTFIELDSIZE")) return CURLOPT_POSTFIELDSIZE;
if (strEQ(name, "POSTQUOTE")) return CURLOPT_POSTQUOTE;
if (strEQ(name, "PROGRESSDATA")) return CURLOPT_PROGRESSDATA;
if (strEQ(name, "PROGRESSFUNCTION")) return CURLOPT_PROGRESSFUNCTION;
if (strEQ(name, "PROXY")) return CURLOPT_PROXY;
if (strEQ(name, "PROXYPORT")) return CURLOPT_PROXYPORT;
if (strEQ(name, "PROXYUSERPWD")) return CURLOPT_PROXYUSERPWD;
if (strEQ(name, "PUT")) return CURLOPT_PUT;
break;
case 'Q':
if (strEQ(name, "QUOTE")) return CURLOPT_QUOTE;
break;
case 'R':
if (strEQ(name, "RANDOM_FILE")) return CURLOPT_RANDOM_FILE;
if (strEQ(name, "RANGE")) return CURLOPT_RANGE;
if (strEQ(name, "READFUNCTION")) return CURLOPT_READFUNCTION;
if (strEQ(name, "REFERER")) return CURLOPT_REFERER;
if (strEQ(name, "RESUME_FROM")) return CURLOPT_RESUME_FROM;
break;
case 'S':
if (strEQ(name, "SSLCERT")) return CURLOPT_SSLCERT;
if (strEQ(name, "SSLCERTPASSWD")) return CURLOPT_SSLCERTPASSWD;
if (strEQ(name, "SSLVERSION")) return CURLOPT_SSLVERSION;
if (strEQ(name, "STDERR")) return CURLOPT_STDERR;
break;
case 'T':
if (strEQ(name, "TELNETOPTIONS")) return CURLOPT_TELNETOPTIONS;
if (strEQ(name, "TIMECONDITION")) return CURLOPT_TIMECONDITION;
if (strEQ(name, "TIMEOUT")) return CURLOPT_TIMEOUT;
if (strEQ(name, "TIMEVALUE")) return CURLOPT_TIMEVALUE;
if (strEQ(name, "TRANSFERTEXT")) return CURLOPT_TRANSFERTEXT;
break;
case 'U':
case 'V':
if (strEQ(name, "UPLOAD")) return CURLOPT_UPLOAD;
if (strEQ(name, "URL")) return CURLOPT_URL;
if (strEQ(name, "USERAGENT")) return CURLOPT_USERAGENT;
if (strEQ(name, "USERPWD")) return CURLOPT_USERPWD;
if (strEQ(name, "VERBOSE")) return CURLOPT_VERBOSE;
break;
case 'W':
case 'X':
case 'Y':
case 'Z':
if (strEQ(name, "WRITEFUNCTION")) return CURLOPT_WRITEFUNCTION;
if (strEQ(name, "WRITEHEADER")) return CURLOPT_WRITEHEADER;
if (strEQ(name, "WRITEINFO")) return CURLOPT_WRITEINFO;
break;
}
}
if (strEQ(name, "USE_INTERNAL_VARS")) return USE_INTERNAL_VARS;
errno = EINVAL;
return 0;
}
MODULE = Curl::easy PACKAGE = Curl::easy PREFIX = curl_easy_
int
constant(name,arg)
char * name
int arg
void *
curl_easy_init()
CODE:
init_globals();
RETVAL = curl_easy_init();
curl_easy_setopt(RETVAL, CURLOPT_HEADERFUNCTION, header_callback_func);
curl_easy_setopt(RETVAL, CURLOPT_WRITEFUNCTION, write_callback_func);
OUTPUT:
RETVAL
char *
curl_easy_version()
CODE:
RETVAL=curl_version();
OUTPUT:
RETVAL
int
curl_easy_setopt(curl, option, value)
void * curl
int option
SV * value
CODE:
if (option < CURLOPTTYPE_OBJECTPOINT) {
/* This is an option specifying an integer value: */
RETVAL = curl_easy_setopt(curl, option, (long)SvIV(value));
} else if (option == CURLOPT_FILE || option == CURLOPT_INFILE ||
option == CURLOPT_WRITEHEADER || option == CURLOPT_PROGRESSDATA ||
option == CURLOPT_PASSWDDATA) {
/* This is an option specifying an SV * value: */
RETVAL = curl_easy_setopt(curl, option, newSVsv(ST(2)));
} else if (option == CURLOPT_ERRORBUFFER) {
/* Pass in variable name for storing error messages... */
RETVAL = curl_easy_setopt(curl, option, errbuf);
if (errbufvarname) free(errbufvarname);
errbufvarname = strdup((char *)SvPV(value, PL_na));
} else if (option == CURLOPT_WRITEFUNCTION || option ==
CURLOPT_READFUNCTION || option == CURLOPT_PROGRESSFUNCTION ||
option == CURLOPT_PASSWDFUNCTION || option == CURLOPT_HEADERFUNCTION) {
/* This is an option specifying a callback function */
switch (option) {
case CURLOPT_WRITEFUNCTION:
register_callback(&write_callback, value);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback_func);
break;
case CURLOPT_READFUNCTION:
register_callback(&read_callback, value);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback_func);
break;
case CURLOPT_HEADERFUNCTION:
register_callback(&header_callback, value);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback_func);
case CURLOPT_PROGRESSFUNCTION:
register_callback(&progress_callback, value);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback_func);
break;
case CURLOPT_PASSWDFUNCTION:
register_callback(&passwd_callback, value);
curl_easy_setopt(curl, CURLOPT_PASSWDFUNCTION, passwd_callback_func);
break;
/* awaiting a prototype for the closepolicy function callback
case CURLOPT_CLOSEFUNCTION:
register_callback(&closepolicy_callback, value);
curl_easy_setopt(curl, CURLOPT_CLOSEFUNCTION, closepolicy_callback_func);
break;
*/
}
RETVAL = -1;
} else if (option == CURLOPT_HTTPHEADER || option == CURLOPT_QUOTE ||
option == CURLOPT_POSTQUOTE) {
/* This is an option specifying a list of curl_slist structs: */
AV *array = (AV *)SvRV(value);
struct curl_slist **slist = NULL;
/* We have to find out which list to use... */
switch (option) {
case CURLOPT_HTTPHEADER:
slist = &httpheader; break;
case CURLOPT_QUOTE:
slist = &quote; break;
case CURLOPT_POSTQUOTE:
slist = &postquote; break;
}
/* free any previous list */
if (*slist) {
curl_slist_free_all(*slist);
*slist=NULL;
}
/* ...store the values into it... */
for (;;) {
SV *sv = av_shift(array);
int len = 0;
char *str = SvPV(sv, len);
if (len == 0) break;
*slist = curl_slist_append(*slist, str);
}
/* ...and pass the list into curl_easy_setopt() */
RETVAL = curl_easy_setopt(curl, option, *slist);
} else {
/* This is an option specifying a char * value: */
RETVAL = curl_easy_setopt(curl, option, SvPV(value, PL_na));
}
OUTPUT:
RETVAL
int
internal_setopt(option, value)
int option
int value
CODE:
if (value == 1) {
internal_options |= option;
} else {
internal_options &= !option;
}
RETVAL = 0;
OUTPUT:
RETVAL
int
curl_easy_perform(curl)
void * curl
CODE:
if (internal_options & USE_INTERNAL_VARS) {
/* Use internal callback which just stores the content into a buffer. */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, internal_write_callback);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
}
RETVAL = curl_easy_perform(curl);
if (RETVAL && errbufvarname) {
/* If an error occurred and a varname for error messages has been
specified, store the error message. */
SV *sv = perl_get_sv(errbufvarname, TRUE | GV_ADDMULTI);
sv_setpv(sv, errbuf);
}
if (!RETVAL && (internal_options & USE_INTERNAL_VARS)) {
/* No error and internal variable for the content are to be used:
Split the data into headers and content and store them into
perl variables. */
SV *head_sv = perl_get_sv("Curl::easy::headers", TRUE | GV_ADDMULTI);
SV *cont_sv = perl_get_sv("Curl::easy::content", TRUE | GV_ADDMULTI);
char *p = contbuf;
int nl = 0, found = 0;
while (p < bufptr) {
if (nl && (*p == '\n' || *p == '\r')) {
/* found empty line, end of headers */
*p++ = '\0';
sv_setpv(head_sv, contbuf);
while (*p == '\n' || *p == '\r') {
p++;
}
sv_setpv(cont_sv, p);
found = 1;
break;
}
nl = (*p == '\n');
p++;
}
if (!found) {
sv_setpv(head_sv, "");
sv_setpv(cont_sv, contbuf);
}
}
OUTPUT:
RETVAL
int
curl_easy_getinfo(curl, option, value)
void * curl
int option
double value
CODE:
#ifdef __GNUC__
/* a(void) warnig about unnused variable */
(void) value;
#endif
switch (option & CURLINFO_TYPEMASK) {
case CURLINFO_STRING: {
char * value = (char *)SvPV(ST(2), PL_na);
RETVAL = curl_easy_getinfo(curl, option, &value);
sv_setpv(ST(2), value);
break;
}
case CURLINFO_LONG: {
long value = (long)SvIV(ST(2));
RETVAL = curl_easy_getinfo(curl, option, &value);
sv_setiv(ST(2), value);
break;
}
case CURLINFO_DOUBLE: {
double value = (double)SvNV(ST(2));
RETVAL = curl_easy_getinfo(curl, option, &value);
sv_setnv(ST(2), value);
break;
}
default: {
RETVAL = CURLE_BAD_FUNCTION_ARGUMENT;
break;
}
}
OUTPUT:
RETVAL
int
curl_easy_cleanup(curl)
void * curl
CODE:
curl_easy_cleanup(curl);
init_globals();
RETVAL = 0;
OUTPUT:
RETVAL

315
perl/Curl_easy/test.pl Normal file
View File

@@ -0,0 +1,315 @@
# Test script for Perl extension Curl::easy.
# Check out the file README for more info.
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'
######################### We start with some black magic to print on failure.
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
use Benchmark;
use strict;
BEGIN { $| = 1; print "1..13\n"; }
END {print "not ok 1\n" unless $::loaded;}
use Curl::easy;
$::loaded = 1;
print "ok 1\n";
######################### End of black magic.
# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):
print "Testing curl version ",&Curl::easy::version(),"\n";
# Read URL to get
my $defurl = "http://localhost/cgi-bin/printenv";
my $url = "";
print "Please enter an URL to fetch [$defurl]: ";
$url = <STDIN>;
if ($url =~ /^\s*\n/) {
$url = $defurl;
}
# Init the curl session
my $curl;
if (($curl = Curl::easy::init()) != 0) {
print "ok 2\n";
} else {
print "ko 2\n";
}
# No progress meter please
# !! Need this on for all tests, as once disabled, can't re-enable it...
#Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
# Shut up completely
Curl::easy::setopt($curl, CURLOPT_MUTE, 1);
# Follow location headers
Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
# Set timeout
Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
# Set file where to read cookies from
Curl::easy::setopt($curl, CURLOPT_COOKIEFILE, "cookies");
# Set file where to store the header
open HEAD, ">head.out";
Curl::easy::setopt($curl, CURLOPT_WRITEHEADER, *HEAD);
print "ok 3\n";
# Set file where to store the body
# Send body to stdout - test difference between FILE * and SV *
#open BODY, ">body.out";
#Curl::easy::setopt($curl, CURLOPT_FILE,*BODY);
print "ok 4\n";
# Add some additional headers to the http-request:
my @myheaders;
$myheaders[0] = "Server: www";
$myheaders[1] = "User-Agent: Perl interface for libcURL";
Curl::easy::setopt($curl, Curl::easy::CURLOPT_HTTPHEADER, \@myheaders);
# Store error messages in variable $errbuf
# NOTE: The name of the variable is passed as a string!
# setopt() creates a perl variable with that name, and
# perform() stores the errormessage into it if an error occurs.
Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "errbuf");
Curl::easy::setopt($curl, CURLOPT_URL, $url);
print "ok 5\n";
my $bytes;
my $realurl;
my $httpcode;
my $errbuf;
# Go get it
if (Curl::easy::perform($curl) == 0) {
Curl::easy::getinfo($curl, CURLINFO_SIZE_DOWNLOAD, $bytes);
print "ok 6: $bytes bytes read\n";
Curl::easy::getinfo($curl, CURLINFO_EFFECTIVE_URL, $realurl);
Curl::easy::getinfo($curl, CURLINFO_HTTP_CODE, $httpcode);
print "effective fetched url (http code: $httpcode) was: $url\n";
} else {
# We can acces the error message in $errbuf here
print "not ok 6: '$errbuf'\n";
die "basic url access failed";
}
# cleanup
#close HEAD;
# test here - BODY is still expected to be the output
# Curl-easy-1.0.2.pm core dumps if we 'perform' with a closed output FD...
#close BODY;
#exit;
#
# The header callback will only be called if your libcurl has the
# CURLOPT_HEADERFUNCTION supported, otherwise your headers
# go to CURLOPT_WRITEFUNCTION instead...
#
my $header_called=0;
sub header_callback { print "header callback called\n"; $header_called=1; return length($_[0])};
# test for sub reference and head callback
Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION, \&header_callback);
print "ok 7\n"; # so far so good
if (Curl::easy::perform($curl) != 0) {
print "not ";
};
print "ok 8\n";
print "next test will fail on libcurl < 7.7.2\n";
print "not " if (!$header_called); # ok if you have a libcurl <7.7.2
print "ok 9\n";
my $body_called=0;
sub body_callback {
my ($chunk,$handle)=@_;
print "body callback called with ",length($chunk)," bytes\n";
print "data=$chunk\n";
$body_called++;
return length($chunk); # OK
}
# test for ref to sub and body callback
my $body_ref=\&body_callback;
Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, $body_ref);
if (Curl::easy::perform($curl) != 0) {
print "not ";
};
print "ok 10\n";
print "not " if (!$body_called);
print "ok 11\n";
my $body_abort_called=0;
sub body_abort_callback {
my ($chunk,$sv)=@_;
print "body abort callback called with ",length($chunk)," bytes\n";
$body_abort_called++;
return -1; # signal a failure
}
# test we can abort a request mid-way
my $body_abort_ref=\&body_abort_callback;
Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, $body_abort_ref);
if (Curl::easy::perform($curl) == 0) { # reverse test - this should have failed
print "not ";
};
print "ok 12\n";
print "not " if (!$body_abort_called); # should have been called
print "ok 13\n";
# reset to a working 'write' function for next tests
Curl::easy::setopt($curl,CURLOPT_WRITEFUNCTION, sub { return length($_[0])} );
# inline progress function
# tests for inline subs and progress callback
# - progress callback must return 'true' on each call.
my $progress_called=0;
sub prog_callb
{
my ($clientp,$dltotal,$dlnow,$ultotal,$ulnow)=@_;
print "\nperl progress_callback has been called!\n";
print "clientp: $clientp, dltotal: $dltotal, dlnow: $dlnow, ultotal: $ultotal, ";
print "ulnow: $ulnow\n";
$progress_called++;
return 0;
}
Curl::easy::setopt($curl, CURLOPT_PROGRESSFUNCTION, \&prog_callb);
# Turn progress meter back on - this doesn't work - once its off, its off.
Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 0);
if (Curl::easy::perform($curl) != 0) {
print "not ";
};
print "ok 14\n";
print "not " if (!$progress_called);
print "ok 15\n";
my $read_max=10;
sub read_callb
{
my ($maxlen,$sv)=@_;
print "\nperl read_callback has been called!\n";
print "max data size: $maxlen\n";
print "(upload needs $read_max bytes)\n";
print "context: ".$sv."\n";
if ($read_max > 0) {
print "\nEnter max ", $read_max, " characters to be uploaded.\n";
my $data = <STDIN>;
chomp $data;
$read_max=$read_max-length($data);
return $data;
} else {
return "";
}
}
#
# test post/read callback functions - requires a url which accepts posts, or it fails!
#
Curl::easy::setopt($curl,CURLOPT_READFUNCTION,\&read_callb);
Curl::easy::setopt($curl,CURLOPT_INFILESIZE,$read_max );
Curl::easy::setopt($curl,CURLOPT_UPLOAD,1 );
Curl::easy::setopt($curl,CURLOPT_CUSTOMREQUEST,"POST" );
if (Curl::easy::perform($curl) != 0) {
print "not ";
};
print "ok 16\n";
sub passwd_callb
{
my ($clientp,$prompt,$buflen)=@_;
print "\nperl passwd_callback has been called!\n";
print "clientp: $clientp, prompt: $prompt, buflen: $buflen\n";
print "\nEnter max $buflen characters for $prompt ";
my $data = <STDIN>;
chomp($data);
return (0,$data);
}
Curl::easy::cleanup($curl);
# Now do an ftp upload:
$defurl = "ftp://horn\@localhost//tmp/bla";
print "\n\nPlease enter an URL for ftp upload [$defurl]: ";
$url = <STDIN>;
if ($url =~ /^\s*\n/) {
$url = $defurl;
}
# Init the curl session
if (($curl = Curl::easy::init()) != 0) {
print "ok 17\n";
} else {
print "not ok 17\n";
}
# Set URL to get
if (Curl::easy::setopt($curl, Curl::easy::CURLOPT_URL, $url) == 0) {
print "ok 18\n";
} else {
print "not ok 18\n";
}
# Tell libcurl to to an upload
Curl::easy::setopt($curl, Curl::easy::CURLOPT_UPLOAD, 1);
# No progress meter please
#Curl::easy::setopt($curl, Curl::easy::CURLOPT_NOPROGRESS, 1);
# Use our own progress callback
Curl::easy::setopt($curl, Curl::easy::CURLOPT_PROGRESSFUNCTION, \&prog_callb);
# Shut up completely
Curl::easy::setopt($curl, Curl::easy::CURLOPT_MUTE, 1);
# Store error messages in $errbuf
Curl::easy::setopt($curl, Curl::easy::CURLOPT_ERRORBUFFER, "errbuf");
$read_max=10;
# Use perl read callback to read data to be uploaded
Curl::easy::setopt($curl, Curl::easy::CURLOPT_READFUNCTION,
\&read_callb);
# Use perl passwd callback to read password for login to ftp server
Curl::easy::setopt($curl, Curl::easy::CURLOPT_PASSWDFUNCTION, \&passwd_callb);
print "ok 19\n";
# Go get it
if (Curl::easy::perform($curl) == 0) {
Curl::easy::getinfo($curl, Curl::easy::CURLINFO_SIZE_UPLOAD, $bytes);
print "ok 20: $bytes bytes transferred\n\n";
} else {
# We can acces the error message in $errbuf here
print "not ok 20: '$errbuf'\n";
}
# Cleanup
Curl::easy::cleanup($curl);
print "ok 21\n";

3
perl/Makefile.am Normal file
View File

@@ -0,0 +1,3 @@
SUBDIRS = Curl_easy
EXTRA_DIST = README

View File

@@ -1,33 +1,18 @@
This is just a small collection of perl scripts that use curl to do _ _ ____ _
their jobs. ___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
If you need a proxy configuration in order to get HTTP or FTP Perl
documents, do edit your .curlrc file in your HOME dir to contain:
-x <proxy host>:<proxy port>
These scripts are all written by Daniel Stenberg. Perl's a great script language, not the least for quick prototyping. Curl is
elegantly used from within it. You can either invoke external curl command
line or use the curl interface.
checklinks.pl Georg Horn's Perl interface to curl is available in the Curl_easy/
============= subdirectory. Using the Curl::easy module is just straightforward and
This script fetches an HTML page, extracts all links and references to works much like using libcurl in a C programm, so please refer to the
other documents and then goes through them to check that they work. documentation of libcurl. Have a look at test.pl to get an idea of how
Reports progress in a format intended for machine-parsing. to start.
getlinks.pl
===========
You ever wanted to download a bunch of programs a certain HTML page has
links to? This program extracts all links and references from a web page
and then compares them to the regex you supply. All matches will be
downloaded in the target directory of your choice.
recursiveftpget.pl
==================
This script recursively downloads all files from a directory on an ftp site
and all subdirectories it has. Optional depth-level.
formfind.pl
===========
Downloads an HTML page (or reads stdin) and reports a human readable report
about the FORM(s) present. What method, what URL, which input or select
field, what default values they have and what submit buttons there are. It
is useful if you intend to use curl to properly fake a form submission.

View File

Some files were not shown because too many files have changed in this diff Show More